Allow property indexes to refer to slots inside the object header.

BUG=

Review URL: https://chromiumcodereview.appspot.com/11365221

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12944 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
mmassi@chromium.org 2012-11-13 11:07:04 +00:00
parent 50bd6e9092
commit ce682a2489
13 changed files with 151 additions and 89 deletions

View File

@ -327,18 +327,23 @@ void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
Register dst,
Register src,
Handle<JSObject> holder,
int index) {
// Adjust for the number of properties stored in the holder.
index -= holder->map()->inobject_properties();
if (index < 0) {
// Get the property straight out of the holder.
int offset = holder->map()->instance_size() + (index * kPointerSize);
PropertyIndex index) {
if (index.is_header_index()) {
int offset = index.header_index() * kPointerSize;
__ ldr(dst, FieldMemOperand(src, offset));
} else {
// Calculate the offset into the properties array.
int offset = index * kPointerSize + FixedArray::kHeaderSize;
__ ldr(dst, FieldMemOperand(src, JSObject::kPropertiesOffset));
__ ldr(dst, FieldMemOperand(dst, offset));
// Adjust for the number of properties stored in the holder.
int slot = index.field_index() - holder->map()->inobject_properties();
if (slot < 0) {
// Get the property straight out of the holder.
int offset = holder->map()->instance_size() + (slot * kPointerSize);
__ ldr(dst, FieldMemOperand(src, offset));
} else {
// Calculate the offset into the properties array.
int offset = slot * kPointerSize + FixedArray::kHeaderSize;
__ ldr(dst, FieldMemOperand(src, JSObject::kPropertiesOffset));
__ ldr(dst, FieldMemOperand(dst, offset));
}
}
}
@ -1196,7 +1201,7 @@ void StubCompiler::GenerateLoadField(Handle<JSObject> object,
Register scratch1,
Register scratch2,
Register scratch3,
int index,
PropertyIndex index,
Handle<String> name,
Label* miss) {
// Check that the receiver isn't a smi.
@ -1545,7 +1550,7 @@ void CallStubCompiler::GenerateMissBranch() {
Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
Handle<JSObject> holder,
int index,
PropertyIndex index,
Handle<String> name) {
// ----------- S t a t e -------------
// -- r2 : name
@ -2912,7 +2917,7 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<String> name,
Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object,
Handle<JSObject> holder,
int index,
PropertyIndex index,
Handle<String> name) {
// ----------- S t a t e -------------
// -- r0 : receiver
@ -3101,7 +3106,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
int index) {
PropertyIndex index) {
// ----------- S t a t e -------------
// -- lr : return address
// -- r0 : key

View File

@ -1084,11 +1084,11 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
LookupResult lookup(isolate);
result->LocalLookup(heap->callee_symbol(), &lookup);
ASSERT(lookup.IsField());
ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsCalleeIndex);
ASSERT(lookup.GetFieldIndex().field_index() == Heap::kArgumentsCalleeIndex);
result->LocalLookup(heap->length_symbol(), &lookup);
ASSERT(lookup.IsField());
ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
ASSERT(lookup.GetFieldIndex().field_index() == Heap::kArgumentsLengthIndex);
ASSERT(result->map()->inobject_properties() > Heap::kArgumentsCalleeIndex);
ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
@ -1186,7 +1186,7 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
LookupResult lookup(isolate);
result->LocalLookup(heap->length_symbol(), &lookup);
ASSERT(lookup.IsField());
ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
ASSERT(lookup.GetFieldIndex().field_index() == Heap::kArgumentsLengthIndex);
ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);

View File

@ -376,18 +376,23 @@ void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
Register dst,
Register src,
Handle<JSObject> holder,
int index) {
// Adjust for the number of properties stored in the holder.
index -= holder->map()->inobject_properties();
if (index < 0) {
// Get the property straight out of the holder.
int offset = holder->map()->instance_size() + (index * kPointerSize);
PropertyIndex index) {
if (index.is_header_index()) {
int offset = index.header_index() * kPointerSize;
__ mov(dst, FieldOperand(src, offset));
} else {
// Calculate the offset into the properties array.
int offset = index * kPointerSize + FixedArray::kHeaderSize;
__ mov(dst, FieldOperand(src, JSObject::kPropertiesOffset));
__ mov(dst, FieldOperand(dst, offset));
// Adjust for the number of properties stored in the holder.
int slot = index.field_index() - holder->map()->inobject_properties();
if (slot < 0) {
// Get the property straight out of the holder.
int offset = holder->map()->instance_size() + (slot * kPointerSize);
__ mov(dst, FieldOperand(src, offset));
} else {
// Calculate the offset into the properties array.
int offset = slot * kPointerSize + FixedArray::kHeaderSize;
__ mov(dst, FieldOperand(src, JSObject::kPropertiesOffset));
__ mov(dst, FieldOperand(dst, offset));
}
}
}
@ -1036,7 +1041,7 @@ void StubCompiler::GenerateLoadField(Handle<JSObject> object,
Register scratch1,
Register scratch2,
Register scratch3,
int index,
PropertyIndex index,
Handle<String> name,
Label* miss) {
// Check that the receiver isn't a smi.
@ -1423,7 +1428,7 @@ void CallStubCompiler::GenerateMissBranch() {
Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
Handle<JSObject> holder,
int index,
PropertyIndex index,
Handle<String> name) {
// ----------- S t a t e -------------
// -- ecx : name
@ -2956,7 +2961,7 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<String> name,
Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object,
Handle<JSObject> holder,
int index,
PropertyIndex index,
Handle<String> name) {
// ----------- S t a t e -------------
// -- ecx : name
@ -3156,7 +3161,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
int index) {
PropertyIndex index) {
// ----------- S t a t e -------------
// -- ecx : key
// -- edx : receiver

View File

@ -646,7 +646,7 @@ Handle<Code> CallICBase::ComputeMonomorphicStub(LookupResult* lookup,
Handle<JSObject> holder(lookup->holder());
switch (lookup->type()) {
case FIELD: {
int index = lookup->GetFieldIndex();
PropertyIndex index = lookup->GetFieldIndex();
return isolate()->stub_cache()->ComputeCallField(
argc, kind_, extra_state, name, object, holder, index);
}
@ -1467,11 +1467,9 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
Handle<Code> code;
switch (type) {
case FIELD:
code = isolate()->stub_cache()->ComputeStoreField(name,
receiver,
lookup->GetFieldIndex(),
Handle<Map>::null(),
strict_mode);
code = isolate()->stub_cache()->ComputeStoreField(
name, receiver, lookup->GetFieldIndex().field_index(),
Handle<Map>::null(), strict_mode);
break;
case NORMAL:
if (receiver->IsGlobalObject()) {
@ -1981,7 +1979,7 @@ void KeyedStoreIC::UpdateCaches(LookupResult* lookup,
switch (type) {
case FIELD:
code = isolate()->stub_cache()->ComputeKeyedStoreField(
name, receiver, lookup->GetFieldIndex(),
name, receiver, lookup->GetFieldIndex().field_index(),
Handle<Map>::null(), strict_mode);
break;
case TRANSITION: {

View File

@ -274,7 +274,8 @@ Handle<Object> BasicJsonStringifier::GetProperty(Handle<JSObject> object,
return Handle<Object>(value, isolate_);
}
case FIELD: {
Object* value = lookup.holder()->FastPropertyAt(lookup.GetFieldIndex());
Object* value = lookup.holder()->FastPropertyAt(
lookup.GetFieldIndex().field_index());
ASSERT(!value->IsTheHole());
return Handle<Object>(value, isolate_);
}

View File

@ -314,18 +314,23 @@ void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
Register dst,
Register src,
Handle<JSObject> holder,
int index) {
// Adjust for the number of properties stored in the holder.
index -= holder->map()->inobject_properties();
if (index < 0) {
// Get the property straight out of the holder.
int offset = holder->map()->instance_size() + (index * kPointerSize);
PropertyIndex index) {
if (index.is_header_index()) {
int offset = index.header_index() * kPointerSize;
__ lw(dst, FieldMemOperand(src, offset));
} else {
// Calculate the offset into the properties array.
int offset = index * kPointerSize + FixedArray::kHeaderSize;
__ lw(dst, FieldMemOperand(src, JSObject::kPropertiesOffset));
__ lw(dst, FieldMemOperand(dst, offset));
// Adjust for the number of properties stored in the holder.
int slot = index.field_index() - holder->map()->inobject_properties();
if (slot < 0) {
// Get the property straight out of the holder.
int offset = holder->map()->instance_size() + (slot * kPointerSize);
__ lw(dst, FieldMemOperand(src, offset));
} else {
// Calculate the offset into the properties array.
int offset = slot * kPointerSize + FixedArray::kHeaderSize;
__ lw(dst, FieldMemOperand(src, JSObject::kPropertiesOffset));
__ lw(dst, FieldMemOperand(dst, offset));
}
}
}
@ -1200,7 +1205,7 @@ void StubCompiler::GenerateLoadField(Handle<JSObject> object,
Register scratch1,
Register scratch2,
Register scratch3,
int index,
PropertyIndex index,
Handle<String> name,
Label* miss) {
// Check that the receiver isn't a smi.

View File

@ -641,7 +641,8 @@ MaybeObject* Object::GetProperty(Object* receiver,
ASSERT(!value->IsTheHole() || result->IsReadOnly());
return value->IsTheHole() ? heap->undefined_value() : value;
case FIELD:
value = result->holder()->FastPropertyAt(result->GetFieldIndex());
value = result->holder()->FastPropertyAt(
result->GetFieldIndex().field_index());
ASSERT(!value->IsTheHole() || result->IsReadOnly());
return value->IsTheHole() ? heap->undefined_value() : value;
case CONSTANT_FUNCTION:
@ -2436,7 +2437,7 @@ void JSObject::LocalLookupRealNamedProperty(String* name,
// occur as fields.
if (result->IsField() &&
result->IsReadOnly() &&
FastPropertyAt(result->GetFieldIndex())->IsTheHole()) {
FastPropertyAt(result->GetFieldIndex().field_index())->IsTheHole()) {
result->DisallowCaching();
}
return;
@ -2929,7 +2930,8 @@ MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup,
result = self->SetNormalizedProperty(lookup, *value);
break;
case FIELD:
result = self->FastPropertyAtPut(lookup->GetFieldIndex(), *value);
result = self->FastPropertyAtPut(
lookup->GetFieldIndex().field_index(), *value);
break;
case CONSTANT_FUNCTION:
// Only replace the function if necessary.
@ -3095,7 +3097,8 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
break;
}
case FIELD:
result = self->FastPropertyAtPut(lookup.GetFieldIndex(), *value);
result = self->FastPropertyAtPut(
lookup.GetFieldIndex().field_index(), *value);
break;
case CONSTANT_FUNCTION:
// Only replace the function if necessary.

View File

@ -63,7 +63,7 @@ void LookupResult::Print(FILE* out) {
break;
case FIELD:
PrintF(out, " -type = field\n");
PrintF(out, " -index = %d", GetFieldIndex());
PrintF(out, " -index = %d", GetFieldIndex().field_index());
PrintF(out, "\n");
break;
case CALLBACKS:

View File

@ -132,6 +132,44 @@ class CallbacksDescriptor: public Descriptor {
};
// Holds a property index value distinguishing if it is a field index or an
// index inside the object header.
class PropertyIndex {
public:
static PropertyIndex NewFieldIndex(int index) {
return PropertyIndex(index, false);
}
static PropertyIndex NewHeaderIndex(int index) {
return PropertyIndex(index, true);
}
bool is_field_index() { return (index_ & kHeaderIndexBit) == 0; }
bool is_header_index() { return (index_ & kHeaderIndexBit) != 0; }
int field_index() {
ASSERT(is_field_index());
return value();
}
int header_index() {
ASSERT(is_header_index());
return value();
}
private:
static const int kHeaderIndexBit = 1 << 31;
static const int kIndexMask = ~kHeaderIndexBit;
int value() { return index_ & kIndexMask; }
PropertyIndex(int index, bool is_header_based)
: index_(index | (is_header_based ? kHeaderIndexBit : 0)) {
ASSERT(index <= kIndexMask);
}
int index_;
};
class LookupResult BASE_EMBEDDED {
public:
explicit LookupResult(Isolate* isolate)
@ -278,7 +316,7 @@ class LookupResult BASE_EMBEDDED {
Object* GetLazyValue() {
switch (type()) {
case FIELD:
return holder()->FastPropertyAt(GetFieldIndex());
return holder()->FastPropertyAt(GetFieldIndex().field_index());
case NORMAL: {
Object* value;
value = holder()->property_dictionary()->ValueAt(GetDictionaryEntry());
@ -334,10 +372,11 @@ class LookupResult BASE_EMBEDDED {
return number_;
}
int GetFieldIndex() {
PropertyIndex GetFieldIndex() {
ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
ASSERT(IsField());
return Descriptor::IndexFromValue(GetValue());
return PropertyIndex::NewFieldIndex(
Descriptor::IndexFromValue(GetValue()));
}
int GetLocalFieldIndexFromMap(Map* map) {

View File

@ -1679,7 +1679,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
// Strict mode handling not needed (const is disallowed in strict mode).
if (lookup.IsField()) {
FixedArray* properties = global->properties();
int index = lookup.GetFieldIndex();
int index = lookup.GetFieldIndex().field_index();
if (properties->get(index)->IsTheHole() || !lookup.IsReadOnly()) {
properties->set(index, *value);
}
@ -1769,7 +1769,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) {
if (lookup.IsField()) {
FixedArray* properties = object->properties();
int index = lookup.GetFieldIndex();
int index = lookup.GetFieldIndex().field_index();
if (properties->get(index)->IsTheHole()) {
properties->set(index, *value);
}
@ -4076,7 +4076,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) {
LookupResult result(isolate);
receiver->LocalLookup(key, &result);
if (result.IsField()) {
int offset = result.GetFieldIndex();
int offset = result.GetFieldIndex().field_index();
keyed_lookup_cache->Update(receiver_map, key, offset);
return receiver->FastPropertyAt(offset);
}
@ -4250,7 +4250,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDataProperty) {
case NORMAL:
return lookup.holder()->GetNormalizedProperty(&lookup);
case FIELD:
return lookup.holder()->FastPropertyAt(lookup.GetFieldIndex());
return lookup.holder()->FastPropertyAt(
lookup.GetFieldIndex().field_index());
case CONSTANT_FUNCTION:
return lookup.GetConstantFunction();
case CALLBACKS:
@ -10010,8 +10011,8 @@ static MaybeObject* DebugLookupResultValue(Heap* heap,
return value;
case FIELD:
value =
JSObject::cast(
result->holder())->FastPropertyAt(result->GetFieldIndex());
JSObject::cast(result->holder())->FastPropertyAt(
result->GetFieldIndex().field_index());
if (value->IsTheHole()) {
return heap->undefined_value();
}

View File

@ -136,7 +136,7 @@ Handle<Code> StubCache::ComputeLoadNonexistent(Handle<String> name,
Handle<Code> StubCache::ComputeLoadField(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
int field_index) {
PropertyIndex field_index) {
ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::FIELD);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
@ -261,7 +261,7 @@ Handle<Code> StubCache::ComputeLoadGlobal(Handle<String> name,
Handle<Code> StubCache::ComputeKeyedLoadField(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
int field_index) {
PropertyIndex field_index) {
ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
Code::Flags flags =
Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::FIELD);
@ -632,7 +632,7 @@ Handle<Code> StubCache::ComputeCallField(int argc,
Handle<String> name,
Handle<Object> object,
Handle<JSObject> holder,
int index) {
PropertyIndex index) {
// Compute the check type and the map.
InlineCacheHolderFlag cache_holder =
IC::GetCodeCacheForObject(*object, *holder);

View File

@ -83,7 +83,7 @@ class StubCache {
Handle<Code> ComputeLoadField(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
int field_index);
PropertyIndex field_index);
Handle<Code> ComputeLoadCallback(Handle<String> name,
Handle<JSObject> receiver,
@ -117,7 +117,7 @@ class StubCache {
Handle<Code> ComputeKeyedLoadField(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
int field_index);
PropertyIndex field_index);
Handle<Code> ComputeKeyedLoadCallback(Handle<String> name,
Handle<JSObject> receiver,
@ -193,7 +193,7 @@ class StubCache {
Handle<String> name,
Handle<Object> object,
Handle<JSObject> holder,
int index);
PropertyIndex index);
Handle<Code> ComputeCallConstant(int argc,
Code::Kind,
@ -453,7 +453,7 @@ class StubCompiler BASE_EMBEDDED {
Register dst,
Register src,
Handle<JSObject> holder,
int index);
PropertyIndex index);
static void GenerateLoadArrayLength(MacroAssembler* masm,
Register receiver,
@ -540,7 +540,7 @@ class StubCompiler BASE_EMBEDDED {
Register scratch1,
Register scratch2,
Register scratch3,
int index,
PropertyIndex index,
Handle<String> name,
Label* miss);
@ -611,7 +611,7 @@ class LoadStubCompiler: public StubCompiler {
Handle<Code> CompileLoadField(Handle<JSObject> object,
Handle<JSObject> holder,
int index,
PropertyIndex index,
Handle<String> name);
Handle<Code> CompileLoadCallback(Handle<String> name,
@ -654,7 +654,7 @@ class KeyedLoadStubCompiler: public StubCompiler {
Handle<Code> CompileLoadField(Handle<String> name,
Handle<JSObject> object,
Handle<JSObject> holder,
int index);
PropertyIndex index);
Handle<Code> CompileLoadCallback(Handle<String> name,
Handle<JSObject> object,
@ -803,7 +803,7 @@ class CallStubCompiler: public StubCompiler {
Handle<Code> CompileCallField(Handle<JSObject> object,
Handle<JSObject> holder,
int index,
PropertyIndex index,
Handle<String> name);
Handle<Code> CompileCallConstant(Handle<Object> object,

View File

@ -350,18 +350,23 @@ void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
Register dst,
Register src,
Handle<JSObject> holder,
int index) {
// Adjust for the number of properties stored in the holder.
index -= holder->map()->inobject_properties();
if (index < 0) {
// Get the property straight out of the holder.
int offset = holder->map()->instance_size() + (index * kPointerSize);
PropertyIndex index) {
if (index.is_header_index()) {
int offset = index.header_index() * kPointerSize;
__ movq(dst, FieldOperand(src, offset));
} else {
// Calculate the offset into the properties array.
int offset = index * kPointerSize + FixedArray::kHeaderSize;
__ movq(dst, FieldOperand(src, JSObject::kPropertiesOffset));
__ movq(dst, FieldOperand(dst, offset));
// Adjust for the number of properties stored in the holder.
int slot = index.field_index() - holder->map()->inobject_properties();
if (slot < 0) {
// Get the property straight out of the holder.
int offset = holder->map()->instance_size() + (slot * kPointerSize);
__ movq(dst, FieldOperand(src, offset));
} else {
// Calculate the offset into the properties array.
int offset = slot * kPointerSize + FixedArray::kHeaderSize;
__ movq(dst, FieldOperand(src, JSObject::kPropertiesOffset));
__ movq(dst, FieldOperand(dst, offset));
}
}
}
@ -1013,7 +1018,7 @@ void StubCompiler::GenerateLoadField(Handle<JSObject> object,
Register scratch1,
Register scratch2,
Register scratch3,
int index,
PropertyIndex index,
Handle<String> name,
Label* miss) {
// Check that the receiver isn't a smi.
@ -1388,7 +1393,7 @@ void CallStubCompiler::GenerateMissBranch() {
Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
Handle<JSObject> holder,
int index,
PropertyIndex index,
Handle<String> name) {
// ----------- S t a t e -------------
// rcx : function name
@ -2780,7 +2785,7 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<String> name,
Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object,
Handle<JSObject> holder,
int index,
PropertyIndex index,
Handle<String> name) {
// ----------- S t a t e -------------
// -- rax : receiver
@ -2973,7 +2978,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
int index) {
PropertyIndex index) {
// ----------- S t a t e -------------
// -- rax : key
// -- rdx : receiver