Index: src/code-stubs-hydrogen.cc |
diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc |
index 36242405b14c0fa5afd1174cb5a54b1d3aae7fc8..e688bedcad1fd20b21f904329f9ceaaea1a81884 100644 |
--- a/src/code-stubs-hydrogen.cc |
+++ b/src/code-stubs-hydrogen.cc |
@@ -1432,15 +1432,61 @@ Handle<Code> StoreFastElementStub::GenerateCode() { |
template <> |
HValue* CodeStubGraphBuilder<TransitionElementsKindStub>::BuildCodeStub() { |
+ ElementsKind const from_kind = casted_stub()->from_kind(); |
+ ElementsKind const to_kind = casted_stub()->to_kind(); |
+ HValue* const object = GetParameter(0); |
+ HValue* const map = GetParameter(1); |
+ |
+ // The {object} is known to be a JSObject (otherwise it wouldn't have elements |
+ // anyways). |
+ object->set_type(HType::JSObject()); |
+ |
info()->MarkAsSavesCallerDoubles(); |
- BuildTransitionElementsKind(GetParameter(0), |
- GetParameter(1), |
- casted_stub()->from_kind(), |
- casted_stub()->to_kind(), |
- casted_stub()->is_js_array()); |
+ DCHECK_IMPLIES(IsFastHoleyElementsKind(from_kind), |
+ IsFastHoleyElementsKind(to_kind)); |
+ |
+ if (AllocationSite::GetMode(from_kind, to_kind) == TRACK_ALLOCATION_SITE) { |
+ Add<HTrapAllocationMemento>(object); |
+ } |
+ |
+ if (!IsSimpleMapChangeTransition(from_kind, to_kind)) { |
+ HInstruction* elements = AddLoadElements(object); |
+ |
+ IfBuilder if_objecthaselements(this); |
+ if_objecthaselements.IfNot<HCompareObjectEqAndBranch>( |
+ elements, Add<HConstant>(isolate()->factory()->empty_fixed_array())); |
+ if_objecthaselements.Then(); |
+ { |
+ // Determine the elements capacity. |
+ HInstruction* elements_length = AddLoadFixedArrayLength(elements); |
+ |
+ // Determine the effective (array) length. |
+ IfBuilder if_objectisarray(this); |
+ if_objectisarray.If<HHasInstanceTypeAndBranch>(object, JS_ARRAY_TYPE); |
+ if_objectisarray.Then(); |
+ { |
+ // The {object} is a JSArray, load the special "length" property. |
+ Push(Add<HLoadNamedField>(object, nullptr, |
+ HObjectAccess::ForArrayLength(from_kind))); |
+ } |
+ if_objectisarray.Else(); |
+ { |
+ // The {object} is some other JSObject. |
+ Push(elements_length); |
+ } |
+ if_objectisarray.End(); |
+ HValue* length = Pop(); |
+ |
+ BuildGrowElementsCapacity(object, elements, from_kind, to_kind, length, |
+ elements_length); |
+ } |
+ if_objecthaselements.End(); |
+ } |
+ |
+ Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map); |
- return GetParameter(0); |
+ return object; |
} |