Commit 05270212 authored by ishell@chromium.org's avatar ishell@chromium.org

Remake of the load elimination fix made earlier (r18884).

R=titzer@chromium.org, verwaest@chromium.org

Review URL: https://codereview.chromium.org/149063010

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19057 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 8d1504b2
This diff is collapsed.
...@@ -3618,8 +3618,7 @@ void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) { ...@@ -3618,8 +3618,7 @@ void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) {
filler_map->FinalizeUniqueness(); // TODO(titzer): should be init'd a'ready filler_map->FinalizeUniqueness(); // TODO(titzer): should be init'd a'ready
filler_map->InsertAfter(free_space_instr); filler_map->InsertAfter(free_space_instr);
HInstruction* store_map = HStoreNamedField::New(zone, context(), HInstruction* store_map = HStoreNamedField::New(zone, context(),
free_space_instr, HObjectAccess::ForMap(), filler_map, free_space_instr, HObjectAccess::ForMap(), filler_map);
INITIALIZING_STORE);
store_map->SetFlag(HValue::kHasNoObservableSideEffects); store_map->SetFlag(HValue::kHasNoObservableSideEffects);
store_map->InsertAfter(filler_map); store_map->InsertAfter(filler_map);
...@@ -3630,10 +3629,11 @@ void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) { ...@@ -3630,10 +3629,11 @@ void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) {
zone, context(), free_space_size, Representation::Smi(), store_map); zone, context(), free_space_size, Representation::Smi(), store_map);
// Must force Smi representation for x64 (see comment above). // Must force Smi representation for x64 (see comment above).
HObjectAccess access = HObjectAccess access =
HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset, HObjectAccess::ForMapAndOffset(isolate()->factory()->free_space_map(),
Representation::Smi()); FreeSpace::kSizeOffset,
Representation::Smi());
HStoreNamedField* store_size = HStoreNamedField::New(zone, context(), HStoreNamedField* store_size = HStoreNamedField::New(zone, context(),
free_space_instr, access, filler_size, INITIALIZING_STORE); free_space_instr, access, filler_size);
store_size->SetFlag(HValue::kHasNoObservableSideEffects); store_size->SetFlag(HValue::kHasNoObservableSideEffects);
store_size->InsertAfter(filler_size); store_size->InsertAfter(filler_size);
filler_free_space_size_ = store_size; filler_free_space_size_ = store_size;
...@@ -3643,10 +3643,11 @@ void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) { ...@@ -3643,10 +3643,11 @@ void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) {
void HAllocate::ClearNextMapWord(int offset) { void HAllocate::ClearNextMapWord(int offset) {
if (MustClearNextMapWord()) { if (MustClearNextMapWord()) {
Zone* zone = block()->zone(); Zone* zone = block()->zone();
HObjectAccess access = HObjectAccess::ForJSObjectOffset(offset); HObjectAccess access =
HObjectAccess::ForObservableJSObjectOffset(offset);
HStoreNamedField* clear_next_map = HStoreNamedField* clear_next_map =
HStoreNamedField::New(zone, context(), this, access, HStoreNamedField::New(zone, context(), this, access,
block()->graph()->GetConstant0(), INITIALIZING_STORE); block()->graph()->GetConstant0());
clear_next_map->ClearAllSideEffects(); clear_next_map->ClearAllSideEffects();
clear_next_map->InsertAfter(this); clear_next_map->InsertAfter(this);
} }
...@@ -4270,7 +4271,7 @@ HObjectAccess HObjectAccess::ForFixedArrayHeader(int offset) { ...@@ -4270,7 +4271,7 @@ HObjectAccess HObjectAccess::ForFixedArrayHeader(int offset) {
} }
HObjectAccess HObjectAccess::ForJSObjectOffset(int offset, HObjectAccess HObjectAccess::ForMapAndOffset(Handle<Map> map, int offset,
Representation representation) { Representation representation) {
ASSERT(offset >= 0); ASSERT(offset >= 0);
Portion portion = kInobject; Portion portion = kInobject;
...@@ -4280,7 +4281,13 @@ HObjectAccess HObjectAccess::ForJSObjectOffset(int offset, ...@@ -4280,7 +4281,13 @@ HObjectAccess HObjectAccess::ForJSObjectOffset(int offset,
} else if (offset == JSObject::kMapOffset) { } else if (offset == JSObject::kMapOffset) {
portion = kMaps; portion = kMaps;
} }
return HObjectAccess(portion, offset, representation); bool existing_inobject_property = true;
if (!map.is_null()) {
existing_inobject_property = (offset <
map->instance_size() - map->unused_property_fields() * kPointerSize);
}
return HObjectAccess(portion, offset, representation, Handle<String>::null(),
false, existing_inobject_property);
} }
...@@ -4332,7 +4339,8 @@ HObjectAccess HObjectAccess::ForJSArrayOffset(int offset) { ...@@ -4332,7 +4339,8 @@ HObjectAccess HObjectAccess::ForJSArrayOffset(int offset) {
HObjectAccess HObjectAccess::ForBackingStoreOffset(int offset, HObjectAccess HObjectAccess::ForBackingStoreOffset(int offset,
Representation representation) { Representation representation) {
ASSERT(offset >= 0); ASSERT(offset >= 0);
return HObjectAccess(kBackingStore, offset, representation); return HObjectAccess(kBackingStore, offset, representation,
Handle<String>::null(), false, false);
} }
...@@ -4357,11 +4365,12 @@ HObjectAccess HObjectAccess::ForField(Handle<Map> map, ...@@ -4357,11 +4365,12 @@ HObjectAccess HObjectAccess::ForField(Handle<Map> map,
// Negative property indices are in-object properties, indexed // Negative property indices are in-object properties, indexed
// from the end of the fixed part of the object. // from the end of the fixed part of the object.
int offset = (index * kPointerSize) + map->instance_size(); int offset = (index * kPointerSize) + map->instance_size();
return HObjectAccess(kInobject, offset, representation, name); return HObjectAccess(kInobject, offset, representation, name, false, true);
} else { } else {
// Non-negative property indices are in the properties array. // Non-negative property indices are in the properties array.
int offset = (index * kPointerSize) + FixedArray::kHeaderSize; int offset = (index * kPointerSize) + FixedArray::kHeaderSize;
return HObjectAccess(kBackingStore, offset, representation, name); return HObjectAccess(kBackingStore, offset, representation, name,
false, false);
} }
} }
......
...@@ -5710,8 +5710,15 @@ class HObjectAccess V8_FINAL { ...@@ -5710,8 +5710,15 @@ class HObjectAccess V8_FINAL {
return ImmutableField::decode(value_); return ImmutableField::decode(value_);
} }
// Returns true if access is being made to an in-object property that
// was already added to the object.
inline bool existing_inobject_property() const {
return ExistingInobjectPropertyField::decode(value_);
}
inline HObjectAccess WithRepresentation(Representation representation) { inline HObjectAccess WithRepresentation(Representation representation) {
return HObjectAccess(portion(), offset(), representation, name()); return HObjectAccess(portion(), offset(), representation, name(),
immutable(), existing_inobject_property());
} }
static HObjectAccess ForHeapNumberValue() { static HObjectAccess ForHeapNumberValue() {
...@@ -5755,7 +5762,8 @@ class HObjectAccess V8_FINAL { ...@@ -5755,7 +5762,8 @@ class HObjectAccess V8_FINAL {
static HObjectAccess ForAllocationSiteOffset(int offset); static HObjectAccess ForAllocationSiteOffset(int offset);
static HObjectAccess ForAllocationSiteList() { static HObjectAccess ForAllocationSiteList() {
return HObjectAccess(kExternalMemory, 0, Representation::Tagged()); return HObjectAccess(kExternalMemory, 0, Representation::Tagged(),
Handle<String>::null(), false, false);
} }
static HObjectAccess ForFixedArrayLength() { static HObjectAccess ForFixedArrayLength() {
...@@ -5857,16 +5865,29 @@ class HObjectAccess V8_FINAL { ...@@ -5857,16 +5865,29 @@ class HObjectAccess V8_FINAL {
} }
static HObjectAccess ForCounter() { static HObjectAccess ForCounter() {
return HObjectAccess(kExternalMemory, 0, Representation::Integer32()); return HObjectAccess(kExternalMemory, 0, Representation::Integer32(),
Handle<String>::null(), false, false);
} }
// Create an access to an offset in a fixed array header. // Create an access to an offset in a fixed array header.
static HObjectAccess ForFixedArrayHeader(int offset); static HObjectAccess ForFixedArrayHeader(int offset);
// Create an access to an in-object property in a JSObject. // Create an access to an in-object property in a JSObject.
static HObjectAccess ForJSObjectOffset(int offset, // This kind of access must be used when the object |map| is known and
// in-object properties are being accessed. Accesses of the in-object
// properties can have different semantics depending on whether corresponding
// property was added to the map or not.
static HObjectAccess ForMapAndOffset(Handle<Map> map, int offset,
Representation representation = Representation::Tagged()); Representation representation = Representation::Tagged());
// Create an access to an in-object property in a JSObject.
// This kind of access can be used for accessing object header fields or
// in-object properties if the map of the object is not known.
static HObjectAccess ForObservableJSObjectOffset(int offset,
Representation representation = Representation::Tagged()) {
return ForMapAndOffset(Handle<Map>::null(), offset, representation);
}
// Create an access to an in-object property in a JSArray. // Create an access to an in-object property in a JSArray.
static HObjectAccess ForJSArrayOffset(int offset); static HObjectAccess ForJSArrayOffset(int offset);
...@@ -5884,39 +5905,42 @@ class HObjectAccess V8_FINAL { ...@@ -5884,39 +5905,42 @@ class HObjectAccess V8_FINAL {
static HObjectAccess ForCellPayload(Isolate* isolate); static HObjectAccess ForCellPayload(Isolate* isolate);
static HObjectAccess ForJSTypedArrayLength() { static HObjectAccess ForJSTypedArrayLength() {
return HObjectAccess::ForJSObjectOffset(JSTypedArray::kLengthOffset); return HObjectAccess::ForObservableJSObjectOffset(
JSTypedArray::kLengthOffset);
} }
static HObjectAccess ForJSArrayBufferBackingStore() { static HObjectAccess ForJSArrayBufferBackingStore() {
return HObjectAccess::ForJSObjectOffset( return HObjectAccess::ForObservableJSObjectOffset(
JSArrayBuffer::kBackingStoreOffset, Representation::External()); JSArrayBuffer::kBackingStoreOffset, Representation::External());
} }
static HObjectAccess ForExternalArrayExternalPointer() { static HObjectAccess ForExternalArrayExternalPointer() {
return HObjectAccess::ForJSObjectOffset( return HObjectAccess::ForObservableJSObjectOffset(
ExternalArray::kExternalPointerOffset, Representation::External()); ExternalArray::kExternalPointerOffset, Representation::External());
} }
static HObjectAccess ForJSArrayBufferViewWeakNext() { static HObjectAccess ForJSArrayBufferViewWeakNext() {
return HObjectAccess::ForJSObjectOffset(JSArrayBufferView::kWeakNextOffset); return HObjectAccess::ForObservableJSObjectOffset(
JSArrayBufferView::kWeakNextOffset);
} }
static HObjectAccess ForJSArrayBufferWeakFirstView() { static HObjectAccess ForJSArrayBufferWeakFirstView() {
return HObjectAccess::ForJSObjectOffset( return HObjectAccess::ForObservableJSObjectOffset(
JSArrayBuffer::kWeakFirstViewOffset); JSArrayBuffer::kWeakFirstViewOffset);
} }
static HObjectAccess ForJSArrayBufferViewBuffer() { static HObjectAccess ForJSArrayBufferViewBuffer() {
return HObjectAccess::ForJSObjectOffset(JSArrayBufferView::kBufferOffset); return HObjectAccess::ForObservableJSObjectOffset(
JSArrayBufferView::kBufferOffset);
} }
static HObjectAccess ForJSArrayBufferViewByteOffset() { static HObjectAccess ForJSArrayBufferViewByteOffset() {
return HObjectAccess::ForJSObjectOffset( return HObjectAccess::ForObservableJSObjectOffset(
JSArrayBufferView::kByteOffsetOffset); JSArrayBufferView::kByteOffsetOffset);
} }
static HObjectAccess ForJSArrayBufferViewByteLength() { static HObjectAccess ForJSArrayBufferViewByteLength() {
return HObjectAccess::ForJSObjectOffset( return HObjectAccess::ForObservableJSObjectOffset(
JSArrayBufferView::kByteLengthOffset); JSArrayBufferView::kByteLengthOffset);
} }
...@@ -5949,23 +5973,29 @@ class HObjectAccess V8_FINAL { ...@@ -5949,23 +5973,29 @@ class HObjectAccess V8_FINAL {
HObjectAccess(Portion portion, int offset, HObjectAccess(Portion portion, int offset,
Representation representation = Representation::Tagged(), Representation representation = Representation::Tagged(),
Handle<String> name = Handle<String>::null(), Handle<String> name = Handle<String>::null(),
bool immutable = false) bool immutable = false,
bool existing_inobject_property = true)
: value_(PortionField::encode(portion) | : value_(PortionField::encode(portion) |
RepresentationField::encode(representation.kind()) | RepresentationField::encode(representation.kind()) |
ImmutableField::encode(immutable ? 1 : 0) | ImmutableField::encode(immutable ? 1 : 0) |
ExistingInobjectPropertyField::encode(
existing_inobject_property ? 1 : 0) |
OffsetField::encode(offset)), OffsetField::encode(offset)),
name_(name) { name_(name) {
// assert that the fields decode correctly // assert that the fields decode correctly
ASSERT(this->offset() == offset); ASSERT(this->offset() == offset);
ASSERT(this->portion() == portion); ASSERT(this->portion() == portion);
ASSERT(this->immutable() == immutable); ASSERT(this->immutable() == immutable);
ASSERT(this->existing_inobject_property() == existing_inobject_property);
ASSERT(RepresentationField::decode(value_) == representation.kind()); ASSERT(RepresentationField::decode(value_) == representation.kind());
ASSERT(!this->existing_inobject_property() || IsInobject());
} }
class PortionField : public BitField<Portion, 0, 3> {}; class PortionField : public BitField<Portion, 0, 3> {};
class RepresentationField : public BitField<Representation::Kind, 3, 4> {}; class RepresentationField : public BitField<Representation::Kind, 3, 4> {};
class ImmutableField : public BitField<bool, 7, 1> {}; class ImmutableField : public BitField<bool, 7, 1> {};
class OffsetField : public BitField<int, 8, 24> {}; class ExistingInobjectPropertyField : public BitField<bool, 8, 1> {};
class OffsetField : public BitField<int, 9, 23> {};
uint32_t value_; // encodes portion, representation, immutable, and offset uint32_t value_; // encodes portion, representation, immutable, and offset
Handle<String> name_; Handle<String> name_;
...@@ -6351,9 +6381,6 @@ class HLoadKeyedGeneric V8_FINAL : public HTemplateInstruction<3> { ...@@ -6351,9 +6381,6 @@ class HLoadKeyedGeneric V8_FINAL : public HTemplateInstruction<3> {
// Indicates whether the store is a store to an entry that was previously // Indicates whether the store is a store to an entry that was previously
// initialized or not. // initialized or not.
enum StoreFieldOrKeyedMode { enum StoreFieldOrKeyedMode {
// This is a store of either an undefined value to a field or a hole/NaN to
// an entry of a newly allocated object.
PREINITIALIZING_STORE,
// The entry could be either previously initialized or not. // The entry could be either previously initialized or not.
INITIALIZING_STORE, INITIALIZING_STORE,
// At the time of this store it is guaranteed that the entry is already // At the time of this store it is guaranteed that the entry is already
...@@ -6364,6 +6391,8 @@ enum StoreFieldOrKeyedMode { ...@@ -6364,6 +6391,8 @@ enum StoreFieldOrKeyedMode {
class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> { class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> {
public: public:
DECLARE_INSTRUCTION_FACTORY_P3(HStoreNamedField, HValue*,
HObjectAccess, HValue*);
DECLARE_INSTRUCTION_FACTORY_P4(HStoreNamedField, HValue*, DECLARE_INSTRUCTION_FACTORY_P4(HStoreNamedField, HValue*,
HObjectAccess, HValue*, StoreFieldOrKeyedMode); HObjectAccess, HValue*, StoreFieldOrKeyedMode);
...@@ -6470,16 +6499,15 @@ class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> { ...@@ -6470,16 +6499,15 @@ class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> {
HStoreNamedField(HValue* obj, HStoreNamedField(HValue* obj,
HObjectAccess access, HObjectAccess access,
HValue* val, HValue* val,
StoreFieldOrKeyedMode store_mode) StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE)
: access_(access), : access_(access),
new_space_dominator_(NULL), new_space_dominator_(NULL),
write_barrier_mode_(UPDATE_WRITE_BARRIER), write_barrier_mode_(UPDATE_WRITE_BARRIER),
has_transition_(false), has_transition_(false),
store_mode_(store_mode) { store_mode_(store_mode) {
// PREINITIALIZING_STORE is only used to mark stores that initialize a // Stores to a non existing in-object property are allowed only to the
// memory region resulting from HAllocate (possibly through an // newly allocated objects (via HAllocate or HInnerAllocatedObject).
// HInnerAllocatedObject). ASSERT(!access.IsInobject() || access.existing_inobject_property() ||
ASSERT(store_mode != PREINITIALIZING_STORE ||
obj->IsAllocate() || obj->IsInnerAllocatedObject()); obj->IsAllocate() || obj->IsInnerAllocatedObject());
SetOperandAt(0, obj); SetOperandAt(0, obj);
SetOperandAt(1, val); SetOperandAt(1, val);
...@@ -6491,7 +6519,7 @@ class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> { ...@@ -6491,7 +6519,7 @@ class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> {
HValue* new_space_dominator_; HValue* new_space_dominator_;
WriteBarrierMode write_barrier_mode_ : 1; WriteBarrierMode write_barrier_mode_ : 1;
bool has_transition_ : 1; bool has_transition_ : 1;
StoreFieldOrKeyedMode store_mode_ : 2; StoreFieldOrKeyedMode store_mode_ : 1;
}; };
...@@ -6536,6 +6564,8 @@ class HStoreNamedGeneric V8_FINAL : public HTemplateInstruction<3> { ...@@ -6536,6 +6564,8 @@ class HStoreNamedGeneric V8_FINAL : public HTemplateInstruction<3> {
class HStoreKeyed V8_FINAL class HStoreKeyed V8_FINAL
: public HTemplateInstruction<3>, public ArrayInstructionInterface { : public HTemplateInstruction<3>, public ArrayInstructionInterface {
public: public:
DECLARE_INSTRUCTION_FACTORY_P4(HStoreKeyed, HValue*, HValue*, HValue*,
ElementsKind);
DECLARE_INSTRUCTION_FACTORY_P5(HStoreKeyed, HValue*, HValue*, HValue*, DECLARE_INSTRUCTION_FACTORY_P5(HStoreKeyed, HValue*, HValue*, HValue*,
ElementsKind, StoreFieldOrKeyedMode); ElementsKind, StoreFieldOrKeyedMode);
...@@ -6655,7 +6685,7 @@ class HStoreKeyed V8_FINAL ...@@ -6655,7 +6685,7 @@ class HStoreKeyed V8_FINAL
private: private:
HStoreKeyed(HValue* obj, HValue* key, HValue* val, HStoreKeyed(HValue* obj, HValue* key, HValue* val,
ElementsKind elements_kind, ElementsKind elements_kind,
StoreFieldOrKeyedMode store_mode) StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE)
: elements_kind_(elements_kind), : elements_kind_(elements_kind),
index_offset_(0), index_offset_(0),
is_dehoisted_(false), is_dehoisted_(false),
...@@ -6666,12 +6696,6 @@ class HStoreKeyed V8_FINAL ...@@ -6666,12 +6696,6 @@ class HStoreKeyed V8_FINAL
SetOperandAt(1, key); SetOperandAt(1, key);
SetOperandAt(2, val); SetOperandAt(2, val);
// PREINITIALIZING_STORE is only used to mark stores that initialize a
// memory region resulting from HAllocate (possibly through an
// HInnerAllocatedObject).
ASSERT(store_mode != PREINITIALIZING_STORE ||
obj->IsAllocate() || obj->IsInnerAllocatedObject());
ASSERT(store_mode != STORE_TO_INITIALIZED_ENTRY || ASSERT(store_mode != STORE_TO_INITIALIZED_ENTRY ||
elements_kind == FAST_SMI_ELEMENTS); elements_kind == FAST_SMI_ELEMENTS);
...@@ -6706,7 +6730,7 @@ class HStoreKeyed V8_FINAL ...@@ -6706,7 +6730,7 @@ class HStoreKeyed V8_FINAL
uint32_t index_offset_; uint32_t index_offset_;
bool is_dehoisted_ : 1; bool is_dehoisted_ : 1;
bool is_uninitialized_ : 1; bool is_uninitialized_ : 1;
StoreFieldOrKeyedMode store_mode_: 2; StoreFieldOrKeyedMode store_mode_: 1;
HValue* new_space_dominator_; HValue* new_space_dominator_;
}; };
......
...@@ -193,6 +193,10 @@ class HLoadEliminationTable : public ZoneObject { ...@@ -193,6 +193,10 @@ class HLoadEliminationTable : public ZoneObject {
// load or store for this object and field exists, return the new value with // load or store for this object and field exists, return the new value with
// which the load should be replaced. Otherwise, return {instr}. // which the load should be replaced. Otherwise, return {instr}.
HValue* load(HLoadNamedField* instr) { HValue* load(HLoadNamedField* instr) {
// There must be no loads from non observable in-object properties.
ASSERT(!instr->access().IsInobject() ||
instr->access().existing_inobject_property());
int field = FieldOf(instr->access()); int field = FieldOf(instr->access());
if (field < 0) return instr; if (field < 0) return instr;
...@@ -217,8 +221,9 @@ class HLoadEliminationTable : public ZoneObject { ...@@ -217,8 +221,9 @@ class HLoadEliminationTable : public ZoneObject {
// the stored values are the same), return NULL indicating that this store // the stored values are the same), return NULL indicating that this store
// instruction is redundant. Otherwise, return {instr}. // instruction is redundant. Otherwise, return {instr}.
HValue* store(HStoreNamedField* instr) { HValue* store(HStoreNamedField* instr) {
if (instr->store_mode() == PREINITIALIZING_STORE) { if (instr->access().IsInobject() &&
TRACE((" skipping preinitializing store\n")); !instr->access().existing_inobject_property()) {
TRACE((" skipping non existing property initialization store\n"));
return instr; return instr;
} }
......
This diff is collapsed.
...@@ -1370,7 +1370,7 @@ class HGraphBuilder { ...@@ -1370,7 +1370,7 @@ class HGraphBuilder {
HInstruction* AddLoadStringLength(HValue* string); HInstruction* AddLoadStringLength(HValue* string);
HStoreNamedField* AddStoreMapNoWriteBarrier(HValue* object, HValue* map) { HStoreNamedField* AddStoreMapNoWriteBarrier(HValue* object, HValue* map) {
HStoreNamedField* store_map = Add<HStoreNamedField>( HStoreNamedField* store_map = Add<HStoreNamedField>(
object, HObjectAccess::ForMap(), map, INITIALIZING_STORE); object, HObjectAccess::ForMap(), map);
store_map->SkipWriteBarrier(); store_map->SkipWriteBarrier();
return store_map; return store_map;
} }
...@@ -2322,7 +2322,7 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { ...@@ -2322,7 +2322,7 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
ASSERT(name_->Equals(isolate()->heap()->length_string())); ASSERT(name_->Equals(isolate()->heap()->length_string()));
*access = HObjectAccess::ForStringLength(); *access = HObjectAccess::ForStringLength();
} else { } else {
*access = HObjectAccess::ForJSObjectOffset(offset); *access = HObjectAccess::ForMapAndOffset(map(), offset);
} }
return true; return true;
} }
......
...@@ -1968,18 +1968,12 @@ void JSObject::FastPropertyAtPut(int index, Object* value) { ...@@ -1968,18 +1968,12 @@ void JSObject::FastPropertyAtPut(int index, Object* value) {
int JSObject::GetInObjectPropertyOffset(int index) { int JSObject::GetInObjectPropertyOffset(int index) {
// Adjust for the number of properties stored in the object. return map()->GetInObjectPropertyOffset(index);
index -= map()->inobject_properties();
ASSERT(index < 0);
return map()->instance_size() + (index * kPointerSize);
} }
Object* JSObject::InObjectPropertyAt(int index) { Object* JSObject::InObjectPropertyAt(int index) {
// Adjust for the number of properties stored in the object. int offset = GetInObjectPropertyOffset(index);
index -= map()->inobject_properties();
ASSERT(index < 0);
int offset = map()->instance_size() + (index * kPointerSize);
return READ_FIELD(this, offset); return READ_FIELD(this, offset);
} }
...@@ -1988,9 +1982,7 @@ Object* JSObject::InObjectPropertyAtPut(int index, ...@@ -1988,9 +1982,7 @@ Object* JSObject::InObjectPropertyAtPut(int index,
Object* value, Object* value,
WriteBarrierMode mode) { WriteBarrierMode mode) {
// Adjust for the number of properties stored in the object. // Adjust for the number of properties stored in the object.
index -= map()->inobject_properties(); int offset = GetInObjectPropertyOffset(index);
ASSERT(index < 0);
int offset = map()->instance_size() + (index * kPointerSize);
WRITE_FIELD(this, offset, value); WRITE_FIELD(this, offset, value);
CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
return value; return value;
...@@ -3808,6 +3800,14 @@ int Map::pre_allocated_property_fields() { ...@@ -3808,6 +3800,14 @@ int Map::pre_allocated_property_fields() {
} }
int Map::GetInObjectPropertyOffset(int index) {
// Adjust for the number of properties stored in the object.
index -= inobject_properties();
ASSERT(index < 0);
return instance_size() + (index * kPointerSize);
}
int HeapObject::SizeFromMap(Map* map) { int HeapObject::SizeFromMap(Map* map) {
int instance_size = map->instance_size(); int instance_size = map->instance_size();
if (instance_size != kVariableSizeSentinel) return instance_size; if (instance_size != kVariableSizeSentinel) return instance_size;
......
...@@ -5981,6 +5981,8 @@ class Map: public HeapObject { ...@@ -5981,6 +5981,8 @@ class Map: public HeapObject {
Map* FindUpdatedMap(int verbatim, int length, DescriptorArray* descriptors); Map* FindUpdatedMap(int verbatim, int length, DescriptorArray* descriptors);
Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors); Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors);
inline int GetInObjectPropertyOffset(int index);
int NumberOfFields(); int NumberOfFields();
bool InstancesNeedRewriting(Map* target, bool InstancesNeedRewriting(Map* target,
......
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