Commit b5bbf957 authored by vitalyr@chromium.org's avatar vitalyr@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5301 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 5a25c6d7
...@@ -1413,7 +1413,7 @@ bool Heap::CreateInitialMaps() { ...@@ -1413,7 +1413,7 @@ bool Heap::CreateInitialMaps() {
set_meta_map(new_meta_map); set_meta_map(new_meta_map);
new_meta_map->set_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; if (obj->IsFailure()) return false;
set_fixed_array_map(Map::cast(obj)); set_fixed_array_map(Map::cast(obj));
...@@ -1455,7 +1455,7 @@ bool Heap::CreateInitialMaps() { ...@@ -1455,7 +1455,7 @@ bool Heap::CreateInitialMaps() {
oddball_map()->set_prototype(null_value()); oddball_map()->set_prototype(null_value());
oddball_map()->set_constructor(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; if (obj->IsFailure()) return false;
set_fixed_cow_array_map(Map::cast(obj)); set_fixed_cow_array_map(Map::cast(obj));
ASSERT(fixed_array_map() != fixed_cow_array_map()); ASSERT(fixed_array_map() != fixed_cow_array_map());
...@@ -1475,17 +1475,17 @@ bool Heap::CreateInitialMaps() { ...@@ -1475,17 +1475,17 @@ bool Heap::CreateInitialMaps() {
roots_[entry.index] = Map::cast(obj); roots_[entry.index] = Map::cast(obj);
} }
obj = AllocateMap(STRING_TYPE, SeqTwoByteString::kAlignedSize); obj = AllocateMap(STRING_TYPE, kVariableSizeSentinel);
if (obj->IsFailure()) return false; if (obj->IsFailure()) return false;
set_undetectable_string_map(Map::cast(obj)); set_undetectable_string_map(Map::cast(obj));
Map::cast(obj)->set_is_undetectable(); Map::cast(obj)->set_is_undetectable();
obj = AllocateMap(ASCII_STRING_TYPE, SeqAsciiString::kAlignedSize); obj = AllocateMap(ASCII_STRING_TYPE, kVariableSizeSentinel);
if (obj->IsFailure()) return false; if (obj->IsFailure()) return false;
set_undetectable_ascii_string_map(Map::cast(obj)); set_undetectable_ascii_string_map(Map::cast(obj));
Map::cast(obj)->set_is_undetectable(); Map::cast(obj)->set_is_undetectable();
obj = AllocateMap(BYTE_ARRAY_TYPE, ByteArray::kAlignedSize); obj = AllocateMap(BYTE_ARRAY_TYPE, kVariableSizeSentinel);
if (obj->IsFailure()) return false; if (obj->IsFailure()) return false;
set_byte_array_map(Map::cast(obj)); set_byte_array_map(Map::cast(obj));
...@@ -1528,7 +1528,7 @@ bool Heap::CreateInitialMaps() { ...@@ -1528,7 +1528,7 @@ bool Heap::CreateInitialMaps() {
if (obj->IsFailure()) return false; if (obj->IsFailure()) return false;
set_external_float_array_map(Map::cast(obj)); set_external_float_array_map(Map::cast(obj));
obj = AllocateMap(CODE_TYPE, Code::kHeaderSize); obj = AllocateMap(CODE_TYPE, kVariableSizeSentinel);
if (obj->IsFailure()) return false; if (obj->IsFailure()) return false;
set_code_map(Map::cast(obj)); set_code_map(Map::cast(obj));
...@@ -1552,19 +1552,19 @@ bool Heap::CreateInitialMaps() { ...@@ -1552,19 +1552,19 @@ bool Heap::CreateInitialMaps() {
roots_[entry.index] = Map::cast(obj); roots_[entry.index] = Map::cast(obj);
} }
obj = AllocateMap(FIXED_ARRAY_TYPE, HeapObject::kHeaderSize); obj = AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
if (obj->IsFailure()) return false; if (obj->IsFailure()) return false;
set_hash_table_map(Map::cast(obj)); 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; if (obj->IsFailure()) return false;
set_context_map(Map::cast(obj)); set_context_map(Map::cast(obj));
obj = AllocateMap(FIXED_ARRAY_TYPE, HeapObject::kHeaderSize); obj = AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
if (obj->IsFailure()) return false; if (obj->IsFailure()) return false;
set_catch_context_map(Map::cast(obj)); 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; if (obj->IsFailure()) return false;
set_global_context_map(Map::cast(obj)); set_global_context_map(Map::cast(obj));
......
...@@ -640,8 +640,9 @@ void Map::MapPrint() { ...@@ -640,8 +640,9 @@ void Map::MapPrint() {
void Map::MapVerify() { void Map::MapVerify() {
ASSERT(!Heap::InNewSpace(this)); ASSERT(!Heap::InNewSpace(this));
ASSERT(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE); ASSERT(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE);
ASSERT(kPointerSize <= instance_size() ASSERT(instance_size() == kVariableSizeSentinel ||
&& instance_size() < Heap::Capacity()); (kPointerSize <= instance_size() &&
instance_size() < Heap::Capacity()));
VerifyHeapPointer(prototype()); VerifyHeapPointer(prototype());
VerifyHeapPointer(instance_descriptors()); VerifyHeapPointer(instance_descriptors());
} }
......
...@@ -2111,20 +2111,28 @@ int Map::pre_allocated_property_fields() { ...@@ -2111,20 +2111,28 @@ int Map::pre_allocated_property_fields() {
int HeapObject::SizeFromMap(Map* map) { 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. // 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) { if (instance_type == FIXED_ARRAY_TYPE) {
return FixedArray::BodyDescriptor::SizeOf(map, this); 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) { if (instance_type == BYTE_ARRAY_TYPE) {
return reinterpret_cast<ByteArray*>(this)->ByteArraySize(); return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
} }
// Otherwise do the general size computation. if (instance_type == STRING_TYPE) {
return SlowSizeFromMap(map); return SeqTwoByteString::SizeFor(
reinterpret_cast<SeqTwoByteString*>(this)->length());
}
ASSERT(instance_type == CODE_TYPE);
return reinterpret_cast<Code*>(this)->CodeSize();
} }
......
...@@ -1024,38 +1024,6 @@ void HeapObject::HeapObjectShortPrint(StringStream* accumulator) { ...@@ -1024,38 +1024,6 @@ void HeapObject::HeapObjectShortPrint(StringStream* accumulator) {
} }
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) { void HeapObject::Iterate(ObjectVisitor* v) {
// Handle header // Handle header
IteratePointer(v, kMapOffset); IteratePointer(v, kMapOffset);
......
...@@ -201,6 +201,10 @@ enum PropertyNormalizationMode { ...@@ -201,6 +201,10 @@ enum PropertyNormalizationMode {
}; };
// Instance size sentinel for objects of variable size.
static const int kVariableSizeSentinel = 0;
// All Maps have a field instance_type containing a InstanceType. // All Maps have a field instance_type containing a InstanceType.
// It describes the type of the instances. // It describes the type of the instances.
// //
...@@ -304,11 +308,11 @@ enum PropertyNormalizationMode { ...@@ -304,11 +308,11 @@ enum PropertyNormalizationMode {
// iterate over them. // iterate over them.
#define STRING_TYPE_LIST(V) \ #define STRING_TYPE_LIST(V) \
V(SYMBOL_TYPE, \ V(SYMBOL_TYPE, \
SeqTwoByteString::kAlignedSize, \ kVariableSizeSentinel, \
symbol, \ symbol, \
Symbol) \ Symbol) \
V(ASCII_SYMBOL_TYPE, \ V(ASCII_SYMBOL_TYPE, \
SeqAsciiString::kAlignedSize, \ kVariableSizeSentinel, \
ascii_symbol, \ ascii_symbol, \
AsciiSymbol) \ AsciiSymbol) \
V(CONS_SYMBOL_TYPE, \ V(CONS_SYMBOL_TYPE, \
...@@ -332,11 +336,11 @@ enum PropertyNormalizationMode { ...@@ -332,11 +336,11 @@ enum PropertyNormalizationMode {
external_ascii_symbol, \ external_ascii_symbol, \
ExternalAsciiSymbol) \ ExternalAsciiSymbol) \
V(STRING_TYPE, \ V(STRING_TYPE, \
SeqTwoByteString::kAlignedSize, \ kVariableSizeSentinel, \
string, \ string, \
String) \ String) \
V(ASCII_STRING_TYPE, \ V(ASCII_STRING_TYPE, \
SeqAsciiString::kAlignedSize, \ kVariableSizeSentinel, \
ascii_string, \ ascii_string, \
AsciiString) \ AsciiString) \
V(CONS_STRING_TYPE, \ V(CONS_STRING_TYPE, \
...@@ -358,7 +362,7 @@ enum PropertyNormalizationMode { ...@@ -358,7 +362,7 @@ enum PropertyNormalizationMode {
V(EXTERNAL_ASCII_STRING_TYPE, \ V(EXTERNAL_ASCII_STRING_TYPE, \
ExternalAsciiString::kSize, \ ExternalAsciiString::kSize, \
external_ascii_string, \ external_ascii_string, \
ExternalAsciiString) \ ExternalAsciiString)
// A struct is a simple object a set of object-valued fields. Including an // 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 // object type in this causes the compiler to generate most of the boilerplate
...@@ -1100,10 +1104,6 @@ class HeapObject: public Object { ...@@ -1100,10 +1104,6 @@ class HeapObject: public Object {
// as above, for the single element at "offset" // as above, for the single element at "offset"
inline void IteratePointer(ObjectVisitor* v, int 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: private:
DISALLOW_IMPLICIT_CONSTRUCTORS(HeapObject); DISALLOW_IMPLICIT_CONSTRUCTORS(HeapObject);
}; };
...@@ -2993,6 +2993,8 @@ class Code: public HeapObject { ...@@ -2993,6 +2993,8 @@ class Code: public HeapObject {
class Map: public HeapObject { class Map: public HeapObject {
public: public:
// Instance size. // Instance size.
// Size in bytes or kVariableSizeSentinel if instances do not have
// a fixed size.
inline int instance_size(); inline int instance_size();
inline void set_instance_size(int value); inline void set_instance_size(int value);
......
...@@ -36,8 +36,8 @@ TEST(HeapMaps) { ...@@ -36,8 +36,8 @@ TEST(HeapMaps) {
InitializeVM(); InitializeVM();
CheckMap(Heap::meta_map(), MAP_TYPE, Map::kSize); CheckMap(Heap::meta_map(), MAP_TYPE, Map::kSize);
CheckMap(Heap::heap_number_map(), HEAP_NUMBER_TYPE, HeapNumber::kSize); CheckMap(Heap::heap_number_map(), HEAP_NUMBER_TYPE, HeapNumber::kSize);
CheckMap(Heap::fixed_array_map(), FIXED_ARRAY_TYPE, FixedArray::kHeaderSize); CheckMap(Heap::fixed_array_map(), FIXED_ARRAY_TYPE, kVariableSizeSentinel);
CheckMap(Heap::string_map(), STRING_TYPE, SeqTwoByteString::kAlignedSize); CheckMap(Heap::string_map(), STRING_TYPE, kVariableSizeSentinel);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment