Revision: 5301
Author: vita...@chromium.org
Date: Wed Aug 18 06:00:38 2010
Log: Make instance_size immediately useful for all fixed size objects.

For variable sized objects this field doesn't really make any sense so
by putting a special value there we can improve SizeFromMap().

Review URL: http://codereview.chromium.org/3127016
http://code.google.com/p/v8/source/detail?r=5301

Modified:
 /branches/bleeding_edge/src/heap.cc
 /branches/bleeding_edge/src/objects-debug.cc
 /branches/bleeding_edge/src/objects-inl.h
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/src/objects.h
 /branches/bleeding_edge/test/cctest/test-heap.cc

=======================================
--- /branches/bleeding_edge/src/heap.cc Tue Aug 17 06:48:03 2010
+++ /branches/bleeding_edge/src/heap.cc Wed Aug 18 06:00:38 2010
@@ -1413,7 +1413,7 @@
   set_meta_map(new_meta_map);
   new_meta_map->set_map(new_meta_map);

-  obj = AllocatePartialMap(FIXED_ARRAY_TYPE, FixedArray::kHeaderSize);
+  obj = AllocatePartialMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
   if (obj->IsFailure()) return false;
   set_fixed_array_map(Map::cast(obj));

@@ -1455,7 +1455,7 @@
   oddball_map()->set_prototype(null_value());
   oddball_map()->set_constructor(null_value());

-  obj = AllocateMap(FIXED_ARRAY_TYPE, FixedArray::kHeaderSize);
+  obj = AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
   if (obj->IsFailure()) return false;
   set_fixed_cow_array_map(Map::cast(obj));
   ASSERT(fixed_array_map() != fixed_cow_array_map());
@@ -1475,17 +1475,17 @@
     roots_[entry.index] = Map::cast(obj);
   }

-  obj = AllocateMap(STRING_TYPE, SeqTwoByteString::kAlignedSize);
+  obj = AllocateMap(STRING_TYPE, kVariableSizeSentinel);
   if (obj->IsFailure()) return false;
   set_undetectable_string_map(Map::cast(obj));
   Map::cast(obj)->set_is_undetectable();

-  obj = AllocateMap(ASCII_STRING_TYPE, SeqAsciiString::kAlignedSize);
+  obj = AllocateMap(ASCII_STRING_TYPE, kVariableSizeSentinel);
   if (obj->IsFailure()) return false;
   set_undetectable_ascii_string_map(Map::cast(obj));
   Map::cast(obj)->set_is_undetectable();

-  obj = AllocateMap(BYTE_ARRAY_TYPE, ByteArray::kAlignedSize);
+  obj = AllocateMap(BYTE_ARRAY_TYPE, kVariableSizeSentinel);
   if (obj->IsFailure()) return false;
   set_byte_array_map(Map::cast(obj));

@@ -1528,7 +1528,7 @@
   if (obj->IsFailure()) return false;
   set_external_float_array_map(Map::cast(obj));

-  obj = AllocateMap(CODE_TYPE, Code::kHeaderSize);
+  obj = AllocateMap(CODE_TYPE, kVariableSizeSentinel);
   if (obj->IsFailure()) return false;
   set_code_map(Map::cast(obj));

@@ -1552,19 +1552,19 @@
     roots_[entry.index] = Map::cast(obj);
   }

-  obj = AllocateMap(FIXED_ARRAY_TYPE, HeapObject::kHeaderSize);
+  obj = AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
   if (obj->IsFailure()) return false;
   set_hash_table_map(Map::cast(obj));

-  obj = AllocateMap(FIXED_ARRAY_TYPE, HeapObject::kHeaderSize);
+  obj = AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
   if (obj->IsFailure()) return false;
   set_context_map(Map::cast(obj));

-  obj = AllocateMap(FIXED_ARRAY_TYPE, HeapObject::kHeaderSize);
+  obj = AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
   if (obj->IsFailure()) return false;
   set_catch_context_map(Map::cast(obj));

