Commit a5fd3c14 authored by plind44@gmail.com's avatar plind44@gmail.com

MIPS: Reland v8:18458 "Load the global proxy from the context of the target function."

Port r18462 (7024b6d)

BUG=
R=plind44@gmail.com

Review URL: https://codereview.chromium.org/126043002

Patch from Balazs Kilvady <kilvadyb@homejinni.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18475 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent fc583434
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "deoptimizer.h" #include "deoptimizer.h"
#include "full-codegen.h" #include "full-codegen.h"
#include "runtime.h" #include "runtime.h"
#include "stub-cache.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -1116,11 +1117,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { ...@@ -1116,11 +1117,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
// Use the global receiver object from the called function as the // Use the global receiver object from the called function as the
// receiver. // receiver.
__ bind(&use_global_receiver); __ bind(&use_global_receiver);
const int kGlobalIndex = __ lw(a2, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
__ lw(a2, FieldMemOperand(cp, kGlobalIndex));
__ lw(a2, FieldMemOperand(a2, GlobalObject::kNativeContextOffset));
__ lw(a2, FieldMemOperand(a2, kGlobalIndex));
__ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset)); __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset));
__ bind(&patch_receiver); __ bind(&patch_receiver);
...@@ -1310,11 +1307,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { ...@@ -1310,11 +1307,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
// Use the current global receiver object as the receiver. // Use the current global receiver object as the receiver.
__ bind(&use_global_receiver); __ bind(&use_global_receiver);
const int kGlobalOffset = __ lw(a0, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
__ lw(a0, FieldMemOperand(cp, kGlobalOffset));
__ lw(a0, FieldMemOperand(a0, GlobalObject::kNativeContextOffset));
__ lw(a0, FieldMemOperand(a0, kGlobalOffset));
__ lw(a0, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset)); __ lw(a0, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset));
// Push the receiver. // Push the receiver.
......
...@@ -3328,32 +3328,48 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { ...@@ -3328,32 +3328,48 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
// a2 : cache cell for call target // a2 : cache cell for call target
Label slow, non_function; Label slow, non_function;
// Check that the function is really a JavaScript function.
// a1: pushed function (to be verified)
__ JumpIfSmi(a1, &non_function);
// The receiver might implicitly be the global object. This is // The receiver might implicitly be the global object. This is
// indicated by passing the hole as the receiver to the call // indicated by passing the hole as the receiver to the call
// function stub. // function stub.
if (ReceiverMightBeImplicit()) { if (ReceiverMightBeImplicit() || ReceiverIsImplicit()) {
Label call; Label try_call, call, patch_current_context;
// Get the receiver from the stack. if (ReceiverMightBeImplicit()) {
// function, receiver [, arguments] // Get the receiver from the stack.
__ lw(t0, MemOperand(sp, argc_ * kPointerSize)); // function, receiver [, arguments]
// Call as function is indicated with the hole. __ lw(t0, MemOperand(sp, argc_ * kPointerSize));
__ LoadRoot(at, Heap::kTheHoleValueRootIndex); // Call as function is indicated with the hole.
__ Branch(&call, ne, t0, Operand(at)); __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
__ Branch(&try_call, ne, t0, Operand(at));
}
// Patch the receiver on the stack with the global receiver object. // Patch the receiver on the stack with the global receiver object.
__ lw(a3, // Goto slow case if we do not have a function.
MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); __ GetObjectType(a1, a3, a3);
__ lw(a3, FieldMemOperand(a3, GlobalObject::kGlobalReceiverOffset)); __ Branch(&patch_current_context, ne, a3, Operand(JS_FUNCTION_TYPE));
CallStubCompiler::FetchGlobalProxy(masm, a3, a1);
__ sw(a3, MemOperand(sp, argc_ * kPointerSize)); __ sw(a3, MemOperand(sp, argc_ * kPointerSize));
__ Branch(&call);
__ bind(&patch_current_context);
__ LoadRoot(t0, Heap::kUndefinedValueRootIndex);
__ sw(t0, MemOperand(sp, argc_ * kPointerSize));
__ Branch(&slow);
__ bind(&try_call);
// Get the map of the function object.
__ GetObjectType(a1, a3, a3);
__ Branch(&slow, ne, a3, Operand(JS_FUNCTION_TYPE));
__ bind(&call); __ bind(&call);
} else {
// Get the map of the function object.
__ GetObjectType(a1, a3, a3);
__ Branch(&slow, ne, a3, Operand(JS_FUNCTION_TYPE));
} }
// Check that the function is really a JavaScript function.
// a1: pushed function (to be verified)
__ JumpIfSmi(a1, &non_function);
// Get the map of the function object.
__ GetObjectType(a1, a3, a3);
__ Branch(&slow, ne, a3, Operand(JS_FUNCTION_TYPE));
if (RecordCallTarget()) { if (RecordCallTarget()) {
GenerateRecordCallTarget(masm); GenerateRecordCallTarget(masm);
} }
...@@ -3396,7 +3412,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { ...@@ -3396,7 +3412,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
__ li(a0, Operand(argc_ + 1, RelocInfo::NONE32)); __ li(a0, Operand(argc_ + 1, RelocInfo::NONE32));
__ li(a2, Operand(0, RelocInfo::NONE32)); __ li(a2, Operand(0, RelocInfo::NONE32));
__ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY); __ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY);
__ SetCallKind(t1, CALL_AS_METHOD); __ SetCallKind(t1, CALL_AS_FUNCTION);
{ {
Handle<Code> adaptor = Handle<Code> adaptor =
masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
......
...@@ -2836,12 +2836,12 @@ void FullCodeGenerator::VisitCall(Call* expr) { ...@@ -2836,12 +2836,12 @@ void FullCodeGenerator::VisitCall(Call* expr) {
{ PreservePositionScope scope(masm()->positions_recorder()); { PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(callee); VisitForStackValue(callee);
} }
// Load global receiver object. // Push the hole as receiver.
__ lw(a1, GlobalObjectOperand()); // It will be correctly replaced in the call stub.
__ lw(a1, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset)); __ LoadRoot(a1, Heap::kTheHoleValueRootIndex);
__ push(a1); __ push(a1);
// Emit function call. // Emit function call.
EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); EmitCallWithStub(expr, RECEIVER_IS_IMPLICIT);
} }
#ifdef DEBUG #ifdef DEBUG
......
...@@ -493,7 +493,7 @@ void CallICBase::GenerateMiss(MacroAssembler* masm, ...@@ -493,7 +493,7 @@ void CallICBase::GenerateMiss(MacroAssembler* masm,
// Patch the receiver on the stack. // Patch the receiver on the stack.
__ bind(&global); __ bind(&global);
__ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset)); CallStubCompiler::FetchGlobalProxy(masm, a2, a1);
__ sw(a2, MemOperand(sp, argc * kPointerSize)); __ sw(a2, MemOperand(sp, argc * kPointerSize));
__ bind(&invoke); __ bind(&invoke);
} }
......
...@@ -3370,11 +3370,8 @@ void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { ...@@ -3370,11 +3370,8 @@ void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
__ Branch(&result_in_receiver); __ Branch(&result_in_receiver);
__ bind(&global_object); __ bind(&global_object);
CallStubCompiler::FetchGlobalProxy(masm(), receiver, function);
__ lw(result, MemOperand(fp, StandardFrameConstants::kContextOffset));
__ lw(result, ContextOperand(result, Context::GLOBAL_OBJECT_INDEX));
__ lw(result,
FieldMemOperand(result, JSGlobalObject::kGlobalReceiverOffset));
if (result.is(receiver)) { if (result.is(receiver)) {
__ bind(&result_in_receiver); __ bind(&result_in_receiver);
} else { } else {
...@@ -3917,7 +3914,10 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) { ...@@ -3917,7 +3914,10 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
ASSERT(ToRegister(instr->result()).is(v0)); ASSERT(ToRegister(instr->result()).is(v0));
int arity = instr->arity(); int arity = instr->arity();
CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS); CallFunctionFlags flags =
instr->hydrogen()->IsContextualCall() ?
RECEIVER_IS_IMPLICIT : NO_CALL_FUNCTION_FLAGS;
CallFunctionStub stub(arity, flags);
if (instr->hydrogen()->IsTailCall()) { if (instr->hydrogen()->IsTailCall()) {
if (NeedsEagerFrame()) __ mov(sp, fp); if (NeedsEagerFrame()) __ mov(sp, fp);
__ Jump(stub.GetCode(isolate()), RelocInfo::CODE_TARGET); __ Jump(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
......
...@@ -2337,11 +2337,23 @@ void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { ...@@ -2337,11 +2337,23 @@ void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
} }
void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) { void CallStubCompiler::PatchGlobalProxy(Handle<Object> object,
Handle<JSFunction> function) {
if (object->IsGlobalObject()) { if (object->IsGlobalObject()) {
const int argc = arguments().immediate(); const int argc = arguments().immediate();
const int receiver_offset = argc * kPointerSize; const int receiver_offset = argc * kPointerSize;
__ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset)); __ li(a3, handle(function->context()->global_proxy()));
__ sw(a3, MemOperand(sp, receiver_offset));
}
}
void CallStubCompiler::PatchGlobalProxy(Handle<Object> object,
Register function) {
if (object->IsGlobalObject()) {
FetchGlobalProxy(masm(), a3, function);
const int argc = arguments().immediate();
const int receiver_offset = argc * kPointerSize;
__ sw(a3, MemOperand(sp, receiver_offset)); __ sw(a3, MemOperand(sp, receiver_offset));
} }
} }
...@@ -2440,7 +2452,7 @@ void CallStubCompiler::GenerateJumpFunction(Handle<Object> object, ...@@ -2440,7 +2452,7 @@ void CallStubCompiler::GenerateJumpFunction(Handle<Object> object,
ASSERT(function.is(a1)); ASSERT(function.is(a1));
// Check that the function really is a function. // Check that the function really is a function.
GenerateFunctionCheck(function, a3, miss); GenerateFunctionCheck(function, a3, miss);
PatchGlobalProxy(object); PatchGlobalProxy(object, function);
// Invoke the function. // Invoke the function.
__ InvokeFunction(a1, arguments(), JUMP_FUNCTION, __ InvokeFunction(a1, arguments(), JUMP_FUNCTION,
NullCallWrapper(), call_kind()); NullCallWrapper(), call_kind());
...@@ -2558,6 +2570,15 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback( ...@@ -2558,6 +2570,15 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
#define __ ACCESS_MASM(masm) #define __ ACCESS_MASM(masm)
void CallStubCompiler::FetchGlobalProxy(MacroAssembler* masm,
Register target,
Register function) {
__ lw(target, FieldMemOperand(function, JSFunction::kContextOffset));
__ lw(target, ContextOperand(target, Context::GLOBAL_OBJECT_INDEX));
__ lw(target, FieldMemOperand(target, GlobalObject::kGlobalReceiverOffset));
}
void StoreStubCompiler::GenerateStoreViaSetter( void StoreStubCompiler::GenerateStoreViaSetter(
MacroAssembler* masm, MacroAssembler* masm,
Handle<JSFunction> setter) { Handle<JSFunction> setter) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment