| Index: src/arm/macro-assembler-arm.cc
|
| ===================================================================
|
| --- src/arm/macro-assembler-arm.cc (revision 8110)
|
| +++ 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());
|
| @@ -976,6 +977,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,
|
| @@ -1003,6 +1007,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,
|
| @@ -1026,6 +1033,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));
|
|
|
| @@ -1050,6 +1060,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.
|
| @@ -1105,10 +1118,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
|
| @@ -1772,13 +1785,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, 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;
|
| @@ -1789,13 +1802,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;
|
| @@ -1898,6 +1910,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));
|
| @@ -2367,6 +2385,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));
|
| @@ -2495,14 +2516,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
|
|
|