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() {
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 @@ bool Heap::CreateInitialMaps() {
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 @@ bool Heap::CreateInitialMaps() {
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 @@ bool Heap::CreateInitialMaps() {
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 @@ bool Heap::CreateInitialMaps() {
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));
......
......@@ -640,8 +640,9 @@ void Map::MapPrint() {
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());
}
......
......@@ -2111,20 +2111,28 @@ int Map::pre_allocated_property_fields() {
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();
}
......
......@@ -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) {
// Handle header
IteratePointer(v, kMapOffset);
......
......@@ -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.
// It describes the type of the instances.
//
......@@ -304,11 +308,11 @@ enum PropertyNormalizationMode {
// 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 @@ enum PropertyNormalizationMode {
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 @@ enum PropertyNormalizationMode {
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 @@ class HeapObject: public Object {
// 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 Code: public HeapObject {
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);
......
......@@ -36,8 +36,8 @@ TEST(HeapMaps) {
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);
}
......
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