Index: src/mips/macro-assembler-mips.cc |
=================================================================== |
--- src/mips/macro-assembler-mips.cc (revision 9277) |
+++ src/mips/macro-assembler-mips.cc (working copy) |
@@ -42,7 +42,8 @@ |
MacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size) |
: Assembler(arg_isolate, buffer, size), |
generating_stub_(false), |
- allow_stub_calls_(true) { |
+ allow_stub_calls_(true), |
+ has_frame_(false) { |
if (isolate() != NULL) { |
code_object_ = Handle<Object>(isolate()->heap()->undefined_value(), |
isolate()); |
@@ -2306,10 +2307,10 @@ |
#ifdef ENABLE_DEBUGGER_SUPPORT |
void MacroAssembler::DebugBreak() { |
- ASSERT(allow_stub_calls()); |
mov(a0, zero_reg); |
li(a1, Operand(ExternalReference(Runtime::kDebugBreak, isolate()))); |
CEntryStub ces(1); |
+ ASSERT(AllowThisStubCall(&ces)); |
Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); |
} |
@@ -3171,6 +3172,9 @@ |
InvokeFlag flag, |
const CallWrapper& call_wrapper, |
CallKind call_kind) { |
+ // You can't call a function without a valid frame. |
+ ASSERT(flag == JUMP_FUNCTION || has_frame()); |
+ |
Label done; |
InvokePrologue(expected, actual, Handle<Code>::null(), code, &done, flag, |
@@ -3195,6 +3199,9 @@ |
RelocInfo::Mode rmode, |
InvokeFlag flag, |
CallKind call_kind) { |
+ // You can't call a function without a valid frame. |
+ ASSERT(flag == JUMP_FUNCTION || has_frame()); |
+ |
Label done; |
InvokePrologue(expected, actual, code, no_reg, &done, flag, |
@@ -3217,6 +3224,9 @@ |
InvokeFlag flag, |
const CallWrapper& call_wrapper, |
CallKind call_kind) { |
+ // You can't call a function without a valid frame. |
+ ASSERT(flag == JUMP_FUNCTION || has_frame()); |
+ |
// Contract with called JS functions requires that function is passed in a1. |
ASSERT(function.is(a1)); |
Register expected_reg = a2; |
@@ -3239,6 +3249,9 @@ |
const ParameterCount& actual, |
InvokeFlag flag, |
CallKind call_kind) { |
+ // You can't call a function without a valid frame. |
+ ASSERT(flag == JUMP_FUNCTION || has_frame()); |
+ |
ASSERT(function->is_compiled()); |
// Get the function and setup the context. |
@@ -3349,14 +3362,14 @@ |
void MacroAssembler::CallStub(CodeStub* stub, Condition cond, |
Register r1, const Operand& r2) { |
- ASSERT(allow_stub_calls()); // Stub calls are not allowed in some stubs. |
+ ASSERT(AllowThisStubCall(stub)); // Stub calls are not allowed in some stubs. |
Call(stub->GetCode(), RelocInfo::CODE_TARGET, kNoASTId, cond, r1, r2); |
} |
MaybeObject* MacroAssembler::TryCallStub(CodeStub* stub, Condition cond, |
Register r1, const Operand& r2) { |
- ASSERT(allow_stub_calls()); // Stub calls are not allowed in some stubs. |
+ ASSERT(AllowThisStubCall(stub)); // Stub calls are not allowed in some stubs. |
Object* result; |
{ MaybeObject* maybe_result = stub->TryGetCode(); |
if (!maybe_result->ToObject(&result)) return maybe_result; |
@@ -3368,7 +3381,7 @@ |
void MacroAssembler::TailCallStub(CodeStub* stub) { |
- ASSERT(allow_stub_calls()); // Stub calls are not allowed in some stubs. |
+ ASSERT(stub->CompilingCallsToThisStubIsGCSafe() || allow_stub_calls_); |
Jump(stub->GetCode(), RelocInfo::CODE_TARGET); |
} |
@@ -3377,7 +3390,6 @@ |
Condition cond, |
Register r1, |
const Operand& r2) { |
- ASSERT(allow_stub_calls()); // Stub calls are not allowed in some stubs. |
Object* result; |
{ MaybeObject* maybe_result = stub->TryGetCode(); |
if (!maybe_result->ToObject(&result)) return maybe_result; |
@@ -3486,6 +3498,12 @@ |
} |
+bool MacroAssembler::AllowThisStubCall(CodeStub* stub) { |
+ if (!has_frame_ && stub->SometimesSetsUpAFrame()) return false; |
+ return stub->CompilingCallsToThisStubIsGCSafe() || allow_stub_calls_; |
+} |
+ |
+ |
void MacroAssembler::IllegalOperation(int num_arguments) { |
if (num_arguments > 0) { |
addiu(sp, sp, num_arguments * kPointerSize); |
@@ -3722,6 +3740,9 @@ |
void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, |
InvokeFlag flag, |
const CallWrapper& call_wrapper) { |
+ // You can't call a builtin without a valid frame. |
+ ASSERT(flag == JUMP_FUNCTION || has_frame()); |
+ |
GetBuiltinEntry(t9, id); |
if (flag == CALL_FUNCTION) { |
call_wrapper.BeforeCall(CallSize(t9)); |
@@ -3854,14 +3875,20 @@ |
RecordComment(msg); |
} |
#endif |
- // Disable stub call restrictions to always allow calls to abort. |
- AllowStubCallsScope allow_scope(this, true); |
li(a0, Operand(p0)); |
push(a0); |
li(a0, Operand(Smi::FromInt(p1 - p0))); |
push(a0); |
- CallRuntime(Runtime::kAbort, 2); |
+ // Disable stub call restrictions to always allow calls to abort. |
+ if (!has_frame_) { |
+ // We don't actually want to generate a pile of code for this, so just |
+ // claim there is a stack frame, without generating one. |
+ FrameScope scope(this, StackFrame::NONE); |
+ CallRuntime(Runtime::kAbort, 2); |
+ } else { |
+ CallRuntime(Runtime::kAbort, 2); |
+ } |
// Will not return here. |
if (is_trampoline_pool_blocked()) { |
// If the calling code cares about the exact number of |
@@ -4290,6 +4317,7 @@ |
ExternalReference function_reference, |
Register scratch, |
int num_arguments) { |
+ ASSERT(has_frame()); |
// Make sure that the stack is aligned before calling a C function unless |
// running in the simulator. The simulator has its own alignment check which |
// provides more information. |