-  obj = AllocateMap(FIXED_ARRAY_TYPE, HeapObject::kHeaderSize);
+  obj = AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
   if (obj->IsFailure()) return false;
   set_global_context_map(Map::cast(obj));

=======================================
--- /branches/bleeding_edge/src/objects-debug.cc        Mon Aug 16 09:06:46 2010
+++ /branches/bleeding_edge/src/objects-debug.cc        Wed Aug 18 06:00:38 2010
@@ -640,8 +640,9 @@
 void Map::MapVerify() {
   ASSERT(!Heap::InNewSpace(this));
   ASSERT(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE);
-  ASSERT(kPointerSize <= instance_size()
-         && instance_size() < Heap::Capacity());
+  ASSERT(instance_size() == kVariableSizeSentinel ||
+         (kPointerSize <= instance_size() &&
+          instance_size() < Heap::Capacity()));
   VerifyHeapPointer(prototype());
   VerifyHeapPointer(instance_descriptors());
 }
=======================================
--- /branches/bleeding_edge/src/objects-inl.h   Tue Aug 17 04:44:01 2010
+++ /branches/bleeding_edge/src/objects-inl.h   Wed Aug 18 06:00:38 2010
@@ -2111,20 +2111,28 @@


 int HeapObject::SizeFromMap(Map* map) {
-  InstanceType instance_type = map->instance_type();
+  int instance_size = map->instance_size();
+  if (instance_size != kVariableSizeSentinel) return instance_size;
+  // We can ignore the "symbol" bit becase it is only set for symbols
+  // and implies a string type.
+ int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
   // Only inline the most frequent cases.
-  if (instance_type == JS_OBJECT_TYPE ||
-      (instance_type & (kIsNotStringMask | kStringRepresentationMask)) ==
-      (kStringTag | kConsStringTag) ||
-      instance_type == JS_ARRAY_TYPE) return map->instance_size();
   if (instance_type == FIXED_ARRAY_TYPE) {
     return FixedArray::BodyDescriptor::SizeOf(map, this);
   }
+  if (instance_type == ASCII_STRING_TYPE) {
+    return SeqAsciiString::SizeFor(
+        reinterpret_cast<SeqAsciiString*>(this)->length());
+  }
   if (instance_type == BYTE_ARRAY_TYPE) {
     return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
   }
-  // Otherwise do the general size computation.
-  return SlowSizeFromMap(map);
+  if (instance_type == STRING_TYPE) {
+    return SeqTwoByteString::SizeFor(
+        reinterpret_cast<SeqTwoByteString*>(this)->length());
+  }
+  ASSERT(instance_type == CODE_TYPE);
+  return reinterpret_cast<Code*>(this)->CodeSize();
 }


=======================================
--- /branches/bleeding_edge/src/objects.cc      Tue Aug 17 04:44:01 2010
+++ /branches/bleeding_edge/src/objects.cc      Wed Aug 18 06:00:38 2010
@@ -1022,38 +1022,6 @@
       break;
   }
 }
-
-
-int HeapObject::SlowSizeFromMap(Map* map) {
-  // Avoid calling functions such as FixedArray::cast during GC, which
-  // read map pointer of this object again.
-  InstanceType instance_type = map->instance_type();
-  uint32_t type = static_cast<uint32_t>(instance_type);
-
-  if (instance_type < FIRST_NONSTRING_TYPE
-      && (StringShape(instance_type).IsSequential())) {
-    if ((type & kStringEncodingMask) == kAsciiStringTag) {
- SeqAsciiString* seq_ascii_this = reinterpret_cast<SeqAsciiString*>(this);
-      return seq_ascii_this->SeqAsciiStringSize(instance_type);
-    } else {
-      SeqTwoByteString* self = reinterpret_cast<SeqTwoByteString*>(this);
-      return self->SeqTwoByteStringSize(instance_type);
-    }
-  }
-
-  switch (instance_type) {
-    case FIXED_ARRAY_TYPE:
-      return FixedArray::BodyDescriptor::SizeOf(map, this);
-    case BYTE_ARRAY_TYPE:
-      return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
-    case CODE_TYPE:
-      return reinterpret_cast<Code*>(this)->CodeSize();
-    case MAP_TYPE:
-      return Map::kSize;
-    default:
-      return map->instance_size();
-  }
-}


 void HeapObject::Iterate(ObjectVisitor* v) {
=======================================
--- /branches/bleeding_edge/src/objects.h       Tue Aug 17 06:48:03 2010
+++ /branches/bleeding_edge/src/objects.h       Wed Aug 18 06:00:38 2010
@@ -201,6 +201,10 @@
 };


