| 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.
|
|
|