| Index: src/x64/stub-cache-x64.cc
|
| diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
|
| index fbd122aba8b83ed167cb26ae4e6c87e261ab81b8..038c067dc146b857abc55a4c9045e69ba3e74d52 100644
|
| --- a/src/x64/stub-cache-x64.cc
|
| +++ b/src/x64/stub-cache-x64.cc
|
| @@ -1593,247 +1593,6 @@ Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
|
| }
|
|
|
|
|
| -Handle<Code> CallStubCompiler::CompileArrayPushCall(
|
| - Handle<Object> object,
|
| - Handle<JSObject> holder,
|
| - Handle<Cell> cell,
|
| - Handle<JSFunction> function,
|
| - Handle<String> name,
|
| - Code::StubType type) {
|
| - // If object is not an array or is observed or sealed, bail out to regular
|
| - // call.
|
| - if (!object->IsJSArray() ||
|
| - !cell.is_null() ||
|
| - Handle<JSArray>::cast(object)->map()->is_observed() ||
|
| - !Handle<JSArray>::cast(object)->map()->is_extensible()) {
|
| - return Handle<Code>::null();
|
| - }
|
| -
|
| - Label miss;
|
| -
|
| - HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
|
| -
|
| - const int argc = arguments().immediate();
|
| - StackArgumentsAccessor args(rsp, argc);
|
| - if (argc == 0) {
|
| - // Noop, return the length.
|
| - __ movp(rax, FieldOperand(rdx, JSArray::kLengthOffset));
|
| - __ ret((argc + 1) * kPointerSize);
|
| - } else {
|
| - Label call_builtin;
|
| -
|
| - if (argc == 1) { // Otherwise fall through to call builtin.
|
| - Label attempt_to_grow_elements, with_write_barrier, check_double;
|
| -
|
| - // Get the elements array of the object.
|
| - __ movp(rdi, FieldOperand(rdx, JSArray::kElementsOffset));
|
| -
|
| - // Check that the elements are in fast mode and writable.
|
| - __ Cmp(FieldOperand(rdi, HeapObject::kMapOffset),
|
| - factory()->fixed_array_map());
|
| - __ j(not_equal, &check_double);
|
| -
|
| - // Get the array's length into rax and calculate new length.
|
| - __ SmiToInteger32(rax, FieldOperand(rdx, JSArray::kLengthOffset));
|
| - STATIC_ASSERT(FixedArray::kMaxLength < Smi::kMaxValue);
|
| - __ addl(rax, Immediate(argc));
|
| -
|
| - // Get the elements' length into rcx.
|
| - __ SmiToInteger32(rcx, FieldOperand(rdi, FixedArray::kLengthOffset));
|
| -
|
| - // Check if we could survive without allocation.
|
| - __ cmpl(rax, rcx);
|
| - __ j(greater, &attempt_to_grow_elements);
|
| -
|
| - // Check if value is a smi.
|
| - __ movp(rcx, args.GetArgumentOperand(1));
|
| - __ JumpIfNotSmi(rcx, &with_write_barrier);
|
| -
|
| - // Save new length.
|
| - __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax);
|
| -
|
| - // Store the value.
|
| - __ movp(FieldOperand(rdi,
|
| - rax,
|
| - times_pointer_size,
|
| - FixedArray::kHeaderSize - argc * kPointerSize),
|
| - rcx);
|
| -
|
| - __ Integer32ToSmi(rax, rax); // Return new length as smi.
|
| - __ ret((argc + 1) * kPointerSize);
|
| -
|
| - __ bind(&check_double);
|
| -
|
| - // Check that the elements are in double mode.
|
| - __ Cmp(FieldOperand(rdi, HeapObject::kMapOffset),
|
| - factory()->fixed_double_array_map());
|
| - __ j(not_equal, &call_builtin);
|
| -
|
| - // Get the array's length into rax and calculate new length.
|
| - __ SmiToInteger32(rax, FieldOperand(rdx, JSArray::kLengthOffset));
|
| - STATIC_ASSERT(FixedArray::kMaxLength < Smi::kMaxValue);
|
| - __ addl(rax, Immediate(argc));
|
| -
|
| - // Get the elements' length into rcx.
|
| - __ SmiToInteger32(rcx, FieldOperand(rdi, FixedArray::kLengthOffset));
|
| -
|
| - // Check if we could survive without allocation.
|
| - __ cmpl(rax, rcx);
|
| - __ j(greater, &call_builtin);
|
| -
|
| - __ movp(rcx, args.GetArgumentOperand(1));
|
| - __ StoreNumberToDoubleElements(
|
| - rcx, rdi, rax, xmm0, &call_builtin, argc * kDoubleSize);
|
| -
|
| - // Save new length.
|
| - __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax);
|
| - __ Integer32ToSmi(rax, rax); // Return new length as smi.
|
| - __ ret((argc + 1) * kPointerSize);
|
| -
|
| - __ bind(&with_write_barrier);
|
| -
|
| - __ movp(rbx, FieldOperand(rdx, HeapObject::kMapOffset));
|
| -
|
| - if (FLAG_smi_only_arrays && !FLAG_trace_elements_transitions) {
|
| - Label fast_object, not_fast_object;
|
| - __ CheckFastObjectElements(rbx, ¬_fast_object, Label::kNear);
|
| - __ jmp(&fast_object);
|
| - // In case of fast smi-only, convert to fast object, otherwise bail out.
|
| - __ bind(¬_fast_object);
|
| - __ CheckFastSmiElements(rbx, &call_builtin);
|
| - __ Cmp(FieldOperand(rcx, HeapObject::kMapOffset),
|
| - factory()->heap_number_map());
|
| - __ j(equal, &call_builtin);
|
| - // rdx: receiver
|
| - // rbx: map
|
| -
|
| - Label try_holey_map;
|
| - __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
|
| - FAST_ELEMENTS,
|
| - rbx,
|
| - rdi,
|
| - &try_holey_map);
|
| -
|
| - ElementsTransitionGenerator::
|
| - GenerateMapChangeElementsTransition(masm(),
|
| - DONT_TRACK_ALLOCATION_SITE,
|
| - NULL);
|
| - // Restore edi.
|
| - __ movp(rdi, FieldOperand(rdx, JSArray::kElementsOffset));
|
| - __ jmp(&fast_object);
|
| -
|
| - __ bind(&try_holey_map);
|
| - __ LoadTransitionedArrayMapConditional(FAST_HOLEY_SMI_ELEMENTS,
|
| - FAST_HOLEY_ELEMENTS,
|
| - rbx,
|
| - rdi,
|
| - &call_builtin);
|
| - ElementsTransitionGenerator::
|
| - GenerateMapChangeElementsTransition(masm(),
|
| - DONT_TRACK_ALLOCATION_SITE,
|
| - NULL);
|
| - __ movp(rdi, FieldOperand(rdx, JSArray::kElementsOffset));
|
| - __ bind(&fast_object);
|
| - } else {
|
| - __ CheckFastObjectElements(rbx, &call_builtin);
|
| - }
|
| -
|
| - // Save new length.
|
| - __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax);
|
| -
|
| - // Store the value.
|
| - __ lea(rdx, FieldOperand(rdi,
|
| - rax, times_pointer_size,
|
| - FixedArray::kHeaderSize - argc * kPointerSize));
|
| - __ movp(Operand(rdx, 0), rcx);
|
| -
|
| - __ RecordWrite(rdi, rdx, rcx, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
|
| - OMIT_SMI_CHECK);
|
| -
|
| - __ Integer32ToSmi(rax, rax); // Return new length as smi.
|
| - __ ret((argc + 1) * kPointerSize);
|
| -
|
| - __ bind(&attempt_to_grow_elements);
|
| - if (!FLAG_inline_new) {
|
| - __ jmp(&call_builtin);
|
| - }
|
| -
|
| - __ movp(rbx, args.GetArgumentOperand(1));
|
| - // Growing elements that are SMI-only requires special handling in case
|
| - // the new element is non-Smi. For now, delegate to the builtin.
|
| - Label no_fast_elements_check;
|
| - __ JumpIfSmi(rbx, &no_fast_elements_check);
|
| - __ movp(rcx, FieldOperand(rdx, HeapObject::kMapOffset));
|
| - __ CheckFastObjectElements(rcx, &call_builtin, Label::kFar);
|
| - __ bind(&no_fast_elements_check);
|
| -
|
| - ExternalReference new_space_allocation_top =
|
| - ExternalReference::new_space_allocation_top_address(isolate());
|
| - ExternalReference new_space_allocation_limit =
|
| - ExternalReference::new_space_allocation_limit_address(isolate());
|
| -
|
| - const int kAllocationDelta = 4;
|
| - // Load top.
|
| - __ Load(rcx, new_space_allocation_top);
|
| -
|
| - // Check if it's the end of elements.
|
| - __ lea(rdx, FieldOperand(rdi,
|
| - rax, times_pointer_size,
|
| - FixedArray::kHeaderSize - argc * kPointerSize));
|
| - __ cmpq(rdx, rcx);
|
| - __ j(not_equal, &call_builtin);
|
| - __ addq(rcx, Immediate(kAllocationDelta * kPointerSize));
|
| - Operand limit_operand =
|
| - masm()->ExternalOperand(new_space_allocation_limit);
|
| - __ cmpq(rcx, limit_operand);
|
| - __ j(above, &call_builtin);
|
| -
|
| - // We fit and could grow elements.
|
| - __ Store(new_space_allocation_top, rcx);
|
| -
|
| - // Push the argument...
|
| - __ movp(Operand(rdx, 0), rbx);
|
| - // ... and fill the rest with holes.
|
| - __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
|
| - for (int i = 1; i < kAllocationDelta; i++) {
|
| - __ movp(Operand(rdx, i * kPointerSize), kScratchRegister);
|
| - }
|
| -
|
| - // We know the elements array is in new space so we don't need the
|
| - // remembered set, but we just pushed a value onto it so we may have to
|
| - // tell the incremental marker to rescan the object that we just grew. We
|
| - // don't need to worry about the holes because they are in old space and
|
| - // already marked black.
|
| - __ RecordWrite(rdi, rdx, rbx, kDontSaveFPRegs, OMIT_REMEMBERED_SET);
|
| -
|
| - // Restore receiver to rdx as finish sequence assumes it's here.
|
| - __ movp(rdx, args.GetReceiverOperand());
|
| -
|
| - // Increment element's and array's sizes.
|
| - __ SmiAddConstant(FieldOperand(rdi, FixedArray::kLengthOffset),
|
| - Smi::FromInt(kAllocationDelta));
|
| -
|
| - // Make new length a smi before returning it.
|
| - __ Integer32ToSmi(rax, rax);
|
| - __ movp(FieldOperand(rdx, JSArray::kLengthOffset), rax);
|
| -
|
| - __ ret((argc + 1) * kPointerSize);
|
| - }
|
| -
|
| - __ bind(&call_builtin);
|
| - __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush,
|
| - isolate()),
|
| - argc + 1,
|
| - 1);
|
| - }
|
| -
|
| - HandlerFrontendFooter(&miss);
|
| -
|
| - // Return the generated code.
|
| - return GetCode(type, name);
|
| -}
|
| -
|
| -
|
| Handle<Code> CallStubCompiler::CompileFastApiCall(
|
| const CallOptimization& optimization,
|
| Handle<Object> object,
|
|
|