| Index: src/s390/builtins-s390.cc
|
| diff --git a/src/s390/builtins-s390.cc b/src/s390/builtins-s390.cc
|
| index fba87e544635b1718c549d574490f5bcb3ea0e06..99520db106a20ad120e72b683b257033c1fd29cb 100644
|
| --- a/src/s390/builtins-s390.cc
|
| +++ b/src/s390/builtins-s390.cc
|
| @@ -521,6 +521,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
|
| // -- r3 : constructor function
|
| // -- r4 : allocation site or undefined
|
| // -- r5 : new target
|
| + // -- cp : context
|
| // -- lr : return address
|
| // -- sp[...]: constructor arguments
|
| // -----------------------------------
|
| @@ -537,11 +538,11 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
|
| if (!create_implicit_receiver) {
|
| __ SmiTag(r6, r2);
|
| __ LoadAndTestP(r6, r6);
|
| - __ Push(r4, r6);
|
| + __ Push(cp, r4, r6);
|
| __ PushRoot(Heap::kTheHoleValueRootIndex);
|
| } else {
|
| __ SmiTag(r2);
|
| - __ Push(r4, r2);
|
| + __ Push(cp, r4, r2);
|
|
|
| // Allocate the new receiver object.
|
| __ Push(r3, r5);
|
| @@ -614,7 +615,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
|
| // r2: result
|
| // sp[0]: receiver
|
| // sp[1]: number of arguments (smi-tagged)
|
| - __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
| + __ LoadP(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset));
|
|
|
| if (create_implicit_receiver) {
|
| // If the result is an object (in the ECMA sense), we should get rid
|
| @@ -738,9 +739,6 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
|
| // r0,r7-r9, cp may be clobbered
|
| ProfileEntryHookStub::MaybeCallEntryHook(masm);
|
|
|
| - // Clear the context before we push it when entering the internal frame.
|
| - __ LoadImmP(cp, Operand::Zero());
|
| -
|
| // Enter an internal frame.
|
| {
|
| // FrameScope ends up calling MacroAssembler::EnterFrame here
|
| @@ -841,14 +839,24 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
| // MANUAL indicates that the scope shouldn't actually generate code to set up
|
| // the frame (that is done below).
|
| FrameScope frame_scope(masm, StackFrame::MANUAL);
|
| - __ PushFixedFrame(r3);
|
| - __ AddP(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
|
| + __ PushStandardFrame(r3);
|
|
|
| // Get the bytecode array from the function object and load the pointer to the
|
| // first entry into kInterpreterBytecodeRegister.
|
| __ LoadP(r2, FieldMemOperand(r3, JSFunction::kSharedFunctionInfoOffset));
|
| + Label array_done;
|
| + Register debug_info = r4;
|
| + DCHECK(!debug_info.is(r2));
|
| + __ LoadP(debug_info,
|
| + FieldMemOperand(r2, SharedFunctionInfo::kDebugInfoOffset));
|
| + // Load original bytecode array or the debug copy.
|
| __ LoadP(kInterpreterBytecodeArrayRegister,
|
| FieldMemOperand(r2, SharedFunctionInfo::kFunctionDataOffset));
|
| + __ CmpSmiLiteral(debug_info, DebugInfo::uninitialized(), r0);
|
| + __ beq(&array_done);
|
| + __ LoadP(kInterpreterBytecodeArrayRegister,
|
| + FieldMemOperand(debug_info, DebugInfo::kAbstractCodeIndex));
|
| + __ bind(&array_done);
|
|
|
| if (FLAG_debug_code) {
|
| // Check function data field is actually a BytecodeArray object.
|
| @@ -1178,8 +1186,7 @@ void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) {
|
| __ LoadRR(ip, r2);
|
|
|
| // Perform prologue operations usually performed by the young code stub.
|
| - __ PushFixedFrame(r3);
|
| - __ la(fp, MemOperand(sp, StandardFrameConstants::kFixedFrameSizeFromFp));
|
| + __ PushStandardFrame(r3);
|
|
|
| // Jump to point after the code-age stub.
|
| __ AddP(r2, ip, Operand(kNoCodeAgeSequenceLength));
|
| @@ -1932,7 +1939,8 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
|
| // Drop possible interpreter handler/stub frame.
|
| {
|
| Label no_interpreter_frame;
|
| - __ LoadP(scratch3, MemOperand(fp, StandardFrameConstants::kMarkerOffset));
|
| + __ LoadP(scratch3,
|
| + MemOperand(fp, CommonFrameConstants::kContextOrFrameTypeOffset));
|
| __ CmpSmiLiteral(scratch3, Smi::FromInt(StackFrame::STUB), r0);
|
| __ bne(&no_interpreter_frame);
|
| __ LoadP(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
| @@ -1940,80 +1948,40 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
|
| }
|
|
|
| // Check if next frame is an arguments adaptor frame.
|
| + Register caller_args_count_reg = scratch1;
|
| Label no_arguments_adaptor, formal_parameter_count_loaded;
|
| __ LoadP(scratch2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
| - __ LoadP(scratch3,
|
| - MemOperand(scratch2, StandardFrameConstants::kContextOffset));
|
| + __ LoadP(
|
| + scratch3,
|
| + MemOperand(scratch2, CommonFrameConstants::kContextOrFrameTypeOffset));
|
| __ CmpSmiLiteral(scratch3, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0);
|
| __ bne(&no_arguments_adaptor);
|
|
|
| - // Drop arguments adaptor frame and load arguments count.
|
| + // Drop current frame and load arguments count from arguments adaptor frame.
|
| __ LoadRR(fp, scratch2);
|
| - __ LoadP(scratch1,
|
| + __ LoadP(caller_args_count_reg,
|
| MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
| - __ SmiUntag(scratch1);
|
| + __ SmiUntag(caller_args_count_reg);
|
| __ b(&formal_parameter_count_loaded);
|
|
|
| __ bind(&no_arguments_adaptor);
|
| // Load caller's formal parameter count
|
| - __ LoadP(scratch1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
|
| + __ LoadP(scratch1,
|
| + MemOperand(fp, ArgumentsAdaptorFrameConstants::kFunctionOffset));
|
| __ LoadP(scratch1,
|
| FieldMemOperand(scratch1, JSFunction::kSharedFunctionInfoOffset));
|
| - __ LoadW(scratch1,
|
| + __ LoadW(caller_args_count_reg,
|
| FieldMemOperand(scratch1,
|
| SharedFunctionInfo::kFormalParameterCountOffset));
|
| #if !V8_TARGET_ARCH_S390X
|
| - __ SmiUntag(scratch1);
|
| + __ SmiUntag(caller_args_count_reg);
|
| #endif
|
|
|
| __ bind(&formal_parameter_count_loaded);
|
|
|
| - // Calculate the end of destination area where we will put the arguments
|
| - // after we drop current frame. We AddP kPointerSize to count the receiver
|
| - // argument which is not included into formal parameters count.
|
| - Register dst_reg = scratch2;
|
| - __ ShiftLeftP(dst_reg, scratch1, Operand(kPointerSizeLog2));
|
| - __ AddP(dst_reg, fp, dst_reg);
|
| - __ AddP(dst_reg, dst_reg,
|
| - Operand(StandardFrameConstants::kCallerSPOffset + kPointerSize));
|
| -
|
| - Register src_reg = scratch1;
|
| - __ ShiftLeftP(src_reg, args_reg, Operand(kPointerSizeLog2));
|
| - __ AddP(src_reg, sp, src_reg);
|
| - // Count receiver argument as well (not included in args_reg).
|
| - __ AddP(src_reg, src_reg, Operand(kPointerSize));
|
| -
|
| - if (FLAG_debug_code) {
|
| - __ CmpLogicalP(src_reg, dst_reg);
|
| - __ Check(lt, kStackAccessBelowStackPointer);
|
| - }
|
| -
|
| - // Restore caller's frame pointer and return address now as they will be
|
| - // overwritten by the copying loop.
|
| - __ RestoreFrameStateForTailCall();
|
| -
|
| - // Now copy callee arguments to the caller frame going backwards to avoid
|
| - // callee arguments corruption (source and destination areas could overlap).
|
| -
|
| - // Both src_reg and dst_reg are pointing to the word after the one to copy,
|
| - // so they must be pre-decremented in the loop.
|
| - Register tmp_reg = scratch3;
|
| - Label loop;
|
| - DCHECK(!src_reg.is(r1));
|
| - DCHECK(!dst_reg.is(r1));
|
| - DCHECK(!tmp_reg.is(r1));
|
| -
|
| - __ AddP(r1, args_reg, Operand(1)); // +1 for receiver
|
| - __ bind(&loop);
|
| - __ lay(src_reg, MemOperand(src_reg, -kPointerSize));
|
| - __ LoadP(tmp_reg, MemOperand(src_reg));
|
| - __ lay(dst_reg, MemOperand(dst_reg, -kPointerSize));
|
| - __ StoreP(tmp_reg, MemOperand(dst_reg));
|
| - __ BranchOnCount(r1, &loop);
|
| -
|
| - // Leave current frame.
|
| - __ LoadRR(sp, dst_reg);
|
| -
|
| + ParameterCount callee_args_count(args_reg);
|
| + __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
|
| + scratch3);
|
| __ bind(&done);
|
| }
|
| } // namespace
|
| @@ -2261,6 +2229,12 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode,
|
| __ CmpP(r7, Operand(JS_BOUND_FUNCTION_TYPE));
|
| __ Jump(masm->isolate()->builtins()->CallBoundFunction(tail_call_mode),
|
| RelocInfo::CODE_TARGET, eq);
|
| +
|
| + // Check if target has a [[Call]] internal method.
|
| + __ LoadlB(r6, FieldMemOperand(r6, Map::kBitFieldOffset));
|
| + __ TestBit(r6, Map::kIsCallable);
|
| + __ beq(&non_callable);
|
| +
|
| __ CmpP(r7, Operand(JS_PROXY_TYPE));
|
| __ bne(&non_function);
|
|
|
| @@ -2281,10 +2255,6 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode,
|
| // 2. Call to something else, which might have a [[Call]] internal method (if
|
| // not we raise an exception).
|
| __ bind(&non_function);
|
| - // Check if target has a [[Call]] internal method.
|
| - __ LoadlB(r6, FieldMemOperand(r6, Map::kBitFieldOffset));
|
| - __ TestBit(r6, Map::kIsCallable, r0);
|
| - __ beq(&non_callable);
|
| // Overwrite the original receiver the (original) target.
|
| __ ShiftLeftP(r7, r2, Operand(kPointerSizeLog2));
|
| __ StoreP(r3, MemOperand(sp, r7));
|
|
|