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

Load elimination fix with a test case.

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

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18884 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent a09a5a86
...@@ -446,7 +446,8 @@ HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() { ...@@ -446,7 +446,8 @@ HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() {
for (int i = 0; i < object_size; i += kPointerSize) { for (int i = 0; i < object_size; i += kPointerSize) {
HObjectAccess access = HObjectAccess::ForJSObjectOffset(i); HObjectAccess access = HObjectAccess::ForJSObjectOffset(i);
Add<HStoreNamedField>(object, access, Add<HStoreNamedField>(object, access,
Add<HLoadNamedField>(boilerplate, access)); Add<HLoadNamedField>(boilerplate, access),
INITIALIZING_STORE);
} }
ASSERT(FLAG_allocation_site_pretenuring || (size == object_size)); ASSERT(FLAG_allocation_site_pretenuring || (size == object_size));
...@@ -483,25 +484,29 @@ HValue* CodeStubGraphBuilder<CreateAllocationSiteStub>::BuildCodeStub() { ...@@ -483,25 +484,29 @@ HValue* CodeStubGraphBuilder<CreateAllocationSiteStub>::BuildCodeStub() {
Add<HStoreNamedField>(object, Add<HStoreNamedField>(object,
HObjectAccess::ForAllocationSiteOffset( HObjectAccess::ForAllocationSiteOffset(
AllocationSite::kTransitionInfoOffset), AllocationSite::kTransitionInfoOffset),
initial_elements_kind); initial_elements_kind,
INITIALIZING_STORE);
// Unlike literals, constructed arrays don't have nested sites // Unlike literals, constructed arrays don't have nested sites
Add<HStoreNamedField>(object, Add<HStoreNamedField>(object,
HObjectAccess::ForAllocationSiteOffset( HObjectAccess::ForAllocationSiteOffset(
AllocationSite::kNestedSiteOffset), AllocationSite::kNestedSiteOffset),
graph()->GetConstant0()); graph()->GetConstant0(),
INITIALIZING_STORE);
// Pretenuring calculation field. // Pretenuring calculation field.
Add<HStoreNamedField>(object, Add<HStoreNamedField>(object,
HObjectAccess::ForAllocationSiteOffset( HObjectAccess::ForAllocationSiteOffset(
AllocationSite::kPretenureDataOffset), AllocationSite::kPretenureDataOffset),
graph()->GetConstant0()); graph()->GetConstant0(),
INITIALIZING_STORE);
// Pretenuring memento creation count field. // Pretenuring memento creation count field.
Add<HStoreNamedField>(object, Add<HStoreNamedField>(object,
HObjectAccess::ForAllocationSiteOffset( HObjectAccess::ForAllocationSiteOffset(
AllocationSite::kPretenureCreateCountOffset), AllocationSite::kPretenureCreateCountOffset),
graph()->GetConstant0()); graph()->GetConstant0(),
INITIALIZING_STORE);
// Store an empty fixed array for the code dependency. // Store an empty fixed array for the code dependency.
HConstant* empty_fixed_array = HConstant* empty_fixed_array =
...@@ -510,7 +515,8 @@ HValue* CodeStubGraphBuilder<CreateAllocationSiteStub>::BuildCodeStub() { ...@@ -510,7 +515,8 @@ HValue* CodeStubGraphBuilder<CreateAllocationSiteStub>::BuildCodeStub() {
object, object,
HObjectAccess::ForAllocationSiteOffset( HObjectAccess::ForAllocationSiteOffset(
AllocationSite::kDependentCodeOffset), AllocationSite::kDependentCodeOffset),
empty_fixed_array); empty_fixed_array,
INITIALIZING_STORE);
// Link the object to the allocation site list // Link the object to the allocation site list
HValue* site_list = Add<HConstant>( HValue* site_list = Add<HConstant>(
...@@ -519,10 +525,10 @@ HValue* CodeStubGraphBuilder<CreateAllocationSiteStub>::BuildCodeStub() { ...@@ -519,10 +525,10 @@ HValue* CodeStubGraphBuilder<CreateAllocationSiteStub>::BuildCodeStub() {
HObjectAccess::ForAllocationSiteList()); HObjectAccess::ForAllocationSiteList());
store = Add<HStoreNamedField>(object, store = Add<HStoreNamedField>(object,
HObjectAccess::ForAllocationSiteOffset(AllocationSite::kWeakNextOffset), HObjectAccess::ForAllocationSiteOffset(AllocationSite::kWeakNextOffset),
site); site, INITIALIZING_STORE);
store->SkipWriteBarrier(); store->SkipWriteBarrier();
Add<HStoreNamedField>(site_list, HObjectAccess::ForAllocationSiteList(), Add<HStoreNamedField>(site_list, HObjectAccess::ForAllocationSiteList(),
object); object, INITIALIZING_STORE);
// We use a hammer (SkipWriteBarrier()) to indicate that we know the input // We use a hammer (SkipWriteBarrier()) to indicate that we know the input
// cell is really a Cell, and so no write barrier is needed. // cell is really a Cell, and so no write barrier is needed.
...@@ -530,7 +536,7 @@ HValue* CodeStubGraphBuilder<CreateAllocationSiteStub>::BuildCodeStub() { ...@@ -530,7 +536,7 @@ HValue* CodeStubGraphBuilder<CreateAllocationSiteStub>::BuildCodeStub() {
// a cell. (perhaps with a new instruction, HAssert). // a cell. (perhaps with a new instruction, HAssert).
HInstruction* cell = GetParameter(0); HInstruction* cell = GetParameter(0);
HObjectAccess access = HObjectAccess::ForCellValue(); HObjectAccess access = HObjectAccess::ForCellValue();
store = Add<HStoreNamedField>(cell, access, object); store = Add<HStoreNamedField>(cell, access, object, INITIALIZING_STORE);
store->SkipWriteBarrier(); store->SkipWriteBarrier();
return cell; return cell;
} }
...@@ -746,7 +752,7 @@ HValue* CodeStubGraphBuilderBase::BuildArrayNArgumentsConstructor( ...@@ -746,7 +752,7 @@ HValue* CodeStubGraphBuilderBase::BuildArrayNArgumentsConstructor(
HInstruction* argument = Add<HAccessArgumentsAt>( HInstruction* argument = Add<HAccessArgumentsAt>(
argument_elements, checked_length, key); argument_elements, checked_length, key);
Add<HStoreKeyed>(elements, key, argument, kind); Add<HStoreKeyed>(elements, key, argument, kind, INITIALIZING_STORE);
builder.EndBody(); builder.EndBody();
return new_object; return new_object;
} }
...@@ -957,7 +963,8 @@ HValue* CodeStubGraphBuilder<BinaryOpICStub>::BuildCodeInitializedStub() { ...@@ -957,7 +963,8 @@ HValue* CodeStubGraphBuilder<BinaryOpICStub>::BuildCodeInitializedStub() {
IfBuilder if_heap_number(this); IfBuilder if_heap_number(this);
if_heap_number.IfNot<HIsSmiAndBranch>(operand); if_heap_number.IfNot<HIsSmiAndBranch>(operand);
if_heap_number.Then(); if_heap_number.Then();
Add<HStoreNamedField>(operand, HObjectAccess::ForHeapNumberValue(), result); Add<HStoreNamedField>(operand, HObjectAccess::ForHeapNumberValue(), result,
INITIALIZING_STORE);
Push(operand); Push(operand);
if_heap_number.Else(); if_heap_number.Else();
Push(result); Push(result);
...@@ -1080,7 +1087,7 @@ HValue* CodeStubGraphBuilder<StoreGlobalStub>::BuildCodeInitializedStub() { ...@@ -1080,7 +1087,7 @@ HValue* CodeStubGraphBuilder<StoreGlobalStub>::BuildCodeInitializedStub() {
builder.Then(); builder.Then();
builder.Deopt("Unexpected cell contents in global store"); builder.Deopt("Unexpected cell contents in global store");
builder.Else(); builder.Else();
Add<HStoreNamedField>(cell, access, value); Add<HStoreNamedField>(cell, access, value, INITIALIZING_STORE);
builder.End(); builder.End();
} }
...@@ -1144,12 +1151,12 @@ void CodeStubGraphBuilderBase::BuildInstallOptimizedCode( ...@@ -1144,12 +1151,12 @@ void CodeStubGraphBuilderBase::BuildInstallOptimizedCode(
HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST)); HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST));
Add<HStoreNamedField>(js_function, Add<HStoreNamedField>(js_function,
HObjectAccess::ForNextFunctionLinkPointer(), HObjectAccess::ForNextFunctionLinkPointer(),
optimized_functions_list); optimized_functions_list, INITIALIZING_STORE);
// This store is the only one that should have a write barrier. // This store is the only one that should have a write barrier.
Add<HStoreNamedField>(native_context, Add<HStoreNamedField>(native_context,
HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST), HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST),
js_function); js_function, INITIALIZING_STORE);
} }
...@@ -1157,7 +1164,8 @@ void CodeStubGraphBuilderBase::BuildInstallCode(HValue* js_function, ...@@ -1157,7 +1164,8 @@ void CodeStubGraphBuilderBase::BuildInstallCode(HValue* js_function,
HValue* shared_info) { HValue* shared_info) {
Add<HStoreNamedField>(js_function, Add<HStoreNamedField>(js_function,
HObjectAccess::ForNextFunctionLinkPointer(), HObjectAccess::ForNextFunctionLinkPointer(),
graph()->GetConstantUndefined()); graph()->GetConstantUndefined(),
INITIALIZING_STORE);
HValue* code_object = Add<HLoadNamedField>(shared_info, HValue* code_object = Add<HLoadNamedField>(shared_info,
HObjectAccess::ForCodeOffset()); HObjectAccess::ForCodeOffset());
Add<HStoreCodeEntry>(js_function, code_object); Add<HStoreCodeEntry>(js_function, code_object);
...@@ -1294,22 +1302,23 @@ HValue* CodeStubGraphBuilder<FastNewClosureStub>::BuildCodeStub() { ...@@ -1294,22 +1302,23 @@ HValue* CodeStubGraphBuilder<FastNewClosureStub>::BuildCodeStub() {
HInstruction* native_context = BuildGetNativeContext(); HInstruction* native_context = BuildGetNativeContext();
HInstruction* map_slot_value = Add<HLoadNamedField>(native_context, HInstruction* map_slot_value = Add<HLoadNamedField>(native_context,
HObjectAccess::ForContextSlot(map_index)); HObjectAccess::ForContextSlot(map_index));
Add<HStoreNamedField>(js_function, HObjectAccess::ForMap(), map_slot_value); Add<HStoreNamedField>(js_function, HObjectAccess::ForMap(), map_slot_value,
INITIALIZING_STORE);
// Initialize the rest of the function. // Initialize the rest of the function.
Add<HStoreNamedField>(js_function, HObjectAccess::ForPropertiesPointer(), Add<HStoreNamedField>(js_function, HObjectAccess::ForPropertiesPointer(),
empty_fixed_array); empty_fixed_array, INITIALIZING_STORE);
Add<HStoreNamedField>(js_function, HObjectAccess::ForElementsPointer(), Add<HStoreNamedField>(js_function, HObjectAccess::ForElementsPointer(),
empty_fixed_array); empty_fixed_array, INITIALIZING_STORE);
Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(), Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(),
empty_fixed_array); empty_fixed_array, INITIALIZING_STORE);
Add<HStoreNamedField>(js_function, HObjectAccess::ForPrototypeOrInitialMap(), Add<HStoreNamedField>(js_function, HObjectAccess::ForPrototypeOrInitialMap(),
graph()->GetConstantHole()); graph()->GetConstantHole(), INITIALIZING_STORE);
Add<HStoreNamedField>(js_function, Add<HStoreNamedField>(js_function,
HObjectAccess::ForSharedFunctionInfoPointer(), HObjectAccess::ForSharedFunctionInfoPointer(),
shared_info); shared_info, INITIALIZING_STORE);
Add<HStoreNamedField>(js_function, HObjectAccess::ForFunctionContextPointer(), Add<HStoreNamedField>(js_function, HObjectAccess::ForFunctionContextPointer(),
context()); context(), INITIALIZING_STORE);
// Initialize the code pointer in the function to be the one // Initialize the code pointer in the function to be the one
// found in the shared function info object. // found in the shared function info object.
...@@ -1346,18 +1355,18 @@ HValue* CodeStubGraphBuilder<FastNewContextStub>::BuildCodeStub() { ...@@ -1346,18 +1355,18 @@ HValue* CodeStubGraphBuilder<FastNewContextStub>::BuildCodeStub() {
isolate()->factory()->function_context_map()); isolate()->factory()->function_context_map());
Add<HStoreNamedField>(function_context, Add<HStoreNamedField>(function_context,
HObjectAccess::ForFixedArrayLength(), HObjectAccess::ForFixedArrayLength(),
Add<HConstant>(length)); Add<HConstant>(length), INITIALIZING_STORE);
// Set up the fixed slots. // Set up the fixed slots.
Add<HStoreNamedField>(function_context, Add<HStoreNamedField>(function_context,
HObjectAccess::ForContextSlot(Context::CLOSURE_INDEX), HObjectAccess::ForContextSlot(Context::CLOSURE_INDEX),
function); function, INITIALIZING_STORE);
Add<HStoreNamedField>(function_context, Add<HStoreNamedField>(function_context,
HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX), HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX),
context()); context(), INITIALIZING_STORE);
Add<HStoreNamedField>(function_context, Add<HStoreNamedField>(function_context,
HObjectAccess::ForContextSlot(Context::EXTENSION_INDEX), HObjectAccess::ForContextSlot(Context::EXTENSION_INDEX),
graph()->GetConstant0()); graph()->GetConstant0(), INITIALIZING_STORE);
// Copy the global object from the previous context. // Copy the global object from the previous context.
HValue* global_object = Add<HLoadNamedField>( HValue* global_object = Add<HLoadNamedField>(
...@@ -1365,13 +1374,15 @@ HValue* CodeStubGraphBuilder<FastNewContextStub>::BuildCodeStub() { ...@@ -1365,13 +1374,15 @@ HValue* CodeStubGraphBuilder<FastNewContextStub>::BuildCodeStub() {
Add<HStoreNamedField>(function_context, Add<HStoreNamedField>(function_context,
HObjectAccess::ForContextSlot( HObjectAccess::ForContextSlot(
Context::GLOBAL_OBJECT_INDEX), Context::GLOBAL_OBJECT_INDEX),
global_object); global_object,
INITIALIZING_STORE);
// Initialize the rest of the slots to undefined. // Initialize the rest of the slots to undefined.
for (int i = Context::MIN_CONTEXT_SLOTS; i < length; ++i) { for (int i = Context::MIN_CONTEXT_SLOTS; i < length; ++i) {
Add<HStoreNamedField>(function_context, Add<HStoreNamedField>(function_context,
HObjectAccess::ForContextSlot(i), HObjectAccess::ForContextSlot(i),
graph()->GetConstantUndefined()); graph()->GetConstantUndefined(),
INITIALIZING_STORE);
} }
return function_context; return function_context;
......
...@@ -3575,7 +3575,8 @@ void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) { ...@@ -3575,7 +3575,8 @@ 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);
...@@ -3589,7 +3590,7 @@ void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) { ...@@ -3589,7 +3590,7 @@ void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) {
HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset, HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset,
Representation::Smi()); Representation::Smi());
HStoreNamedField* store_size = HStoreNamedField::New(zone, context(), HStoreNamedField* store_size = HStoreNamedField::New(zone, context(),
free_space_instr, access, filler_size); free_space_instr, access, filler_size, INITIALIZING_STORE);
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;
...@@ -3602,7 +3603,7 @@ void HAllocate::ClearNextMapWord(int offset) { ...@@ -3602,7 +3603,7 @@ void HAllocate::ClearNextMapWord(int offset) {
HObjectAccess access = HObjectAccess::ForJSObjectOffset(offset); HObjectAccess access = HObjectAccess::ForJSObjectOffset(offset);
HStoreNamedField* clear_next_map = HStoreNamedField* clear_next_map =
HStoreNamedField::New(zone, context(), this, access, HStoreNamedField::New(zone, context(), this, access,
block()->graph()->GetConstant0()); block()->graph()->GetConstant0(), INITIALIZING_STORE);
clear_next_map->ClearAllSideEffects(); clear_next_map->ClearAllSideEffects();
clear_next_map->InsertAfter(this); clear_next_map->InsertAfter(this);
} }
......
...@@ -6494,15 +6494,19 @@ class HLoadKeyedGeneric V8_FINAL : public HTemplateInstruction<3> { ...@@ -6494,15 +6494,19 @@ 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.
INITIALIZING_STORE, INITIALIZING_STORE,
// At the time of this store it is guaranteed that the entry is already
// initialized.
STORE_TO_INITIALIZED_ENTRY STORE_TO_INITIALIZED_ENTRY
}; };
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);
...@@ -6609,12 +6613,17 @@ class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> { ...@@ -6609,12 +6613,17 @@ class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> {
HStoreNamedField(HValue* obj, HStoreNamedField(HValue* obj,
HObjectAccess access, HObjectAccess access,
HValue* val, HValue* val,
StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE) StoreFieldOrKeyedMode store_mode)
: 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
// memory region resulting from HAllocate (possibly through an
// HInnerAllocatedObject).
ASSERT(store_mode != PREINITIALIZING_STORE ||
obj->IsAllocate() || obj->IsInnerAllocatedObject());
SetOperandAt(0, obj); SetOperandAt(0, obj);
SetOperandAt(1, val); SetOperandAt(1, val);
SetOperandAt(2, obj); SetOperandAt(2, obj);
...@@ -6625,7 +6634,7 @@ class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> { ...@@ -6625,7 +6634,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_ : 1; StoreFieldOrKeyedMode store_mode_ : 2;
}; };
...@@ -6670,8 +6679,6 @@ class HStoreNamedGeneric V8_FINAL : public HTemplateInstruction<3> { ...@@ -6670,8 +6679,6 @@ 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);
...@@ -6791,7 +6798,7 @@ class HStoreKeyed V8_FINAL ...@@ -6791,7 +6798,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 = INITIALIZING_STORE) StoreFieldOrKeyedMode store_mode)
: elements_kind_(elements_kind), : elements_kind_(elements_kind),
index_offset_(0), index_offset_(0),
is_dehoisted_(false), is_dehoisted_(false),
...@@ -6802,6 +6809,12 @@ class HStoreKeyed V8_FINAL ...@@ -6802,6 +6809,12 @@ 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);
...@@ -6836,7 +6849,7 @@ class HStoreKeyed V8_FINAL ...@@ -6836,7 +6849,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_: 1; StoreFieldOrKeyedMode store_mode_: 2;
HValue* new_space_dominator_; HValue* new_space_dominator_;
}; };
......
...@@ -176,6 +176,10 @@ class HLoadEliminationTable : public ZoneObject { ...@@ -176,6 +176,10 @@ class HLoadEliminationTable : public ZoneObject {
approx = approx->next_; approx = approx->next_;
} }
} }
if (FLAG_trace_load_elimination) {
TRACE((" merge-to B%d\n", succ->block_id()));
Print();
}
return this; return this;
} }
...@@ -208,6 +212,11 @@ class HLoadEliminationTable : public ZoneObject { ...@@ -208,6 +212,11 @@ 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) {
TRACE((" skipping preinitializing store\n"));
return instr;
}
int field = FieldOf(instr->access()); int field = FieldOf(instr->access());
if (field < 0) return KillIfMisaligned(instr); if (field < 0) return KillIfMisaligned(instr);
......
This diff is collapsed.
...@@ -1365,7 +1365,7 @@ class HGraphBuilder { ...@@ -1365,7 +1365,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); object, HObjectAccess::ForMap(), map, INITIALIZING_STORE);
store_map->SkipWriteBarrier(); store_map->SkipWriteBarrier();
return store_map; return store_map;
} }
......
...@@ -83,6 +83,15 @@ function test_transitioning_store2() { ...@@ -83,6 +83,15 @@ function test_transitioning_store2() {
return a.x + a.y; return a.x + a.y;
} }
var false_v = false;
function test_transitioning_store3() {
var o = new C();
var v = o;
if (false_v) v = 0;
v.x = 20;
return o.x;
}
function killall() { function killall() {
try { } catch(e) { } try { } catch(e) { }
} }
...@@ -123,5 +132,6 @@ test(22, test_store_load); ...@@ -123,5 +132,6 @@ test(22, test_store_load);
test(8, test_nonaliasing_store1); test(8, test_nonaliasing_store1);
test(5, test_transitioning_store1); test(5, test_transitioning_store1);
test(4, test_transitioning_store2); test(4, test_transitioning_store2);
test(20, test_transitioning_store3);
test(22, test_store_load_kill); test(22, test_store_load_kill);
test(7, test_store_store); test(7, test_store_store);
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