// checks.
ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
- FieldIndex index = lookup->GetFieldIndex();
+ int index = lookup->GetFieldIndex().field_index();
+
+ // Adjust for the number of properties stored in the object. Even in the
+ // face of a transition we can use the old map here because the size of the
+ // object and the number of in-object properties is not going to change.
+ index -= object->map()->inobject_properties();
Representation representation = lookup->representation();
ASSERT(!representation.IsNone());
}
} else if (representation.IsDouble()) {
// Load the double storage.
- if (index.is_inobject()) {
- __ ldr(scratch1, FieldMemOperand(receiver_reg, index.offset()));
+ if (index < 0) {
+ int offset = object->map()->instance_size() + (index * kPointerSize);
+ __ ldr(scratch1, FieldMemOperand(receiver_reg, offset));
} else {
__ ldr(scratch1,
FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
- __ ldr(scratch1, FieldMemOperand(scratch1, index.offset()));
+ int offset = index * kPointerSize + FixedArray::kHeaderSize;
+ __ ldr(scratch1, FieldMemOperand(scratch1, offset));
}
// Store the value into the storage.
// TODO(verwaest): Share this code as a code stub.
SmiCheck smi_check = representation.IsTagged()
? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
- if (index.is_inobject()) {
+ if (index < 0) {
// Set the property straight into the object.
- __ str(value_reg, FieldMemOperand(receiver_reg, index.offset()));
+ int offset = object->map()->instance_size() + (index * kPointerSize);
+ __ str(value_reg, FieldMemOperand(receiver_reg, offset));
if (!representation.IsSmi()) {
// Skip updating write barrier if storing a smi.
// Pass the now unused name_reg as a scratch register.
__ mov(name_reg, value_reg);
__ RecordWriteField(receiver_reg,
- index.offset(),
+ offset,
name_reg,
scratch1,
kLRHasNotBeenSaved,
}
} else {
// Write to the properties array.
+ int offset = index * kPointerSize + FixedArray::kHeaderSize;
// Get the properties array
__ ldr(scratch1,
FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
- __ str(value_reg, FieldMemOperand(scratch1, index.offset()));
+ __ str(value_reg, FieldMemOperand(scratch1, offset));
if (!representation.IsSmi()) {
// Skip updating write barrier if storing a smi.
// Ok to clobber receiver_reg and name_reg, since we return.
__ mov(name_reg, value_reg);
__ RecordWriteField(scratch1,
- index.offset(),
+ offset,
name_reg,
receiver_reg,
kLRHasNotBeenSaved,
void LoadStubCompiler::GenerateLoadField(Register reg,
Handle<JSObject> holder,
- FieldIndex field,
+ PropertyIndex field,
Representation representation) {
if (!reg.is(receiver())) __ mov(receiver(), reg);
if (kind() == Code::LOAD_IC) {
- LoadFieldStub stub(isolate(), field);
+ LoadFieldStub stub(isolate(),
+ field.is_inobject(holder),
+ field.translate(holder),
+ representation);
GenerateTailCall(masm(), stub.GetCode());
} else {
- KeyedLoadFieldStub stub(isolate(), field);
+ KeyedLoadFieldStub stub(isolate(),
+ field.is_inobject(holder),
+ field.translate(holder),
+ representation);
GenerateTailCall(masm(), stub.GetCode());
}
}
// checks.
ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
- FieldIndex index = lookup->GetFieldIndex();
+ int index = lookup->GetFieldIndex().field_index();
+
+ // Adjust for the number of properties stored in the object. Even in the
+ // face of a transition we can use the old map here because the size of the
+ // object and the number of in-object properties is not going to change.
+ index -= object->map()->inobject_properties();
Representation representation = lookup->representation();
ASSERT(!representation.IsNone());
__ SmiUntagToDouble(temp_double, value_reg, kSpeculativeUntag);
// Load the double storage.
- if (index.is_inobject()) {
- __ Ldr(scratch1, FieldMemOperand(receiver_reg, index.offset()));
+ if (index < 0) {
+ int offset = (index * kPointerSize) + object->map()->instance_size();
+ __ Ldr(scratch1, FieldMemOperand(receiver_reg, offset));
} else {
+ int offset = (index * kPointerSize) + FixedArray::kHeaderSize;
__ Ldr(scratch1,
FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
- __ Ldr(scratch1, FieldMemOperand(scratch1, index.offset()));
+ __ Ldr(scratch1, FieldMemOperand(scratch1, offset));
}
// Store the value into the storage.
// TODO(verwaest): Share this code as a code stub.
SmiCheck smi_check = representation.IsTagged()
? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
- if (index.is_inobject()) {
+ if (index < 0) {
// Set the property straight into the object.
- __ Str(value_reg, FieldMemOperand(receiver_reg, index.offset()));
+ int offset = object->map()->instance_size() + (index * kPointerSize);
+ __ Str(value_reg, FieldMemOperand(receiver_reg, offset));
if (!representation.IsSmi()) {
// Skip updating write barrier if storing a smi.
// Pass the now unused name_reg as a scratch register.
__ Mov(name_reg, value_reg);
__ RecordWriteField(receiver_reg,
- index.offset(),
+ offset,
name_reg,
scratch1,
kLRHasNotBeenSaved,
}
} else {
// Write to the properties array.
+ int offset = index * kPointerSize + FixedArray::kHeaderSize;
// Get the properties array
__ Ldr(scratch1,
FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
- __ Str(value_reg, FieldMemOperand(scratch1, index.offset()));
+ __ Str(value_reg, FieldMemOperand(scratch1, offset));
if (!representation.IsSmi()) {
// Skip updating write barrier if storing a smi.
// Ok to clobber receiver_reg and name_reg, since we return.
__ Mov(name_reg, value_reg);
__ RecordWriteField(scratch1,
- index.offset(),
+ offset,
name_reg,
receiver_reg,
kLRHasNotBeenSaved,
void LoadStubCompiler::GenerateLoadField(Register reg,
Handle<JSObject> holder,
- FieldIndex field,
+ PropertyIndex field,
Representation representation) {
__ Mov(receiver(), reg);
if (kind() == Code::LOAD_IC) {
- LoadFieldStub stub(isolate(), field);
+ LoadFieldStub stub(isolate(),
+ field.is_inobject(holder),
+ field.translate(holder),
+ representation);
GenerateTailCall(masm(), stub.GetCode());
} else {
- KeyedLoadFieldStub stub(isolate(), field);
+ KeyedLoadFieldStub stub(isolate(),
+ field.is_inobject(holder),
+ field.translate(holder),
+ representation);
GenerateTailCall(masm(), stub.GetCode());
}
}
LookupResult lookup(isolate);
result->LookupOwn(factory->callee_string(), &lookup);
ASSERT(lookup.IsField());
- ASSERT(lookup.GetFieldIndex().property_index() ==
- Heap::kArgumentsCalleeIndex);
+ ASSERT(lookup.GetFieldIndex().field_index() == Heap::kArgumentsCalleeIndex);
result->LookupOwn(factory->length_string(), &lookup);
ASSERT(lookup.IsField());
- ASSERT(lookup.GetFieldIndex().property_index() ==
- 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->LookupOwn(factory->length_string(), &lookup);
ASSERT(lookup.IsField());
- ASSERT(lookup.GetFieldIndex().property_index() ==
- Heap::kArgumentsLengthIndex);
+ ASSERT(lookup.GetFieldIndex().field_index() == Heap::kArgumentsLengthIndex);
ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
case FIELD: {
HandleScope inner(isolate());
Handle<Name> key = Handle<Name>(descs->GetKey(i));
- FieldIndex index = FieldIndex::ForDescriptor(from->map(), i);
+ int index = descs->GetFieldIndex(i);
ASSERT(!descs->GetDetails(i).representation().IsDouble());
Handle<Object> value = Handle<Object>(from->RawFastPropertyAt(index),
isolate());
#include "src/v8.h"
#include "src/code-stubs.h"
-#include "src/field-index.h"
#include "src/hydrogen.h"
#include "src/lithium.h"
Isolate* isolate() { return info_.isolate(); }
HLoadNamedField* BuildLoadNamedField(HValue* object,
- FieldIndex index);
+ Representation representation,
+ int offset,
+ bool is_inobject);
enum ArgumentClass {
NONE,
HLoadNamedField* CodeStubGraphBuilderBase::BuildLoadNamedField(
- HValue* object, FieldIndex index) {
- Representation representation = index.is_double()
- ? Representation::Double()
- : Representation::Tagged();
- int offset = index.offset();
- HObjectAccess access = index.is_inobject()
+ HValue* object,
+ Representation representation,
+ int offset,
+ bool is_inobject) {
+ HObjectAccess access = is_inobject
? HObjectAccess::ForObservableJSObjectOffset(offset, representation)
: HObjectAccess::ForBackingStoreOffset(offset, representation);
- if (index.is_double()) {
+ if (representation.IsDouble()) {
// Load the heap number.
object = Add<HLoadNamedField>(
object, static_cast<HValue*>(NULL),
template<>
HValue* CodeStubGraphBuilder<LoadFieldStub>::BuildCodeStub() {
- return BuildLoadNamedField(GetParameter(0), casted_stub()->index());
+ return BuildLoadNamedField(GetParameter(0),
+ casted_stub()->representation(),
+ casted_stub()->offset(),
+ casted_stub()->is_inobject());
}
template<>
HValue* CodeStubGraphBuilder<StringLengthStub>::BuildCodeStub() {
- HValue* string = BuildLoadNamedField(GetParameter(0),
- FieldIndex::ForInObjectOffset(JSValue::kValueOffset));
- return BuildLoadNamedField(string,
- FieldIndex::ForInObjectOffset(String::kLengthOffset));
+ HValue* string = BuildLoadNamedField(
+ GetParameter(0), Representation::Tagged(), JSValue::kValueOffset, true);
+ return BuildLoadNamedField(
+ string, Representation::Tagged(), String::kLengthOffset, true);
}
class LoadFieldStub: public HandlerStub {
public:
- LoadFieldStub(Isolate* isolate, FieldIndex index)
- : HandlerStub(isolate), index_(index) {
- Initialize(Code::LOAD_IC);
+ LoadFieldStub(Isolate* isolate,
+ bool inobject,
+ int index, Representation representation)
+ : HandlerStub(isolate) {
+ Initialize(Code::LOAD_IC, inobject, index, representation);
}
virtual Handle<Code> GenerateCode() V8_OVERRIDE;
return KindBits::decode(bit_field_);
}
- FieldIndex index() const { return index_; }
+ bool is_inobject() {
+ return InobjectBits::decode(bit_field_);
+ }
+
+ int offset() {
+ int index = IndexBits::decode(bit_field_);
+ int offset = index * kPointerSize;
+ if (is_inobject()) return offset;
+ return FixedArray::kHeaderSize + offset;
+ }
bool unboxed_double() {
- return index_.is_double();
+ return UnboxedDoubleBits::decode(bit_field_);
}
virtual Code::StubType GetStubType() { return Code::FAST; }
protected:
- explicit LoadFieldStub(Isolate* isolate);
+ explicit LoadFieldStub(Isolate* isolate) : HandlerStub(isolate) { }
- void Initialize(Code::Kind kind) {
- int property_index_key = index_.GetLoadFieldStubKey();
- // Save a copy of the essence of the property index into the bit field to
- // make sure that hashing of unique stubs works correctly..
- bit_field_ = KindBits::encode(kind) |
- EncodedLoadFieldByIndexBits::encode(property_index_key);
+ void Initialize(Code::Kind kind,
+ bool inobject,
+ int index,
+ Representation representation) {
+ bit_field_ = KindBits::encode(kind)
+ | InobjectBits::encode(inobject)
+ | IndexBits::encode(index)
+ | UnboxedDoubleBits::encode(representation.IsDouble());
}
private:
STATIC_ASSERT(KindBits::kSize == 4);
- class EncodedLoadFieldByIndexBits: public BitField<int, 4, 13> {};
+ class InobjectBits: public BitField<bool, 4, 1> {};
+ class IndexBits: public BitField<int, 5, 11> {};
+ class UnboxedDoubleBits: public BitField<bool, 16, 1> {};
virtual CodeStub::Major MajorKey() { return LoadField; }
- FieldIndex index_;
};
class KeyedLoadFieldStub: public LoadFieldStub {
public:
- KeyedLoadFieldStub(Isolate* isolate, FieldIndex index)
- : LoadFieldStub(isolate, index) {
- Initialize(Code::KEYED_LOAD_IC);
+ KeyedLoadFieldStub(Isolate* isolate,
+ bool inobject,
+ int index, Representation representation)
+ : LoadFieldStub(isolate) {
+ Initialize(Code::KEYED_LOAD_IC, inobject, index, representation);
}
virtual void InitializeInterfaceDescriptor(
object->set_elements(FixedArrayBase::cast(*elements));
for (int i = 0; i < length - 3; ++i) {
Handle<Object> value = MaterializeNextValue();
- FieldIndex index = FieldIndex::ForPropertyIndex(object->map(), i);
- object->FastPropertyAtPut(index, *value);
+ object->FastPropertyAtPut(i, *value);
}
break;
}
object->set_elements(FixedArrayBase::cast(*elements));
for (int i = 0; i < length - 3; ++i) {
Handle<Object> value = GetNext(isolate, lvl + 1);
- FieldIndex index = FieldIndex::ForPropertyIndex(object->map(), i);
- object->FastPropertyAtPut(index, *value);
+ object->FastPropertyAtPut(i, *value);
}
return object;
}
+++ /dev/null
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_FIELD_INDEX_INL_H_
-#define V8_FIELD_INDEX_INL_H_
-
-#include "src/field-index.h"
-
-namespace v8 {
-namespace internal {
-
-
-inline FieldIndex FieldIndex::ForInObjectOffset(int offset, Map* map) {
- ASSERT((offset % kPointerSize) == 0);
- int index = offset / kPointerSize;
- if (map == NULL) {
- return FieldIndex(true, index, false, index + 1, 0, true);
- }
- int first_inobject_offset = map->GetInObjectPropertyOffset(0);
- if (offset < first_inobject_offset) {
- return FieldIndex(true, index, false, 0, 0, true);
- } else {
- return FieldIndex::ForPropertyIndex(map, offset / kPointerSize);
- }
-}
-
-
-inline FieldIndex FieldIndex::ForPropertyIndex(Map* map,
- int property_index,
- bool is_double) {
- ASSERT(map->instance_type() >= FIRST_NONSTRING_TYPE);
- int inobject_properties = map->inobject_properties();
- bool is_inobject = property_index < inobject_properties;
- int first_inobject_offset;
- if (is_inobject) {
- first_inobject_offset = map->GetInObjectPropertyOffset(0);
- } else {
- first_inobject_offset = FixedArray::kHeaderSize;
- property_index -= inobject_properties;
- }
- return FieldIndex(is_inobject,
- property_index + first_inobject_offset / kPointerSize,
- is_double, inobject_properties, first_inobject_offset);
-}
-
-
-inline FieldIndex FieldIndex::ForLoadByFieldIndex(Map* map, int orig_index) {
- int field_index = orig_index;
- int is_inobject = true;
- bool is_double = field_index & 1;
- int first_inobject_offset = 0;
- field_index >>= 1;
- if (field_index < 0) {
- field_index = -(field_index + 1);
- is_inobject = false;
- first_inobject_offset = FixedArray::kHeaderSize;
- field_index += FixedArray::kHeaderSize / kPointerSize;
- } else {
- first_inobject_offset = map->GetInObjectPropertyOffset(0);
- field_index += JSObject::kHeaderSize / kPointerSize;
- }
- return FieldIndex(is_inobject, field_index, is_double,
- map->inobject_properties(), first_inobject_offset);
-}
-
-
-inline FieldIndex FieldIndex::ForDescriptor(Map* map, int descriptor_index) {
- PropertyDetails details =
- map->instance_descriptors()->GetDetails(descriptor_index);
- int field_index =
- map->instance_descriptors()->GetFieldIndex(descriptor_index);
- return ForPropertyIndex(map, field_index,
- details.representation().IsDouble());
-}
-
-
-} } // namespace v8::internal
-
-#endif
+++ /dev/null
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/v8.h"
-
-#include "src/field-index.h"
-#include "src/objects.h"
-#include "src/objects-inl.h"
-
-namespace v8 {
-namespace internal {
-
-
-FieldIndex FieldIndex::ForLookupResult(const LookupResult* lookup_result) {
- Map* map = lookup_result->holder()->map();
- return ForPropertyIndex(map,
- lookup_result->GetFieldIndexFromMap(map),
- lookup_result->representation().IsDouble());
-}
-
-
-} } // namespace v8::internal
+++ /dev/null
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_FIELD_INDEX_H_
-#define V8_FIELD_INDEX_H_
-
-#include "src/utils.h"
-#include "src/property-details.h"
-
-namespace v8 {
-namespace internal {
-
-class Map;
-
-// Wrapper class to hold a field index, usually but not necessarily generated
-// from a property index. When available, the wrapper class captures additional
-// information to allow the field index to be translated back into the property
-// index it was originally generated from.
-class FieldIndex V8_FINAL {
- public:
- static FieldIndex ForPropertyIndex(Map* map,
- int index,
- bool is_double = false);
- static FieldIndex ForInObjectOffset(int offset, Map* map = NULL);
- static FieldIndex ForLookupResult(const LookupResult* result);
- static FieldIndex ForDescriptor(Map* map, int descriptor_index);
- static FieldIndex ForLoadByFieldIndex(Map* map, int index);
- static FieldIndex ForKeyedLookupCacheIndex(Map* map, int index) {
- return ForPropertyIndex(map, index);
- }
-
- bool is_inobject() const {
- return IsInObjectBits::decode(bit_field_);
- }
-
- bool is_double() const {
- return IsDoubleBits::decode(bit_field_);
- }
-
- int offset() const {
- return index() * kPointerSize;
- }
-
- int index() const {
- return IndexBits::decode(bit_field_);
- }
-
- int outobject_array_index() const {
- ASSERT(!is_inobject());
- return index() - first_inobject_property_offset() / kPointerSize;
- }
-
- int property_index() const {
- ASSERT(!IsHiddenField::decode(bit_field_));
- int result = index() - first_inobject_property_offset() / kPointerSize;
- if (!is_inobject()) {
- result += InObjectPropertyBits::decode(bit_field_);
- }
- return result;
- }
-
- int GetLoadByFieldIndex() const {
- // For efficiency, the LoadByFieldIndex instruction takes an index that is
- // optimized for quick access. If the property is inline, the index is
- // positive. If it's out-of-line, the encoded index is -raw_index - 1 to
- // disambiguate the zero out-of-line index from the zero inobject case.
- // The index itself is shifted up by one bit, the lower-most bit
- // signifying if the field is a mutable double box (1) or not (0).
- int result = index() - first_inobject_property_offset() / kPointerSize;
- if (!is_inobject()) {
- result = -result - 1;
- }
- result <<= 1;
- return is_double() ? (result | 1) : result;
- }
-
- int GetKeyedLookupCacheIndex() const {
- return property_index();
- }
-
- int GetLoadFieldStubKey() const {
- return bit_field_ &
- (IsInObjectBits::kMask | IsDoubleBits::kMask | IndexBits::kMask);
- }
-
- private:
- FieldIndex(bool is_inobject, int local_index, bool is_double,
- int inobject_properties, int first_inobject_property_offset,
- bool is_hidden = false) {
- ASSERT((first_inobject_property_offset & (kPointerSize - 1)) == 0);
- bit_field_ = IsInObjectBits::encode(is_inobject) |
- IsDoubleBits::encode(is_double) |
- FirstInobjectPropertyOffsetBits::encode(first_inobject_property_offset) |
- IsHiddenField::encode(is_hidden) |
- IndexBits::encode(local_index) |
- InObjectPropertyBits::encode(inobject_properties);
- }
-
- int first_inobject_property_offset() const {
- ASSERT(!IsHiddenField::decode(bit_field_));
- return FirstInobjectPropertyOffsetBits::decode(bit_field_);
- }
-
- static const int kIndexBitsSize = kDescriptorIndexBitCount + 1;
-
- class IndexBits: public BitField<int, 0, kIndexBitsSize> {};
- class IsInObjectBits: public BitField<bool, IndexBits::kNext, 1> {};
- class IsDoubleBits: public BitField<bool, IsInObjectBits::kNext, 1> {};
- class InObjectPropertyBits: public BitField<int, IsDoubleBits::kNext,
- kDescriptorIndexBitCount> {};
- class FirstInobjectPropertyOffsetBits:
- public BitField<int, InObjectPropertyBits::kNext, 7> {};
- class IsHiddenField:
- public BitField<bool, FirstInobjectPropertyOffsetBits::kNext, 1> {};
- STATIC_ASSERT(IsHiddenField::kNext <= 32);
-
- int bit_field_;
-};
-
-} } // namespace v8::internal
-
-#endif
js_obj->GetInObjectPropertyOffset(index));
}
} else {
- FieldIndex field_index =
- FieldIndex::ForDescriptor(js_obj->map(), i);
- Object* value = js_obj->RawFastPropertyAt(field_index);
+ Object* value = js_obj->RawFastPropertyAt(index);
if (k != heap_->hidden_string()) {
SetPropertyReference(js_obj, entry, k, value);
} else {
// checks.
ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
- FieldIndex index = lookup->GetFieldIndex();
+ int index = lookup->GetFieldIndex().field_index();
+
+ // Adjust for the number of properties stored in the object. Even in the
+ // face of a transition we can use the old map here because the size of the
+ // object and the number of in-object properties is not going to change.
+ index -= object->map()->inobject_properties();
Representation representation = lookup->representation();
ASSERT(!representation.IsNone());
}
} else if (representation.IsDouble()) {
// Load the double storage.
- if (index.is_inobject()) {
- __ mov(scratch1, FieldOperand(receiver_reg, index.offset()));
+ if (index < 0) {
+ int offset = object->map()->instance_size() + (index * kPointerSize);
+ __ mov(scratch1, FieldOperand(receiver_reg, offset));
} else {
__ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
- __ mov(scratch1, FieldOperand(scratch1, index.offset()));
+ int offset = index * kPointerSize + FixedArray::kHeaderSize;
+ __ mov(scratch1, FieldOperand(scratch1, offset));
}
// Store the value into the storage.
// TODO(verwaest): Share this code as a code stub.
SmiCheck smi_check = representation.IsTagged()
? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
- if (index.is_inobject()) {
+ if (index < 0) {
// Set the property straight into the object.
- __ mov(FieldOperand(receiver_reg, index.offset()), value_reg);
+ int offset = object->map()->instance_size() + (index * kPointerSize);
+ __ mov(FieldOperand(receiver_reg, offset), value_reg);
if (!representation.IsSmi()) {
// Update the write barrier for the array address.
// Pass the value being stored in the now unused name_reg.
__ mov(name_reg, value_reg);
__ RecordWriteField(receiver_reg,
- index.offset(),
+ offset,
name_reg,
scratch1,
kDontSaveFPRegs,
}
} else {
// Write to the properties array.
+ int offset = index * kPointerSize + FixedArray::kHeaderSize;
// Get the properties array (optimistically).
__ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
- __ mov(FieldOperand(scratch1, index.offset()), value_reg);
+ __ mov(FieldOperand(scratch1, offset), value_reg);
if (!representation.IsSmi()) {
// Update the write barrier for the array address.
// Pass the value being stored in the now unused name_reg.
__ mov(name_reg, value_reg);
__ RecordWriteField(scratch1,
- index.offset(),
+ offset,
name_reg,
receiver_reg,
kDontSaveFPRegs,
void LoadStubCompiler::GenerateLoadField(Register reg,
Handle<JSObject> holder,
- FieldIndex field,
+ PropertyIndex field,
Representation representation) {
if (!reg.is(receiver())) __ mov(receiver(), reg);
if (kind() == Code::LOAD_IC) {
- LoadFieldStub stub(isolate(), field);
+ LoadFieldStub stub(isolate(),
+ field.is_inobject(holder),
+ field.translate(holder),
+ representation);
GenerateTailCall(masm(), stub.GetCode());
} else {
- KeyedLoadFieldStub stub(isolate(), field);
+ KeyedLoadFieldStub stub(isolate(),
+ field.is_inobject(holder),
+ field.translate(holder),
+ representation);
GenerateTailCall(masm(), stub.GetCode());
}
}
}
-Handle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) {
+Handle<Code> LoadIC::SimpleFieldLoad(int offset,
+ bool inobject,
+ Representation representation) {
if (kind() == Code::LOAD_IC) {
- LoadFieldStub stub(isolate(), index);
+ LoadFieldStub stub(isolate(), inobject, offset, representation);
return stub.GetCode();
} else {
- KeyedLoadFieldStub stub(isolate(), index);
+ KeyedLoadFieldStub stub(isolate(), inobject, offset, representation);
return stub.GetCode();
}
}
InlineCacheHolderFlag cache_holder) {
if (object->IsString() &&
String::Equals(isolate()->factory()->length_string(), name)) {
- FieldIndex index = FieldIndex::ForInObjectOffset(String::kLengthOffset);
- return SimpleFieldLoad(index);
+ int length_index = String::kLengthOffset / kPointerSize;
+ return SimpleFieldLoad(length_index);
}
if (object->IsStringWrapper() &&
switch (lookup->type()) {
case FIELD: {
- FieldIndex field = lookup->GetFieldIndex();
+ PropertyIndex field = lookup->GetFieldIndex();
if (object.is_identical_to(holder)) {
- return SimpleFieldLoad(field);
+ return SimpleFieldLoad(field.translate(holder),
+ field.is_inobject(holder),
+ lookup->representation());
}
return compiler.CompileLoadField(
type, holder, name, field, lookup->representation());
// Use simple field loads for some well-known callback properties.
if (object->IsJSObject()) {
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
- Handle<Map> map(receiver->map());
Handle<HeapType> type = IC::MapToType<HeapType>(
handle(receiver->map()), isolate());
int object_offset;
if (Accessors::IsJSObjectFieldAccessor<HeapType>(
type, name, &object_offset)) {
- FieldIndex index = FieldIndex::ForInObjectOffset(
- object_offset, receiver->map());
- return SimpleFieldLoad(index);
+ return SimpleFieldLoad(object_offset / kPointerSize);
}
}
return pre_monomorphic_stub(isolate(), extra_ic_state());
}
- Handle<Code> SimpleFieldLoad(FieldIndex index);
+ Handle<Code> SimpleFieldLoad(int offset,
+ bool inobject = true,
+ Representation representation =
+ Representation::Tagged());
static void Clear(Isolate* isolate,
Address address,
int length = properties.length();
for (int i = 0; i < length; i++) {
Handle<Object> value = properties[i];
- FieldIndex index = FieldIndex::ForPropertyIndex(*map, i);
- json_object->FastPropertyAtPut(index, *value);
+ json_object->FastPropertyAtPut(i, *value);
}
} else {
key = ParseJsonInternalizedString();
int length = properties.length();
for (int i = 0; i < length; i++) {
Handle<Object> value = properties[i];
- FieldIndex index = FieldIndex::ForPropertyIndex(*map, i);
- json_object->FastPropertyAtPut(index, *value);
+ json_object->FastPropertyAtPut(i, *value);
}
}
}
if (details.IsDontEnum()) continue;
Handle<Object> property;
if (details.type() == FIELD && *map == object->map()) {
- property = Handle<Object>(object->RawFastPropertyAt(
- FieldIndex::ForDescriptor(*map, i)), isolate_);
+ property = Handle<Object>(
+ object->RawFastPropertyAt(
+ map->instance_descriptors()->GetFieldIndex(i)),
+ isolate_);
} else {
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate_, property,
for (int i = 0; i < map()->NumberOfOwnDescriptors(); i++) {
if (descriptors->GetDetails(i).type() == FIELD) {
Representation r = descriptors->GetDetails(i).representation();
- FieldIndex index = FieldIndex::ForDescriptor(map(), i);
- Object* value = RawFastPropertyAt(index);
+ int field = descriptors->GetFieldIndex(i);
+ Object* value = RawFastPropertyAt(field);
if (r.IsDouble()) ASSERT(value->IsHeapNumber());
if (value->IsUninitialized()) continue;
if (r.IsSmi()) ASSERT(value->IsSmi());
#include "src/objects.h"
#include "src/contexts.h"
#include "src/conversions-inl.h"
-#include "src/field-index-inl.h"
#include "src/heap.h"
#include "src/isolate.h"
#include "src/heap-inl.h"
// 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.
-Object* JSObject::RawFastPropertyAt(FieldIndex index) {
- if (index.is_inobject()) {
- return READ_FIELD(this, index.offset());
+Object* JSObject::RawFastPropertyAt(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 {
- return properties()->get(index.outobject_array_index());
+ ASSERT(index < properties()->length());
+ return properties()->get(index);
}
}
-void JSObject::FastPropertyAtPut(FieldIndex index, Object* value) {
- if (index.is_inobject()) {
- int offset = index.offset();
+void 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(GetHeap(), this, offset, value);
} else {
- properties()->set(index.outobject_array_index(), value);
+ ASSERT(index < properties()->length());
+ properties()->set(index, value);
}
}
int Map::GetInObjectPropertyOffset(int index) {
// Adjust for the number of properties stored in the object.
index -= inobject_properties();
- ASSERT(index <= 0);
+ ASSERT(index < 0);
return instance_size() + (index * kPointerSize);
}
PrintF(out, ": ");
switch (descs->GetType(i)) {
case FIELD: {
- FieldIndex index = FieldIndex::ForDescriptor(map(), i);
+ int index = descs->GetFieldIndex(i);
RawFastPropertyAt(index)->ShortPrint(out);
- PrintF(out, " (field at offset %d)\n", index.property_index());
+ PrintF(out, " (field at offset %d)\n", index);
break;
}
case CONSTANT:
#include "src/date.h"
#include "src/elements.h"
#include "src/execution.h"
-#include "src/field-index.h"
-#include "src/field-index-inl.h"
#include "src/full-codegen.h"
#include "src/hydrogen.h"
#include "src/isolate-inl.h"
}
case FIELD:
value = JSObject::FastPropertyAt(handle(result->holder(), isolate),
- result->representation(), FieldIndex::ForLookupResult(result));
+ result->representation(),
+ result->GetFieldIndex().field_index());
break;
case CONSTANT:
return handle(result->GetConstant(), isolate);
old_details.type() == FIELD);
Object* raw_value = old_details.type() == CONSTANT
? old_descriptors->GetValue(i)
- : object->RawFastPropertyAt(FieldIndex::ForDescriptor(*old_map, i));
+ : object->RawFastPropertyAt(old_descriptors->GetFieldIndex(i));
Handle<Object> value(raw_value, isolate);
if (!old_details.representation().IsDouble() &&
details.representation().IsDouble()) {
// avoid overwriting |one_pointer_filler_map|.
int limit = Min(inobject, number_of_fields);
for (int i = 0; i < limit; i++) {
- FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i);
- object->FastPropertyAtPut(index, array->get(external + i));
+ object->FastPropertyAtPut(i, array->get(external + i));
}
// Create filler object past the new instance size.
// occur as fields.
if (result->IsField() &&
result->IsReadOnly() &&
- RawFastPropertyAt(result->GetFieldIndex())->IsTheHole()) {
+ RawFastPropertyAt(result->GetFieldIndex().field_index())->IsTheHole()) {
result->DisallowCaching();
}
return;
ASSERT(details.type() == FIELD);
- FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor);
+ int field_index = desc->GetFieldIndex(descriptor);
if (details.representation().IsDouble()) {
// Nothing more to be done.
if (value->IsUninitialized()) return;
- HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index));
+ HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(field_index));
box->set_value(value->Number());
} else {
- FastPropertyAtPut(index, value);
+ FastPropertyAtPut(field_index, value);
}
}
}
case FIELD: {
Handle<Name> key(descs->GetKey(i));
- FieldIndex index = FieldIndex::ForDescriptor(*map, i);
Handle<Object> value(
- object->RawFastPropertyAt(index), isolate);
+ object->RawFastPropertyAt(descs->GetFieldIndex(i)), isolate);
PropertyDetails d =
PropertyDetails(details.attributes(), NORMAL, i + 1);
dictionary = NameDictionary::Add(dictionary, key, value, d);
ASSERT(descriptors->GetType(sorted_index) == FIELD);
ASSERT(descriptors->GetDetails(sorted_index).representation().
IsCompatibleForLoad(Representation::Tagged()));
- FieldIndex index = FieldIndex::ForDescriptor(this->map(),
- sorted_index);
- return this->RawFastPropertyAt(index);
+ return this->RawFastPropertyAt(
+ descriptors->GetFieldIndex(sorted_index));
} else {
return GetHeap()->undefined_value();
}
Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object,
Representation representation,
- FieldIndex index) {
+ int index) {
Isolate* isolate = object->GetIsolate();
Handle<Object> raw_value(object->RawFastPropertyAt(index), isolate);
return Object::NewStorageFor(isolate, raw_value, representation);
for (int i = 0; i < limit; i++) {
PropertyDetails details = descriptors->GetDetails(i);
if (details.type() != FIELD) continue;
- FieldIndex index = FieldIndex::ForDescriptor(copy->map(), i);
+ int index = descriptors->GetFieldIndex(i);
Handle<Object> value(object->RawFastPropertyAt(index), isolate);
if (value->IsJSObject()) {
ASSIGN_RETURN_ON_EXCEPTION(
case FIELD:
result = FastPropertyAt(Handle<JSObject>(lookup.holder(), isolate),
lookup.representation(),
- lookup.GetFieldIndex());
+ lookup.GetFieldIndex().field_index());
break;
case CONSTANT:
result = Handle<Object>(lookup.GetConstant(), isolate);
if (details.type() != FIELD) {
indices = Handle<FixedArray>();
} else {
- FieldIndex field_index = FieldIndex::ForDescriptor(*map, i);
- int load_by_field_index = field_index.GetLoadByFieldIndex();
- indices->set(index, Smi::FromInt(load_by_field_index));
+ int field_index = descs->GetFieldIndex(i);
+ if (field_index >= map->inobject_properties()) {
+ field_index = -(field_index - map->inobject_properties() + 1);
+ }
+ field_index = field_index << 1;
+ if (details.representation().IsDouble()) {
+ field_index |= 1;
+ }
+ indices->set(index, Smi::FromInt(field_index));
}
}
index++;
DescriptorArray* descs = map()->instance_descriptors();
for (int i = 0; i < number_of_own_descriptors; i++) {
if (descs->GetType(i) == FIELD) {
- Object* property =
- RawFastPropertyAt(FieldIndex::ForDescriptor(map(), i));
+ Object* property = RawFastPropertyAt(descs->GetFieldIndex(i));
if (descs->GetDetails(i).representation().IsDouble()) {
ASSERT(property->IsHeapNumber());
if (value->IsNumber() && property->Number() == value->Number()) {
#include "src/assert-scope.h"
#include "src/builtins.h"
#include "src/elements-kind.h"
-#include "src/field-index.h"
#include "src/flags.h"
#include "src/list.h"
#include "src/property-details.h"
// Access fast-case object properties at index.
static Handle<Object> FastPropertyAt(Handle<JSObject> object,
Representation representation,
- FieldIndex index);
- inline Object* RawFastPropertyAt(FieldIndex index);
- inline void FastPropertyAtPut(FieldIndex index, Object* value);
+ int index);
+ inline Object* RawFastPropertyAt(int index);
+ inline void FastPropertyAtPut(int index, Object* value);
void WriteToField(int descriptor, Object* value);
// Access to in object properties.
break;
case FIELD:
PrintF(out, " -type = field\n");
- PrintF(out, " -index = %d\n",
- GetFieldIndex().property_index());
+ PrintF(out, " -index = %d\n", GetFieldIndex().field_index());
PrintF(out, " -field type:\n");
GetFieldType()->TypePrint(out);
break;
#include "src/isolate.h"
#include "src/factory.h"
-#include "src/field-index.h"
-#include "src/field-index-inl.h"
#include "src/types.h"
namespace v8 {
};
+// Holds a property index value distinguishing if it is a field index or an
+// index inside the object header.
+class PropertyIndex V8_FINAL {
+ 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();
+ }
+
+ bool is_inobject(Handle<JSObject> holder) {
+ if (is_header_index()) return true;
+ return field_index() < holder->map()->inobject_properties();
+ }
+
+ int translate(Handle<JSObject> holder) {
+ if (is_header_index()) return header_index();
+ int index = field_index() - holder->map()->inobject_properties();
+ if (index >= 0) return index;
+ return index + holder->map()->instance_size() / kPointerSize;
+ }
+
+ 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 V8_FINAL BASE_EMBEDDED {
public:
explicit LookupResult(Isolate* isolate)
case DICTIONARY_TYPE:
switch (type()) {
case FIELD:
- return holder()->RawFastPropertyAt(GetFieldIndex());
+ return holder()->RawFastPropertyAt(GetFieldIndex().field_index());
case NORMAL: {
Object* value = holder()->property_dictionary()->ValueAt(
GetDictionaryEntry());
return number_;
}
- FieldIndex GetFieldIndex() const {
+ PropertyIndex GetFieldIndex() const {
ASSERT(lookup_type_ == DESCRIPTOR_TYPE ||
lookup_type_ == TRANSITION_TYPE);
- return FieldIndex::ForLookupResult(this);
+ return PropertyIndex::NewFieldIndex(GetFieldIndexFromMap(holder()->map()));
}
int GetLocalFieldIndexFromMap(Map* map) const {
// Strict mode handling not needed (const is disallowed in strict mode).
if (lookup.IsField()) {
FixedArray* properties = global->properties();
- int index = lookup.GetFieldIndex().outobject_array_index();
+ int index = lookup.GetFieldIndex().field_index();
if (properties->get(index)->IsTheHole() || !lookup.IsReadOnly()) {
properties->set(index, *value);
}
if (lookup.IsField()) {
FixedArray* properties = object->properties();
- FieldIndex index = lookup.GetFieldIndex();
- ASSERT(!index.is_inobject());
- if (properties->get(index.outobject_array_index())->IsTheHole()) {
- properties->set(index.outobject_array_index(), *value);
+ int index = lookup.GetFieldIndex().field_index();
+ if (properties->get(index)->IsTheHole()) {
+ properties->set(index, *value);
}
} else if (lookup.IsNormal()) {
if (object->GetNormalizedProperty(&lookup)->IsTheHole()) {
// Attempt to use lookup cache.
Handle<Map> receiver_map(receiver->map(), isolate);
KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache();
- int index = keyed_lookup_cache->Lookup(receiver_map, key);
- if (index != -1) {
+ int offset = keyed_lookup_cache->Lookup(receiver_map, key);
+ if (offset != -1) {
// Doubles are not cached, so raw read the value.
- Object* value = receiver->RawFastPropertyAt(
- FieldIndex::ForKeyedLookupCacheIndex(*receiver_map, index));
+ Object* value = receiver->RawFastPropertyAt(offset);
return value->IsTheHole()
? isolate->heap()->undefined_value()
: value;
LookupResult result(isolate);
receiver->LookupOwn(key, &result);
if (result.IsField()) {
- FieldIndex field_index = result.GetFieldIndex();
+ int offset = result.GetFieldIndex().field_index();
// Do not track double fields in the keyed lookup cache. Reading
// double values requires boxing.
if (!result.representation().IsDouble()) {
- keyed_lookup_cache->Update(receiver_map, key,
- field_index.GetKeyedLookupCacheIndex());
+ keyed_lookup_cache->Update(receiver_map, key, offset);
}
AllowHeapAllocation allow_allocation;
- return *JSObject::FastPropertyAt(receiver, result.representation(),
- field_index);
+ return *JSObject::FastPropertyAt(
+ receiver, result.representation(), offset);
}
} else {
// Attempt dictionary lookup.
case FIELD:
value = JSObject::FastPropertyAt(handle(result->holder(), isolate),
result->representation(),
- result->GetFieldIndex());
+ result->GetFieldIndex().field_index());
break;
case CONSTANT:
return handle(result->GetConstant(), isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1);
- RUNTIME_ASSERT((index->value() & 1) == 1);
- FieldIndex field_index =
- FieldIndex::ForLoadByFieldIndex(object->map(), index->value() >> 1);
- if (field_index.is_inobject()) {
- RUNTIME_ASSERT(field_index.property_index() <
- object->map()->inobject_properties());
- } else {
- RUNTIME_ASSERT(field_index.outobject_array_index() <
- object->properties()->length());
- }
- Handle<Object> raw_value(object->RawFastPropertyAt(field_index), isolate);
+ int idx = index->value() >> 1;
+ int inobject_properties = object->map()->inobject_properties();
+ if (idx < 0) {
+ idx = -idx + inobject_properties - 1;
+ }
+ int max_idx = object->properties()->length() + inobject_properties;
+ RUNTIME_ASSERT(idx < max_idx);
+ Handle<Object> raw_value(object->RawFastPropertyAt(idx), isolate);
RUNTIME_ASSERT(raw_value->IsNumber() || raw_value->IsUninitialized());
return *Object::NewStorageFor(isolate, raw_value, Representation::Double());
}
key->ShortPrint();
}
Add(": ");
- FieldIndex index = FieldIndex::ForDescriptor(map, i);
- Object* value = js_object->RawFastPropertyAt(index);
+ Object* value = js_object->RawFastPropertyAt(descs->GetFieldIndex(i));
Add("%o\n", value);
}
}
Handle<HeapType> type,
Handle<JSObject> holder,
Handle<Name> name,
- FieldIndex field,
+ PropertyIndex field,
Representation representation) {
Register reg = HandlerFrontend(type, receiver(), holder, name);
GenerateLoadField(reg, holder, field, representation);
LookupResult* lookup) {
Handle<JSObject> holder(lookup->holder());
if (lookup->IsField()) {
- FieldIndex field = lookup->GetFieldIndex();
+ PropertyIndex field = lookup->GetFieldIndex();
if (interceptor_holder.is_identical_to(holder)) {
GenerateLoadField(
interceptor_reg, holder, field, lookup->representation());
Handle<Code> CompileLoadField(Handle<HeapType> type,
Handle<JSObject> holder,
Handle<Name> name,
- FieldIndex index,
+ PropertyIndex index,
Representation representation);
Handle<Code> CompileLoadCallback(Handle<HeapType> type,
void GenerateLoadField(Register reg,
Handle<JSObject> holder,
- FieldIndex field,
+ PropertyIndex field,
Representation representation);
void GenerateLoadConstant(Handle<Object> value);
void GenerateLoadCallback(Register reg,
static const U kMask = ((kOne << shift) << size) - (kOne << shift);
static const U kShift = shift;
static const U kSize = size;
- static const U kNext = kShift + kSize;
// Value for the field with all bits set.
static const T kMax = static_cast<T>((1U << size) - 1);
// checks.
ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
- FieldIndex index = lookup->GetFieldIndex();
+ int index = lookup->GetFieldIndex().field_index();
+
+ // Adjust for the number of properties stored in the object. Even in the
+ // face of a transition we can use the old map here because the size of the
+ // object and the number of in-object properties is not going to change.
+ index -= object->map()->inobject_properties();
Representation representation = lookup->representation();
ASSERT(!representation.IsNone());
}
} else if (representation.IsDouble()) {
// Load the double storage.
- if (index.is_inobject()) {
- __ movp(scratch1, FieldOperand(receiver_reg, index.offset()));
+ if (index < 0) {
+ int offset = object->map()->instance_size() + (index * kPointerSize);
+ __ movp(scratch1, FieldOperand(receiver_reg, offset));
} else {
__ movp(scratch1,
FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
- __ movp(scratch1, FieldOperand(scratch1, index.offset()));
+ int offset = index * kPointerSize + FixedArray::kHeaderSize;
+ __ movp(scratch1, FieldOperand(scratch1, offset));
}
// Store the value into the storage.
// TODO(verwaest): Share this code as a code stub.
SmiCheck smi_check = representation.IsTagged()
? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
- if (index.is_inobject()) {
+ if (index < 0) {
// Set the property straight into the object.
- __ movp(FieldOperand(receiver_reg, index.offset()), value_reg);
+ int offset = object->map()->instance_size() + (index * kPointerSize);
+ __ movp(FieldOperand(receiver_reg, offset), value_reg);
if (!representation.IsSmi()) {
// Update the write barrier for the array address.
// Pass the value being stored in the now unused name_reg.
__ movp(name_reg, value_reg);
__ RecordWriteField(
- receiver_reg, index.offset(), name_reg, scratch1, kDontSaveFPRegs,
+ receiver_reg, offset, name_reg, scratch1, kDontSaveFPRegs,
EMIT_REMEMBERED_SET, smi_check);
}
} else {
// Write to the properties array.
+ int offset = index * kPointerSize + FixedArray::kHeaderSize;
// Get the properties array (optimistically).
__ movp(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
- __ movp(FieldOperand(scratch1, index.offset()), value_reg);
+ __ movp(FieldOperand(scratch1, offset), value_reg);
if (!representation.IsSmi()) {
// Update the write barrier for the array address.
// Pass the value being stored in the now unused name_reg.
__ movp(name_reg, value_reg);
__ RecordWriteField(
- scratch1, index.offset(), name_reg, receiver_reg, kDontSaveFPRegs,
+ scratch1, offset, name_reg, receiver_reg, kDontSaveFPRegs,
EMIT_REMEMBERED_SET, smi_check);
}
}
void LoadStubCompiler::GenerateLoadField(Register reg,
Handle<JSObject> holder,
- FieldIndex field,
+ PropertyIndex field,
Representation representation) {
if (!reg.is(receiver())) __ movp(receiver(), reg);
if (kind() == Code::LOAD_IC) {
- LoadFieldStub stub(isolate(), field);
+ LoadFieldStub stub(isolate(),
+ field.is_inobject(holder),
+ field.translate(holder),
+ representation);
GenerateTailCall(masm(), stub.GetCode());
} else {
- KeyedLoadFieldStub stub(isolate(), field);
+ KeyedLoadFieldStub stub(isolate(),
+ field.is_inobject(holder),
+ field.translate(holder),
+ representation);
GenerateTailCall(masm(), stub.GetCode());
}
}
CHECK_EQ(0, FixedArray::cast(jsobject->elements())->length());
CHECK_EQ(0, jsobject->properties()->length());
// Create a reference to object in new space in jsobject.
- FieldIndex index = FieldIndex::ForInObjectOffset(
- JSObject::kHeaderSize - kPointerSize);
- jsobject->FastPropertyAtPut(index, array);
+ jsobject->FastPropertyAtPut(-1, array);
CHECK_EQ(0, static_cast<int>(*limit_addr - *top_addr));
v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res));
CHECK(CcTest::heap()->InOldPointerSpace(*o));
- FieldIndex idx1 = FieldIndex::ForPropertyIndex(o->map(), 0);
- FieldIndex idx2 = FieldIndex::ForPropertyIndex(o->map(), 1);
- CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(idx1)));
- CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(idx2)));
+ CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(0)));
+ CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(1)));
- JSObject* inner_object =
- reinterpret_cast<JSObject*>(o->RawFastPropertyAt(idx1));
+ JSObject* inner_object = reinterpret_cast<JSObject*>(o->RawFastPropertyAt(0));
CHECK(CcTest::heap()->InOldPointerSpace(inner_object));
- CHECK(CcTest::heap()->InOldDataSpace(inner_object->RawFastPropertyAt(idx1)));
- CHECK(CcTest::heap()->InOldPointerSpace(
- inner_object->RawFastPropertyAt(idx2)));
+ CHECK(CcTest::heap()->InOldDataSpace(inner_object->RawFastPropertyAt(0)));
+ CHECK(CcTest::heap()->InOldPointerSpace(inner_object->RawFastPropertyAt(1)));
}
CHECK(value->Equals(obj->GetHiddenValue(v8_str("key string"))));
// Check size.
- FieldIndex index = FieldIndex::ForDescriptor(internal_obj->map(), 0);
+ DescriptorArray* descriptors = internal_obj->map()->instance_descriptors();
ObjectHashTable* hashtable = ObjectHashTable::cast(
- internal_obj->RawFastPropertyAt(index));
+ internal_obj->RawFastPropertyAt(descriptors->GetFieldIndex(0)));
// HashTable header (5) and 4 initial entries (8).
CHECK_LE(hashtable->SizeFor(hashtable->length()), 13 * kPointerSize);
}
'../../src/fast-dtoa.cc',
'../../src/fast-dtoa.h',
'../../src/feedback-slots.h',
- '../../src/field-index.cc',
- '../../src/field-index.h',
- '../../src/field-index-inl.h',
'../../src/fixed-dtoa.cc',
'../../src/fixed-dtoa.h',
'../../src/flag-definitions.h',