Index: src/arm/macro-assembler-arm.cc |
=================================================================== |
--- src/arm/macro-assembler-arm.cc (revision 9277) |
+++ src/arm/macro-assembler-arm.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()); |
@@ -961,6 +962,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, |
@@ -988,6 +992,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, |
@@ -1011,6 +1018,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 r1. |
ASSERT(fun.is(r1)); |
@@ -1035,6 +1045,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. |
@@ -1090,10 +1103,10 @@ |
#ifdef ENABLE_DEBUGGER_SUPPORT |
void MacroAssembler::DebugBreak() { |
- ASSERT(allow_stub_calls()); |
mov(r0, Operand(0, RelocInfo::NONE)); |
mov(r1, Operand(ExternalReference(Runtime::kDebugBreak, isolate()))); |
CEntryStub ces(1); |
+ ASSERT(AllowThisStubCall(&ces)); |
Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); |
} |
#endif |
@@ -1895,13 +1908,13 @@ |
void MacroAssembler::CallStub(CodeStub* stub, Condition cond) { |
- 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); |
} |
MaybeObject* MacroAssembler::TryCallStub(CodeStub* stub, Condition cond) { |
- 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; |
@@ -1913,13 +1926,12 @@ |
void MacroAssembler::TailCallStub(CodeStub* stub, Condition cond) { |
- ASSERT(allow_stub_calls()); // Stub calls are not allowed in some stubs. |
+ ASSERT(stub->CompilingCallsToThisStubIsGCSafe() || allow_stub_calls_); |
Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond); |
} |
MaybeObject* MacroAssembler::TryTailCallStub(CodeStub* stub, Condition cond) { |
- 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; |
@@ -2022,6 +2034,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) { |
add(sp, sp, Operand(num_arguments * kPointerSize)); |
@@ -2491,6 +2509,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(r2, id); |
if (flag == CALL_FUNCTION) { |
call_wrapper.BeforeCall(CallSize(r2)); |
@@ -2622,14 +2643,20 @@ |
RecordComment(msg); |
} |
#endif |
- // Disable stub call restrictions to always allow calls to abort. |
- AllowStubCallsScope allow_scope(this, true); |
mov(r0, Operand(p0)); |
push(r0); |
mov(r0, Operand(Smi::FromInt(p1 - p0))); |
push(r0); |
- 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_const_pool_blocked()) { |
// If the calling code cares about the exact number of |
@@ -3127,6 +3154,7 @@ |
Register scratch, |
int num_reg_arguments, |
int num_double_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. |