Index: src/code-stubs-hydrogen.cc |
diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc |
index 320799db4a79128173b5f1c657a623372e4d134b..50337ad6344ef3e4d97a0dc04cee8a8080d49046 100644 |
--- a/src/code-stubs-hydrogen.cc |
+++ b/src/code-stubs-hydrogen.cc |
@@ -550,6 +550,79 @@ |
template <> |
+HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() { |
+ HValue* undefined = graph()->GetConstantUndefined(); |
+ HValue* closure = GetParameter(0); |
+ HValue* literal_index = GetParameter(1); |
+ |
+ HValue* literals_array = Add<HLoadNamedField>( |
+ closure, nullptr, HObjectAccess::ForLiteralsPointer()); |
+ |
+ HInstruction* allocation_site = Add<HLoadKeyed>( |
+ literals_array, literal_index, nullptr, nullptr, FAST_ELEMENTS, |
+ NEVER_RETURN_HOLE, LiteralsArray::kOffsetToFirstLiteral - kHeapObjectTag); |
+ |
+ IfBuilder checker(this); |
+ checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site, |
+ undefined); |
+ checker.And(); |
+ |
+ HObjectAccess access = HObjectAccess::ForAllocationSiteOffset( |
+ AllocationSite::kTransitionInfoOffset); |
+ HInstruction* boilerplate = |
+ Add<HLoadNamedField>(allocation_site, nullptr, access); |
+ |
+ int length = casted_stub()->length(); |
+ if (length == 0) { |
+ // Empty objects have some slack added to them. |
+ length = JSObject::kInitialGlobalObjectUnusedPropertiesCount; |
+ } |
+ int size = JSObject::kHeaderSize + length * kPointerSize; |
+ int object_size = size; |
+ if (FLAG_allocation_site_pretenuring) { |
+ size += AllocationMemento::kSize; |
+ } |
+ |
+ HValue* boilerplate_map = |
+ Add<HLoadNamedField>(boilerplate, nullptr, HObjectAccess::ForMap()); |
+ HValue* boilerplate_size = Add<HLoadNamedField>( |
+ boilerplate_map, nullptr, HObjectAccess::ForMapInstanceSize()); |
+ HValue* size_in_words = Add<HConstant>(object_size >> kPointerSizeLog2); |
+ checker.If<HCompareNumericAndBranch>(boilerplate_size, |
+ size_in_words, Token::EQ); |
+ checker.Then(); |
+ |
+ HValue* size_in_bytes = Add<HConstant>(size); |
+ |
+ HInstruction* object = Add<HAllocate>(size_in_bytes, HType::JSObject(), |
+ NOT_TENURED, JS_OBJECT_TYPE); |
+ |
+ for (int i = 0; i < object_size; i += kPointerSize) { |
+ HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset(i); |
+ Add<HStoreNamedField>(object, access, |
+ Add<HLoadNamedField>(boilerplate, nullptr, access)); |
+ } |
+ |
+ DCHECK(FLAG_allocation_site_pretenuring || (size == object_size)); |
+ if (FLAG_allocation_site_pretenuring) { |
+ BuildCreateAllocationMemento( |
+ object, Add<HConstant>(object_size), allocation_site); |
+ } |
+ |
+ environment()->Push(object); |
+ checker.ElseDeopt(Deoptimizer::kUninitializedBoilerplateInFastClone); |
+ checker.End(); |
+ |
+ return environment()->Pop(); |
+} |
+ |
+ |
+Handle<Code> FastCloneShallowObjectStub::GenerateCode() { |
+ return DoGenerateCode(this); |
+} |
+ |
+ |
+template <> |
HValue* CodeStubGraphBuilder<CreateAllocationSiteStub>::BuildCodeStub() { |
// This stub is performance sensitive, the generated code must be tuned |
// so that it doesn't build an eager frame. |