| Index: src/code-stubs.cc
|
| diff --git a/src/code-stubs.cc b/src/code-stubs.cc
|
| index 686a449ac7f7a688be1de31c98d279c614957b33..532756569b1ecb3033e306e199685f60dbf2a669 100644
|
| --- a/src/code-stubs.cc
|
| +++ b/src/code-stubs.cc
|
| @@ -1777,123 +1777,6 @@ void LoadIndexedInterceptorStub::GenerateAssembly(
|
| slot, vector);
|
| }
|
|
|
| -// static
|
| -int FastCloneShallowObjectStub::PropertiesCount(int literal_length) {
|
| - // This heuristic of setting empty literals to have
|
| - // kInitialGlobalObjectUnusedPropertiesCount must remain in-sync with the
|
| - // runtime.
|
| - // TODO(verwaest): Unify this with the heuristic in the runtime.
|
| - return literal_length == 0
|
| - ? JSObject::kInitialGlobalObjectUnusedPropertiesCount
|
| - : literal_length;
|
| -}
|
| -
|
| -// static
|
| -compiler::Node* FastCloneShallowObjectStub::GenerateFastPath(
|
| - CodeStubAssembler* assembler, compiler::CodeAssembler::Label* call_runtime,
|
| - compiler::Node* closure, compiler::Node* literals_index,
|
| - compiler::Node* properties_count) {
|
| - typedef compiler::Node Node;
|
| - typedef compiler::CodeAssembler::Label Label;
|
| - typedef compiler::CodeAssembler::Variable Variable;
|
| -
|
| - Node* literals_array =
|
| - assembler->LoadObjectField(closure, JSFunction::kLiteralsOffset);
|
| - Node* allocation_site = assembler->LoadFixedArrayElement(
|
| - literals_array, literals_index,
|
| - LiteralsArray::kFirstLiteralIndex * kPointerSize,
|
| - CodeStubAssembler::SMI_PARAMETERS);
|
| - assembler->GotoIf(assembler->IsUndefined(allocation_site), call_runtime);
|
| -
|
| - // Calculate the object and allocation size based on the properties count.
|
| - Node* object_size = assembler->IntPtrAdd(
|
| - assembler->WordShl(properties_count, kPointerSizeLog2),
|
| - assembler->IntPtrConstant(JSObject::kHeaderSize));
|
| - Node* allocation_size = object_size;
|
| - if (FLAG_allocation_site_pretenuring) {
|
| - allocation_size = assembler->IntPtrAdd(
|
| - object_size, assembler->IntPtrConstant(AllocationMemento::kSize));
|
| - }
|
| - Node* boilerplate = assembler->LoadObjectField(
|
| - allocation_site, AllocationSite::kTransitionInfoOffset);
|
| - Node* boilerplate_map = assembler->LoadMap(boilerplate);
|
| - Node* instance_size = assembler->LoadMapInstanceSize(boilerplate_map);
|
| - Node* size_in_words = assembler->WordShr(object_size, kPointerSizeLog2);
|
| - assembler->GotoUnless(assembler->WordEqual(instance_size, size_in_words),
|
| - call_runtime);
|
| -
|
| - Node* copy = assembler->Allocate(allocation_size);
|
| -
|
| - // Copy boilerplate elements.
|
| - Variable offset(assembler, MachineType::PointerRepresentation());
|
| - offset.Bind(assembler->IntPtrConstant(-kHeapObjectTag));
|
| - Node* end_offset = assembler->IntPtrAdd(object_size, offset.value());
|
| - Label loop_body(assembler, &offset), loop_check(assembler, &offset);
|
| - // We should always have an object size greater than zero.
|
| - assembler->Goto(&loop_body);
|
| - assembler->Bind(&loop_body);
|
| - {
|
| - // The Allocate above guarantees that the copy lies in new space. This
|
| - // allows us to skip write barriers. This is necessary since we may also be
|
| - // copying unboxed doubles.
|
| - Node* field =
|
| - assembler->Load(MachineType::IntPtr(), boilerplate, offset.value());
|
| - assembler->StoreNoWriteBarrier(MachineType::PointerRepresentation(), copy,
|
| - offset.value(), field);
|
| - assembler->Goto(&loop_check);
|
| - }
|
| - assembler->Bind(&loop_check);
|
| - {
|
| - offset.Bind(assembler->IntPtrAdd(offset.value(),
|
| - assembler->IntPtrConstant(kPointerSize)));
|
| - assembler->GotoUnless(
|
| - assembler->IntPtrGreaterThanOrEqual(offset.value(), end_offset),
|
| - &loop_body);
|
| - }
|
| -
|
| - if (FLAG_allocation_site_pretenuring) {
|
| - Node* memento = assembler->InnerAllocate(copy, object_size);
|
| - assembler->StoreMapNoWriteBarrier(memento,
|
| - Heap::kAllocationMementoMapRootIndex);
|
| - assembler->StoreObjectFieldNoWriteBarrier(
|
| - memento, AllocationMemento::kAllocationSiteOffset, allocation_site);
|
| - Node* memento_create_count = assembler->LoadObjectField(
|
| - allocation_site, AllocationSite::kPretenureCreateCountOffset);
|
| - memento_create_count = assembler->SmiAdd(
|
| - memento_create_count, assembler->SmiConstant(Smi::FromInt(1)));
|
| - assembler->StoreObjectFieldNoWriteBarrier(
|
| - allocation_site, AllocationSite::kPretenureCreateCountOffset,
|
| - memento_create_count);
|
| - }
|
| -
|
| - // TODO(verwaest): Allocate and fill in double boxes.
|
| - return copy;
|
| -}
|
| -
|
| -void FastCloneShallowObjectStub::GenerateAssembly(
|
| - compiler::CodeAssemblerState* state) const {
|
| - typedef CodeStubAssembler::Label Label;
|
| - typedef compiler::Node Node;
|
| - CodeStubAssembler assembler(state);
|
| -
|
| - Label call_runtime(&assembler);
|
| - Node* closure = assembler.Parameter(0);
|
| - Node* literals_index = assembler.Parameter(1);
|
| -
|
| - Node* properties_count =
|
| - assembler.IntPtrConstant(PropertiesCount(this->length()));
|
| - Node* copy = GenerateFastPath(&assembler, &call_runtime, closure,
|
| - literals_index, properties_count);
|
| - assembler.Return(copy);
|
| -
|
| - assembler.Bind(&call_runtime);
|
| - Node* constant_properties = assembler.Parameter(2);
|
| - Node* flags = assembler.Parameter(3);
|
| - Node* context = assembler.Parameter(4);
|
| - assembler.TailCallRuntime(Runtime::kCreateObjectLiteral, context, closure,
|
| - literals_index, constant_properties, flags);
|
| -}
|
| -
|
| template<class StateType>
|
| void HydrogenCodeStub::TraceTransition(StateType from, StateType to) {
|
| // Note: Although a no-op transition is semantically OK, it is hinting at a
|
| @@ -2053,252 +1936,6 @@ void GetPropertyStub::GenerateAssembly(
|
| assembler.Return(var_result.value());
|
| }
|
|
|
| -// static
|
| -compiler::Node* FastCloneRegExpStub::Generate(CodeStubAssembler* assembler,
|
| - compiler::Node* closure,
|
| - compiler::Node* literal_index,
|
| - compiler::Node* pattern,
|
| - compiler::Node* flags,
|
| - compiler::Node* context) {
|
| - typedef CodeStubAssembler::Label Label;
|
| - typedef CodeStubAssembler::Variable Variable;
|
| - typedef compiler::Node Node;
|
| -
|
| - Label call_runtime(assembler, Label::kDeferred), end(assembler);
|
| -
|
| - Variable result(assembler, MachineRepresentation::kTagged);
|
| -
|
| - Node* literals_array =
|
| - assembler->LoadObjectField(closure, JSFunction::kLiteralsOffset);
|
| - Node* boilerplate = assembler->LoadFixedArrayElement(
|
| - literals_array, literal_index,
|
| - LiteralsArray::kFirstLiteralIndex * kPointerSize,
|
| - CodeStubAssembler::SMI_PARAMETERS);
|
| - assembler->GotoIf(assembler->IsUndefined(boilerplate), &call_runtime);
|
| -
|
| - {
|
| - int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
|
| - Node* copy = assembler->Allocate(size);
|
| - for (int offset = 0; offset < size; offset += kPointerSize) {
|
| - Node* value = assembler->LoadObjectField(boilerplate, offset);
|
| - assembler->StoreObjectFieldNoWriteBarrier(copy, offset, value);
|
| - }
|
| - result.Bind(copy);
|
| - assembler->Goto(&end);
|
| - }
|
| -
|
| - assembler->Bind(&call_runtime);
|
| - {
|
| - result.Bind(assembler->CallRuntime(Runtime::kCreateRegExpLiteral, context,
|
| - closure, literal_index, pattern, flags));
|
| - assembler->Goto(&end);
|
| - }
|
| -
|
| - assembler->Bind(&end);
|
| - return result.value();
|
| -}
|
| -
|
| -void FastCloneRegExpStub::GenerateAssembly(
|
| - compiler::CodeAssemblerState* state) const {
|
| - typedef compiler::Node Node;
|
| - CodeStubAssembler assembler(state);
|
| - Node* closure = assembler.Parameter(Descriptor::kClosure);
|
| - Node* literal_index = assembler.Parameter(Descriptor::kLiteralIndex);
|
| - Node* pattern = assembler.Parameter(Descriptor::kPattern);
|
| - Node* flags = assembler.Parameter(Descriptor::kFlags);
|
| - Node* context = assembler.Parameter(Descriptor::kContext);
|
| -
|
| - assembler.Return(
|
| - Generate(&assembler, closure, literal_index, pattern, flags, context));
|
| -}
|
| -
|
| -namespace {
|
| -
|
| -compiler::Node* NonEmptyShallowClone(CodeStubAssembler* assembler,
|
| - compiler::Node* boilerplate,
|
| - compiler::Node* boilerplate_map,
|
| - compiler::Node* boilerplate_elements,
|
| - compiler::Node* allocation_site,
|
| - compiler::Node* capacity,
|
| - ElementsKind kind) {
|
| - typedef compiler::Node Node;
|
| - typedef CodeStubAssembler::ParameterMode ParameterMode;
|
| -
|
| - ParameterMode param_mode = assembler->OptimalParameterMode();
|
| -
|
| - Node* length = assembler->LoadJSArrayLength(boilerplate);
|
| - capacity = assembler->TaggedToParameter(capacity, param_mode);
|
| -
|
| - Node *array, *elements;
|
| - std::tie(array, elements) =
|
| - assembler->AllocateUninitializedJSArrayWithElements(
|
| - kind, boilerplate_map, length, allocation_site, capacity, param_mode);
|
| -
|
| - assembler->Comment("copy elements header");
|
| - // Header consists of map and length.
|
| - STATIC_ASSERT(FixedArrayBase::kHeaderSize == 2 * kPointerSize);
|
| - assembler->StoreMap(elements, assembler->LoadMap(boilerplate_elements));
|
| - {
|
| - int offset = FixedArrayBase::kLengthOffset;
|
| - assembler->StoreObjectFieldNoWriteBarrier(
|
| - elements, offset,
|
| - assembler->LoadObjectField(boilerplate_elements, offset));
|
| - }
|
| -
|
| - length = assembler->TaggedToParameter(length, param_mode);
|
| -
|
| - assembler->Comment("copy boilerplate elements");
|
| - assembler->CopyFixedArrayElements(kind, boilerplate_elements, elements,
|
| - length, SKIP_WRITE_BARRIER, param_mode);
|
| - assembler->IncrementCounter(
|
| - assembler->isolate()->counters()->inlined_copied_elements(), 1);
|
| -
|
| - return array;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -// static
|
| -compiler::Node* FastCloneShallowArrayStub::Generate(
|
| - CodeStubAssembler* assembler, compiler::Node* closure,
|
| - compiler::Node* literal_index, compiler::Node* context,
|
| - CodeStubAssembler::Label* call_runtime,
|
| - AllocationSiteMode allocation_site_mode) {
|
| - typedef CodeStubAssembler::Label Label;
|
| - typedef CodeStubAssembler::Variable Variable;
|
| - typedef compiler::Node Node;
|
| -
|
| - Label zero_capacity(assembler), cow_elements(assembler),
|
| - fast_elements(assembler), return_result(assembler);
|
| - Variable result(assembler, MachineRepresentation::kTagged);
|
| -
|
| - Node* literals_array =
|
| - assembler->LoadObjectField(closure, JSFunction::kLiteralsOffset);
|
| - Node* allocation_site = assembler->LoadFixedArrayElement(
|
| - literals_array, literal_index,
|
| - LiteralsArray::kFirstLiteralIndex * kPointerSize,
|
| - CodeStubAssembler::SMI_PARAMETERS);
|
| -
|
| - assembler->GotoIf(assembler->IsUndefined(allocation_site), call_runtime);
|
| - allocation_site = assembler->LoadFixedArrayElement(
|
| - literals_array, literal_index,
|
| - LiteralsArray::kFirstLiteralIndex * kPointerSize,
|
| - CodeStubAssembler::SMI_PARAMETERS);
|
| -
|
| - Node* boilerplate = assembler->LoadObjectField(
|
| - allocation_site, AllocationSite::kTransitionInfoOffset);
|
| - Node* boilerplate_map = assembler->LoadMap(boilerplate);
|
| - Node* boilerplate_elements = assembler->LoadElements(boilerplate);
|
| - Node* capacity = assembler->LoadFixedArrayBaseLength(boilerplate_elements);
|
| - allocation_site =
|
| - allocation_site_mode == TRACK_ALLOCATION_SITE ? allocation_site : nullptr;
|
| -
|
| - Node* zero = assembler->SmiConstant(Smi::kZero);
|
| - assembler->GotoIf(assembler->SmiEqual(capacity, zero), &zero_capacity);
|
| -
|
| - Node* elements_map = assembler->LoadMap(boilerplate_elements);
|
| - assembler->GotoIf(assembler->IsFixedCOWArrayMap(elements_map), &cow_elements);
|
| -
|
| - assembler->GotoIf(assembler->IsFixedArrayMap(elements_map), &fast_elements);
|
| - {
|
| - assembler->Comment("fast double elements path");
|
| - if (FLAG_debug_code) {
|
| - Label correct_elements_map(assembler), abort(assembler, Label::kDeferred);
|
| - assembler->Branch(assembler->IsFixedDoubleArrayMap(elements_map),
|
| - &correct_elements_map, &abort);
|
| -
|
| - assembler->Bind(&abort);
|
| - {
|
| - Node* abort_id = assembler->SmiConstant(
|
| - Smi::FromInt(BailoutReason::kExpectedFixedDoubleArrayMap));
|
| - assembler->CallRuntime(Runtime::kAbort, context, abort_id);
|
| - result.Bind(assembler->UndefinedConstant());
|
| - assembler->Goto(&return_result);
|
| - }
|
| - assembler->Bind(&correct_elements_map);
|
| - }
|
| -
|
| - Node* array = NonEmptyShallowClone(assembler, boilerplate, boilerplate_map,
|
| - boilerplate_elements, allocation_site,
|
| - capacity, FAST_DOUBLE_ELEMENTS);
|
| - result.Bind(array);
|
| - assembler->Goto(&return_result);
|
| - }
|
| -
|
| - assembler->Bind(&fast_elements);
|
| - {
|
| - assembler->Comment("fast elements path");
|
| - Node* array = NonEmptyShallowClone(assembler, boilerplate, boilerplate_map,
|
| - boilerplate_elements, allocation_site,
|
| - capacity, FAST_ELEMENTS);
|
| - result.Bind(array);
|
| - assembler->Goto(&return_result);
|
| - }
|
| -
|
| - Variable length(assembler, MachineRepresentation::kTagged),
|
| - elements(assembler, MachineRepresentation::kTagged);
|
| - Label allocate_without_elements(assembler);
|
| -
|
| - assembler->Bind(&cow_elements);
|
| - {
|
| - assembler->Comment("fixed cow path");
|
| - length.Bind(assembler->LoadJSArrayLength(boilerplate));
|
| - elements.Bind(boilerplate_elements);
|
| -
|
| - assembler->Goto(&allocate_without_elements);
|
| - }
|
| -
|
| - assembler->Bind(&zero_capacity);
|
| - {
|
| - assembler->Comment("zero capacity path");
|
| - length.Bind(zero);
|
| - elements.Bind(assembler->LoadRoot(Heap::kEmptyFixedArrayRootIndex));
|
| -
|
| - assembler->Goto(&allocate_without_elements);
|
| - }
|
| -
|
| - assembler->Bind(&allocate_without_elements);
|
| - {
|
| - Node* array = assembler->AllocateUninitializedJSArrayWithoutElements(
|
| - FAST_ELEMENTS, boilerplate_map, length.value(), allocation_site);
|
| - assembler->StoreObjectField(array, JSObject::kElementsOffset,
|
| - elements.value());
|
| - result.Bind(array);
|
| - assembler->Goto(&return_result);
|
| - }
|
| -
|
| - assembler->Bind(&return_result);
|
| - return result.value();
|
| -}
|
| -
|
| -void FastCloneShallowArrayStub::GenerateAssembly(
|
| - compiler::CodeAssemblerState* state) const {
|
| - typedef compiler::Node Node;
|
| - typedef CodeStubAssembler::Label Label;
|
| - CodeStubAssembler assembler(state);
|
| -
|
| - Node* closure = assembler.Parameter(Descriptor::kClosure);
|
| - Node* literal_index = assembler.Parameter(Descriptor::kLiteralIndex);
|
| - Node* constant_elements = assembler.Parameter(Descriptor::kConstantElements);
|
| - Node* context = assembler.Parameter(Descriptor::kContext);
|
| - Label call_runtime(&assembler, Label::kDeferred);
|
| - assembler.Return(Generate(&assembler, closure, literal_index, context,
|
| - &call_runtime, allocation_site_mode()));
|
| -
|
| - assembler.Bind(&call_runtime);
|
| - {
|
| - assembler.Comment("call runtime");
|
| - Node* flags = assembler.SmiConstant(
|
| - Smi::FromInt(ArrayLiteral::kShallowElements |
|
| - (allocation_site_mode() == TRACK_ALLOCATION_SITE
|
| - ? 0
|
| - : ArrayLiteral::kDisableMementos)));
|
| - assembler.Return(assembler.CallRuntime(Runtime::kCreateArrayLiteral,
|
| - context, closure, literal_index,
|
| - constant_elements, flags));
|
| - }
|
| -}
|
| -
|
| void CreateAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) {
|
| CreateAllocationSiteStub stub(isolate);
|
| stub.GetCode();
|
|
|