+// Instance size sentinel for objects of variable size.
+static const int kVariableSizeSentinel = 0;
+
+
 // All Maps have a field instance_type containing a InstanceType.
 // It describes the type of the instances.
 //
@@ -304,11 +308,11 @@
 // iterate over them.
#define STRING_TYPE_LIST(V) \ V(SYMBOL_TYPE, \ - SeqTwoByteString::kAlignedSize, \ + kVariableSizeSentinel, \ symbol, \ Symbol) \ V(ASCII_SYMBOL_TYPE, \ - SeqAsciiString::kAlignedSize, \ + kVariableSizeSentinel, \ ascii_symbol, \ AsciiSymbol) \ V(CONS_SYMBOL_TYPE, \
@@ -332,11 +336,11 @@
external_ascii_symbol, \ ExternalAsciiSymbol) \ V(STRING_TYPE, \ - SeqTwoByteString::kAlignedSize, \ + kVariableSizeSentinel, \ string, \ String) \ V(ASCII_STRING_TYPE, \ - SeqAsciiString::kAlignedSize, \ + kVariableSizeSentinel, \ ascii_string, \ AsciiString) \ V(CONS_STRING_TYPE, \
@@ -358,7 +362,7 @@
V(EXTERNAL_ASCII_STRING_TYPE, \ ExternalAsciiString::kSize, \ external_ascii_string, \ - ExternalAsciiString) \
+    ExternalAsciiString)

 // A struct is a simple object a set of object-valued fields.  Including an
// object type in this causes the compiler to generate most of the boilerplate
@@ -1100,10 +1104,6 @@
   // as above, for the single element at "offset"
   inline void IteratePointer(ObjectVisitor* v, int offset);

-  // Computes the object size from the map.
-  // Should only be used from SizeFromMap.
-  int SlowSizeFromMap(Map* map);
-
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(HeapObject);
 };
@@ -2993,6 +2993,8 @@
 class Map: public HeapObject {
  public:
   // Instance size.
+  // Size in bytes or kVariableSizeSentinel if instances do not have
+  // a fixed size.
   inline int instance_size();
   inline void set_instance_size(int value);

=======================================
--- /branches/bleeding_edge/test/cctest/test-heap.cc Tue Aug 17 05:10:27 2010 +++ /branches/bleeding_edge/test/cctest/test-heap.cc Wed Aug 18 06:00:38 2010
@@ -36,8 +36,8 @@
   InitializeVM();
   CheckMap(Heap::meta_map(), MAP_TYPE, Map::kSize);
   CheckMap(Heap::heap_number_map(), HEAP_NUMBER_TYPE, HeapNumber::kSize);
- CheckMap(Heap::fixed_array_map(), FIXED_ARRAY_TYPE, FixedArray::kHeaderSize); - CheckMap(Heap::string_map(), STRING_TYPE, SeqTwoByteString::kAlignedSize); + CheckMap(Heap::fixed_array_map(), FIXED_ARRAY_TYPE, kVariableSizeSentinel);
+  CheckMap(Heap::string_map(), STRING_TYPE, kVariableSizeSentinel);
 }


--
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev

Reply via email to