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));
+ }
}
}
Register scratch1,
Register scratch2,
Register scratch3,
- int index,
+ PropertyIndex index,
Handle<String> name,
Label* miss) {
// Check that the receiver isn't a smi.
Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
Handle<JSObject> holder,
- int index,
+ PropertyIndex index,
Handle<String> name) {
// ----------- S t a t e -------------
// -- r2 : 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
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
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);
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);
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));
+ }
}
}
Register scratch1,
Register scratch2,
Register scratch3,
- int index,
+ PropertyIndex index,
Handle<String> name,
Label* miss) {
// Check that the receiver isn't a smi.
Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
Handle<JSObject> holder,
- int index,
+ PropertyIndex index,
Handle<String> name) {
// ----------- S t a t e -------------
// -- ecx : 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
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
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);
}
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()) {
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: {
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_);
}
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));
+ }
}
}
Register scratch1,
Register scratch2,
Register scratch3,
- int index,
+ PropertyIndex index,
Handle<String> name,
Label* miss) {
// Check that the receiver isn't a smi.
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:
// occur as fields.
if (result->IsField() &&
result->IsReadOnly() &&
- FastPropertyAt(result->GetFieldIndex())->IsTheHole()) {
+ FastPropertyAt(result->GetFieldIndex().field_index())->IsTheHole()) {
result->DisallowCaching();
}
return;
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.
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.
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:
};
+// 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)
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());
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) {
// 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);
}
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);
}
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);
}
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:
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();
}
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));
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);
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);
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,
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,
Handle<String> name,
Handle<Object> object,
Handle<JSObject> holder,
- int index);
+ PropertyIndex index);
Handle<Code> ComputeCallConstant(int argc,
Code::Kind,
Register dst,
Register src,
Handle<JSObject> holder,
- int index);
+ PropertyIndex index);
static void GenerateLoadArrayLength(MacroAssembler* masm,
Register receiver,
Register scratch1,
Register scratch2,
Register scratch3,
- int index,
+ PropertyIndex index,
Handle<String> name,
Label* miss);
Handle<Code> CompileLoadField(Handle<JSObject> object,
Handle<JSObject> holder,
- int index,
+ PropertyIndex index,
Handle<String> name);
Handle<Code> CompileLoadCallback(Handle<String> name,
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,
Handle<Code> CompileCallField(Handle<JSObject> object,
Handle<JSObject> holder,
- int index,
+ PropertyIndex index,
Handle<String> name);
Handle<Code> CompileCallConstant(Handle<Object> object,
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));
+ }
}
}
Register scratch1,
Register scratch2,
Register scratch3,
- int index,
+ PropertyIndex index,
Handle<String> name,
Label* miss) {
// Check that the receiver isn't a smi.
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
Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object,
Handle<JSObject> holder,
- int index,
+ PropertyIndex index,
Handle<String> name) {
// ----------- S t a t e -------------
// -- rax : receiver
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