Index: src/objects-inl.h |
=================================================================== |
--- src/objects-inl.h (revision 500) |
+++ src/objects-inl.h (working copy) |
@@ -898,24 +898,64 @@ |
int JSObject::GetInternalFieldCount() { |
ASSERT(1 << kPointerSizeLog2 == kPointerSize); |
- return (Size() - GetHeaderSize()) >> kPointerSizeLog2; |
+ // Make sure to adjust for the number of in-object properties. These |
+ // properties do contribute to the size, but are not internal fields. |
+ return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) - |
+ map()->inobject_properties(); |
} |
Object* JSObject::GetInternalField(int index) { |
ASSERT(index < GetInternalFieldCount() && index >= 0); |
+ // Internal objects do follow immediately after the header, whereas in-object |
+ // properties are at the end of the object. Therefore there is no need |
+ // to adjust the index here. |
return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index)); |
} |
void JSObject::SetInternalField(int index, Object* value) { |
ASSERT(index < GetInternalFieldCount() && index >= 0); |
+ // Internal objects do follow immediately after the header, whereas in-object |
+ // properties are at the end of the object. Therefore there is no need |
+ // to adjust the index here. |
int offset = GetHeaderSize() + (kPointerSize * index); |
WRITE_FIELD(this, offset, value); |
WRITE_BARRIER(this, offset); |
} |
+// Access fast-case object properties at index. The use of these routines |
+// is needed to correctly distinguish between properties stored in-object and |
+// properties stored in the properties array. |
+inline Object* JSObject::FastPropertyAt(int index) { |
+ // Adjust for the number of properties stored in the object. |
+ index -= map()->inobject_properties(); |
+ if (index < 0) { |
+ int offset = map()->instance_size() + (index * kPointerSize); |
+ return READ_FIELD(this, offset); |
+ } else { |
+ ASSERT(index < properties()->length()); |
+ return properties()->get(index); |
+ } |
+} |
+ |
+ |
+inline Object* JSObject::FastPropertyAtPut(int index, Object* value) { |
+ // Adjust for the number of properties stored in the object. |
+ index -= map()->inobject_properties(); |
+ if (index < 0) { |
+ int offset = map()->instance_size() + (index * kPointerSize); |
+ WRITE_FIELD(this, offset, value); |
+ WRITE_BARRIER(this, offset); |
+ } else { |
+ ASSERT(index < properties()->length()); |
+ properties()->set(index, value); |
+ } |
+ return value; |
+} |
+ |
+ |
void JSObject::InitializeBody(int object_size) { |
for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) { |
WRITE_FIELD(this, offset, Heap::undefined_value()); |
@@ -1529,10 +1569,15 @@ |
int Map::instance_size() { |
- return READ_BYTE_FIELD(this, kInstanceSizeOffset); |
+ return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2; |
} |
+int Map::inobject_properties() { |
+ return READ_BYTE_FIELD(this, kInObjectPropertiesOffset); |
+} |
+ |
+ |
int HeapObject::SizeFromMap(Map* map) { |
InstanceType instance_type = map->instance_type(); |
// Only inline the two most frequent cases. |
@@ -1546,11 +1591,19 @@ |
void Map::set_instance_size(int value) { |
+ ASSERT((value & ~(kPointerSize - 1)) == value); |
+ value >>= kPointerSizeLog2; |
ASSERT(0 <= value && value < 256); |
WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value)); |
} |
+void Map::set_inobject_properties(int value) { |
+ ASSERT(0 <= value && value < 256); |
+ WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value)); |
+} |
+ |
+ |
InstanceType Map::instance_type() { |
return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset)); |
} |