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(); |