| Index: src/mips/lithium-codegen-mips.cc
|
| diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
|
| index ac8c04a49debda1aa7037fa0c0f434f00ddee8a0..0d2863aad9d90498aabdcf408c5cb4d42da25473 100644
|
| --- a/src/mips/lithium-codegen-mips.cc
|
| +++ b/src/mips/lithium-codegen-mips.cc
|
| @@ -1,4 +1,4 @@
|
| -// Copyright 2012 the V8 project authors. All rights reserved.
|
| +// Copyright 2012 the V8 project authors. All rights reserved.7
|
| // Redistribution and use in source and binary forms, with or without
|
| // modification, are permitted provided that the following conditions are
|
| // met:
|
| @@ -146,17 +146,23 @@ bool LCodeGen::GeneratePrologue() {
|
| // fp: Caller's frame pointer.
|
| // lr: Caller's pc.
|
|
|
| - // Strict mode functions and builtins need to replace the receiver
|
| - // with undefined when called as functions (without an explicit
|
| - // receiver object). r5 is zero for method calls and non-zero for
|
| - // function calls.
|
| - if (!info_->is_classic_mode() || info_->is_native()) {
|
| + // Classic mode functions and builtins need to replace the receiver with the
|
| + // global proxy when called as functions (without an explicit receiver
|
| + // object).
|
| + if (info_->this_has_uses() &&
|
| + info_->is_classic_mode() &&
|
| + !info_->is_native()) {
|
| Label ok;
|
| - __ Branch(&ok, eq, t1, Operand(zero_reg));
|
| + int receiver_offset = info_->scope()->num_parameters() * kPointerSize;
|
| + __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
|
| + __ lw(a2, MemOperand(sp, receiver_offset));
|
| + __ Branch(&ok, ne, a2, Operand(at));
|
| +
|
| + __ lw(a2, GlobalObjectOperand());
|
| + __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset));
|
|
|
| - int receiver_offset = scope()->num_parameters() * kPointerSize;
|
| - __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
|
| __ sw(a2, MemOperand(sp, receiver_offset));
|
| +
|
| __ bind(&ok);
|
| }
|
| }
|
| @@ -686,7 +692,6 @@ void LCodeGen::CallCodeGeneric(Handle<Code> code,
|
| RelocInfo::Mode mode,
|
| LInstruction* instr,
|
| SafepointMode safepoint_mode) {
|
| - EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
|
| ASSERT(instr != NULL);
|
| __ Call(code, mode);
|
| RecordSafepointWithLazyDeopt(instr, safepoint_mode);
|
| @@ -3370,7 +3375,11 @@ void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
|
| __ Branch(&result_in_receiver);
|
|
|
| __ bind(&global_object);
|
| - CallStubCompiler::FetchGlobalProxy(masm(), receiver, function);
|
| + __ lw(receiver, FieldMemOperand(function, JSFunction::kContextOffset));
|
| + __ lw(receiver,
|
| + ContextOperand(receiver, Context::GLOBAL_OBJECT_INDEX));
|
| + __ lw(receiver,
|
| + FieldMemOperand(receiver, GlobalObject::kGlobalReceiverOffset));
|
|
|
| if (result.is(receiver)) {
|
| __ bind(&result_in_receiver);
|
| @@ -3428,8 +3437,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
|
| // The number of arguments is stored in receiver which is a0, as expected
|
| // by InvokeFunction.
|
| ParameterCount actual(receiver);
|
| - __ InvokeFunction(function, actual, CALL_FUNCTION,
|
| - safepoint_generator, CALL_AS_METHOD);
|
| + __ InvokeFunction(function, actual, CALL_FUNCTION, safepoint_generator);
|
| }
|
|
|
|
|
| @@ -3503,7 +3511,6 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
|
| int formal_parameter_count,
|
| int arity,
|
| LInstruction* instr,
|
| - CallKind call_kind,
|
| A1State a1_state) {
|
| bool dont_adapt_arguments =
|
| formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel;
|
| @@ -3527,7 +3534,6 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
|
| }
|
|
|
| // Invoke function.
|
| - __ SetCallKind(t1, call_kind);
|
| __ lw(at, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
|
| __ Call(at);
|
|
|
| @@ -3537,24 +3543,11 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
|
| SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
|
| ParameterCount count(arity);
|
| ParameterCount expected(formal_parameter_count);
|
| - __ InvokeFunction(
|
| - function, expected, count, CALL_FUNCTION, generator, call_kind);
|
| + __ InvokeFunction(function, expected, count, CALL_FUNCTION, generator);
|
| }
|
| }
|
|
|
|
|
| -void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
|
| - ASSERT(ToRegister(instr->result()).is(v0));
|
| - __ mov(a0, v0);
|
| - CallKnownFunction(instr->hydrogen()->function(),
|
| - instr->hydrogen()->formal_parameter_count(),
|
| - instr->arity(),
|
| - instr,
|
| - CALL_AS_METHOD,
|
| - A1_UNINITIALIZED);
|
| -}
|
| -
|
| -
|
| void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
|
| ASSERT(instr->context() != NULL);
|
| ASSERT(ToRegister(instr->context()).is(cp));
|
| @@ -3873,38 +3866,55 @@ void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
|
| LPointerMap* pointers = instr->pointer_map();
|
| SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
|
| ParameterCount count(instr->arity());
|
| - __ InvokeFunction(a1, count, CALL_FUNCTION, generator, CALL_AS_METHOD);
|
| + __ InvokeFunction(a1, count, CALL_FUNCTION, generator);
|
| } else {
|
| CallKnownFunction(known_function,
|
| instr->hydrogen()->formal_parameter_count(),
|
| instr->arity(),
|
| instr,
|
| - CALL_AS_METHOD,
|
| A1_CONTAINS_TARGET);
|
| }
|
| }
|
|
|
|
|
| -void LCodeGen::DoCallKeyed(LCallKeyed* instr) {
|
| - ASSERT(ToRegister(instr->context()).is(cp));
|
| +void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
|
| ASSERT(ToRegister(instr->result()).is(v0));
|
|
|
| - int arity = instr->arity();
|
| - Handle<Code> ic =
|
| - isolate()->stub_cache()->ComputeKeyedCallInitialize(arity);
|
| - CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
| + LPointerMap* pointers = instr->pointer_map();
|
| + SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
|
| +
|
| + if (instr->target()->IsConstantOperand()) {
|
| + LConstantOperand* target = LConstantOperand::cast(instr->target());
|
| + Handle<Code> code = Handle<Code>::cast(ToHandle(target));
|
| + generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET));
|
| + __ Call(code, RelocInfo::CODE_TARGET);
|
| + } else {
|
| + ASSERT(instr->target()->IsRegister());
|
| + Register target = ToRegister(instr->target());
|
| + generator.BeforeCall(__ CallSize(target));
|
| + __ Addu(target, target, Operand(Code::kHeaderSize - kHeapObjectTag));
|
| + __ Call(target);
|
| + }
|
| + generator.AfterCall();
|
| }
|
|
|
|
|
| -void LCodeGen::DoCallNamed(LCallNamed* instr) {
|
| - ASSERT(ToRegister(instr->context()).is(cp));
|
| +void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) {
|
| + ASSERT(ToRegister(instr->function()).is(a1));
|
| ASSERT(ToRegister(instr->result()).is(v0));
|
|
|
| - int arity = instr->arity();
|
| - Handle<Code> ic =
|
| - isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_CONTEXTUAL);
|
| - __ li(a2, Operand(instr->name()));
|
| - CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
| + if (instr->hydrogen()->pass_argument_count()) {
|
| + __ li(a0, Operand(instr->arity()));
|
| + }
|
| +
|
| + // Change context.
|
| + __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
|
| +
|
| + // Load the code entry address
|
| + __ lw(at, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
|
| + __ Call(at);
|
| +
|
| + RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
|
| }
|
|
|
|
|
| @@ -3914,10 +3924,7 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
|
| ASSERT(ToRegister(instr->result()).is(v0));
|
|
|
| int arity = instr->arity();
|
| - CallFunctionFlags flags =
|
| - instr->hydrogen()->IsContextualCall() ?
|
| - RECEIVER_IS_IMPLICIT : NO_CALL_FUNCTION_FLAGS;
|
| - CallFunctionStub stub(arity, flags);
|
| + CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS);
|
| if (instr->hydrogen()->IsTailCall()) {
|
| if (NeedsEagerFrame()) __ mov(sp, fp);
|
| __ Jump(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
|
| @@ -3927,29 +3934,6 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
|
| }
|
|
|
|
|
| -void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
|
| - ASSERT(ToRegister(instr->context()).is(cp));
|
| - ASSERT(ToRegister(instr->result()).is(v0));
|
| -
|
| - int arity = instr->arity();
|
| - Handle<Code> ic =
|
| - isolate()->stub_cache()->ComputeCallInitialize(arity, CONTEXTUAL);
|
| - __ li(a2, Operand(instr->name()));
|
| - CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
| -}
|
| -
|
| -
|
| -void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
|
| - ASSERT(ToRegister(instr->result()).is(v0));
|
| - CallKnownFunction(instr->hydrogen()->target(),
|
| - instr->hydrogen()->formal_parameter_count(),
|
| - instr->arity(),
|
| - instr,
|
| - CALL_AS_FUNCTION,
|
| - A1_UNINITIALIZED);
|
| -}
|
| -
|
| -
|
| void LCodeGen::DoCallNew(LCallNew* instr) {
|
| ASSERT(ToRegister(instr->context()).is(cp));
|
| ASSERT(ToRegister(instr->constructor()).is(a1));
|
| @@ -5127,7 +5111,7 @@ void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
|
| PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
|
| __ push(object);
|
| __ mov(cp, zero_reg);
|
| - __ CallRuntimeSaveDoubles(Runtime::kMigrateInstance);
|
| + __ CallRuntimeSaveDoubles(Runtime::kTryMigrateInstance);
|
| RecordSafepointWithRegisters(
|
| instr->pointer_map(), 1, Safepoint::kNoLazyDeopt);
|
| __ StoreToSafepointRegisterSlot(v0, scratch0());
|
| @@ -5590,24 +5574,25 @@ void LCodeGen::EmitIsConstructCall(Register temp1, Register temp2) {
|
|
|
|
|
| void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) {
|
| - if (info()->IsStub()) return;
|
| - // Ensure that we have enough space after the previous lazy-bailout
|
| - // instruction for patching the code here.
|
| - int current_pc = masm()->pc_offset();
|
| - if (current_pc < last_lazy_deopt_pc_ + space_needed) {
|
| - int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
|
| - ASSERT_EQ(0, padding_size % Assembler::kInstrSize);
|
| - while (padding_size > 0) {
|
| - __ nop();
|
| - padding_size -= Assembler::kInstrSize;
|
| + if (!info()->IsStub()) {
|
| + // Ensure that we have enough space after the previous lazy-bailout
|
| + // instruction for patching the code here.
|
| + int current_pc = masm()->pc_offset();
|
| + if (current_pc < last_lazy_deopt_pc_ + space_needed) {
|
| + int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
|
| + ASSERT_EQ(0, padding_size % Assembler::kInstrSize);
|
| + while (padding_size > 0) {
|
| + __ nop();
|
| + padding_size -= Assembler::kInstrSize;
|
| + }
|
| }
|
| }
|
| + last_lazy_deopt_pc_ = masm()->pc_offset();
|
| }
|
|
|
|
|
| void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
|
| EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
|
| - last_lazy_deopt_pc_ = masm()->pc_offset();
|
| ASSERT(instr->HasEnvironment());
|
| LEnvironment* env = instr->environment();
|
| RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
|
| @@ -5680,7 +5665,6 @@ void LCodeGen::DoStackCheck(LStackCheck* instr) {
|
| RelocInfo::CODE_TARGET,
|
| instr);
|
| EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
|
| - last_lazy_deopt_pc_ = masm()->pc_offset();
|
| __ bind(&done);
|
| RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
|
| safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
|
| @@ -5692,7 +5676,6 @@ void LCodeGen::DoStackCheck(LStackCheck* instr) {
|
| __ LoadRoot(at, Heap::kStackLimitRootIndex);
|
| __ Branch(deferred_stack_check->entry(), lo, sp, Operand(at));
|
| EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
|
| - last_lazy_deopt_pc_ = masm()->pc_offset();
|
| __ bind(instr->done_label());
|
| deferred_stack_check->SetExit(instr->done_label());
|
| RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
|
|
|