Chromium Code Reviews| Index: src/code-stubs-hydrogen.cc |
| diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc |
| index 51734da2f16a754110d4acb04f6192e2aeb10664..78a2af2b25fa212d20ee1e4d2c4ee36959cb3a38 100644 |
| --- a/src/code-stubs-hydrogen.cc |
| +++ b/src/code-stubs-hydrogen.cc |
| @@ -918,4 +918,94 @@ Handle<Code> StoreGlobalStub::GenerateCode() { |
| } |
| +template<> |
| +HValue* CodeStubGraphBuilder<ElementsTransitionAndStoreStub>::BuildCodeStub() { |
| + ElementsTransitionAndStoreStub* stub = casted_stub(); |
| + ElementsKind from_kind = stub->from(); |
| + ElementsKind to_kind = stub->to(); |
| + |
| + HValue* value = GetParameter(0); |
| + HValue* target_map = GetParameter(1); |
| + HValue* key = GetParameter(2); |
| + HValue* array = GetParameter(3); |
| + |
| + ASSERT(!IsFastHoleyElementsKind(from_kind) || |
| + IsFastHoleyElementsKind(to_kind)); |
| + if (FLAG_trace_elements_transitions) { |
| + // Tracing elements transitions is the job of the runtime. |
| + current_block()->FinishExitWithDeoptimization(HDeoptimize::kUseAll); |
| + set_current_block(NULL); |
|
danno
2013/07/10 09:52:37
I think it's cleaner if you return value here and
Benedikt Meurer
2013/07/10 12:23:09
Done.
|
| + } else { |
| + if (AllocationSite::GetMode(from_kind, to_kind) == TRACK_ALLOCATION_SITE) { |
| + Add<HTrapAllocationMemento>(array); |
| + } |
| + if (IsFastDoubleElementsKind(from_kind) && |
| + to_kind == FAST_HOLEY_DOUBLE_ELEMENTS) { |
| + // Set transitioned map. |
| + AddStore(array, HObjectAccess::ForMap(), target_map); |
|
danno
2013/07/10 09:52:37
Why the special casing here? Either the stub shoul
Benedikt Meurer
2013/07/10 12:23:09
Done.
|
| + |
| + // Let the runtime handle the actual store. |
| + current_block()->FinishExitWithDeoptimization(HDeoptimize::kUseAll); |
| + set_current_block(NULL); |
| + } else { |
| + // Check if we need to transition the array elements first |
| + // (either SMI -> Double or Double -> Object). |
| + if ((IsFastSmiElementsKind(from_kind) && |
| + IsFastDoubleElementsKind(to_kind)) || |
| + (IsFastDoubleElementsKind(from_kind) && |
| + IsFastObjectElementsKind(to_kind))) { |
|
danno
2013/07/10 09:52:37
Can you create a predicate in elements-kind.h to t
Benedikt Meurer
2013/07/10 12:23:09
Done.
|
| + HInstruction* elements = AddLoadElements(array); |
| + HInstruction* elements_length = AddLoadFixedArrayLength(elements); |
| + |
| + IfBuilder if_fixed(this); |
| + |
| + // Check if we have any elements. |
| + if_fixed.If<HCompareNumericAndBranch>(elements_length, |
|
danno
2013/07/10 09:52:37
You can use IfNot here and then put the meat of th
Benedikt Meurer
2013/07/10 12:23:09
Done.
|
| + graph()->GetConstant0(), |
| + Token::EQ); |
| + |
| + if_fixed.Then(); |
| + |
| + // Nothing to do, just change the map. |
| + |
| + if_fixed.Else(); |
| + |
| + // Check if we can allocate in new space. |
| + BuildNewSpaceArrayCheck(elements_length, to_kind); |
|
danno
2013/07/10 09:52:37
Why can't you use the helper function "BuildGrowEl
Benedikt Meurer
2013/07/10 12:23:09
Done.
danno
2013/07/10 12:33:44
Done.
|
| + |
| + // Allocate new elements storage. |
| + HValue* new_elements = BuildAllocateElementsAndInitializeElementsHeader( |
| + context(), to_kind, elements_length); |
| + |
| + // Convert and copy the elements to new storage. |
| + BuildCopyElements(context(), |
| + elements, from_kind, |
| + new_elements, to_kind, |
| + elements_length, elements_length); |
| + |
| + // Set new elements pointer. |
| + AddStore(array, HObjectAccess::ForElementsPointer(), new_elements); |
| + |
| + if_fixed.End(); |
| + } |
| + |
| + // Set transitioned map. |
| + AddStore(array, HObjectAccess::ForMap(), target_map); |
| + |
| + // Generate the actual store. |
| + BuildUncheckedMonomorphicElementAccess(array, key, value, NULL, |
|
danno
2013/07/10 09:52:37
You can probably factor this out to only be called
Benedikt Meurer
2013/07/10 12:23:09
Maybe I'm missing the point here, but BuildUncheck
|
| + stub->is_jsarray(), to_kind, |
| + true, ALLOW_RETURN_HOLE, |
| + stub->store_mode()); |
| + } |
| + } |
| + return value; |
| +} |
| + |
| + |
| +Handle<Code> ElementsTransitionAndStoreStub::GenerateCode() { |
| + return DoGenerateCode(this); |
| +} |
| + |
| + |
| } } // namespace v8::internal |