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 @@
#include "deoptimizer.h"
#include "full-codegen.h"
#include "runtime.h"
#include "stub-cache.h"
namespace v8 {
namespace internal {
......@@ -1116,11 +1117,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
// Use the global receiver object from the called function as the
// receiver.
__ bind(&use_global_receiver);
const int kGlobalIndex =
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, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
__ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset));
__ bind(&patch_receiver);
......@@ -1310,11 +1307,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
// Use the current global receiver object as the receiver.
__ bind(&use_global_receiver);
const int kGlobalOffset =
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, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
__ lw(a0, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset));
// Push the receiver.
......
......@@ -3328,32 +3328,48 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
// a2 : cache cell for call target
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
// indicated by passing the hole as the receiver to the call
// function stub.
if (ReceiverMightBeImplicit()) {
Label call;
// Get the receiver from the stack.
// function, receiver [, arguments]
__ lw(t0, MemOperand(sp, argc_ * kPointerSize));
// Call as function is indicated with the hole.
__ LoadRoot(at, Heap::kTheHoleValueRootIndex);
__ Branch(&call, ne, t0, Operand(at));
if (ReceiverMightBeImplicit() || ReceiverIsImplicit()) {
Label try_call, call, patch_current_context;
if (ReceiverMightBeImplicit()) {
// Get the receiver from the stack.
// function, receiver [, arguments]
__ lw(t0, MemOperand(sp, argc_ * kPointerSize));
// Call as function is indicated with the hole.
__ LoadRoot(at, Heap::kTheHoleValueRootIndex);
__ Branch(&try_call, ne, t0, Operand(at));
}
// Patch the receiver on the stack with the global receiver object.
__ lw(a3,
MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
__ lw(a3, FieldMemOperand(a3, GlobalObject::kGlobalReceiverOffset));
// Goto slow case if we do not have a function.
__ GetObjectType(a1, a3, a3);
__ Branch(&patch_current_context, ne, a3, Operand(JS_FUNCTION_TYPE));
CallStubCompiler::FetchGlobalProxy(masm, a3, a1);
__ 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);
} 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()) {
GenerateRecordCallTarget(masm);
}
......@@ -3396,7 +3412,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
__ li(a0, Operand(argc_ + 1, RelocInfo::NONE32));
__ li(a2, Operand(0, RelocInfo::NONE32));
__ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY);
__ SetCallKind(t1, CALL_AS_METHOD);
__ SetCallKind(t1, CALL_AS_FUNCTION);
{
Handle<Code> adaptor =
masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
......
......@@ -2836,12 +2836,12 @@ void FullCodeGenerator::VisitCall(Call* expr) {
{ PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(callee);
}
// Load global receiver object.
__ lw(a1, GlobalObjectOperand());
__ lw(a1, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset));
// Push the hole as receiver.
// It will be correctly replaced in the call stub.
__ LoadRoot(a1, Heap::kTheHoleValueRootIndex);
__ push(a1);
// Emit function call.
EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS);
EmitCallWithStub(expr, RECEIVER_IS_IMPLICIT);
}
#ifdef DEBUG
......
......@@ -493,7 +493,7 @@ void CallICBase::GenerateMiss(MacroAssembler* masm,
// Patch the receiver on the stack.
__ bind(&global);
__ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset));
CallStubCompiler::FetchGlobalProxy(masm, a2, a1);
__ sw(a2, MemOperand(sp, argc * kPointerSize));
__ bind(&invoke);
}
......
......@@ -3370,11 +3370,8 @@ void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
__ Branch(&result_in_receiver);
__ 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)) {
__ bind(&result_in_receiver);
} else {
......@@ -3917,7 +3914,10 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
ASSERT(ToRegister(instr->result()).is(v0));
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 (NeedsEagerFrame()) __ mov(sp, fp);
__ Jump(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
......
......@@ -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()) {
const int argc = arguments().immediate();
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));
}
}
......@@ -2440,7 +2452,7 @@ void CallStubCompiler::GenerateJumpFunction(Handle<Object> object,
ASSERT(function.is(a1));
// Check that the function really is a function.
GenerateFunctionCheck(function, a3, miss);
PatchGlobalProxy(object);
PatchGlobalProxy(object, function);
// Invoke the function.
__ InvokeFunction(a1, arguments(), JUMP_FUNCTION,
NullCallWrapper(), call_kind());
......@@ -2558,6 +2570,15 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
#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(
MacroAssembler* masm,
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