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