Index: src/x64/macro-assembler-x64.cc |
=================================================================== |
--- src/x64/macro-assembler-x64.cc (revision 9277) |
+++ src/x64/macro-assembler-x64.cc (working copy) |
@@ -44,6 +44,7 @@ |
: Assembler(arg_isolate, buffer, size), |
generating_stub_(false), |
allow_stub_calls_(true), |
+ has_frame_(false), |
root_array_available_(true) { |
if (isolate() != NULL) { |
code_object_ = Handle<Object>(isolate()->heap()->undefined_value(), |
@@ -400,7 +401,7 @@ |
Label L; |
j(cc, &L, Label::kNear); |
Abort(msg); |
- // will not return here |
+ // Control will not return here. |
bind(&L); |
} |
@@ -448,9 +449,6 @@ |
RecordComment(msg); |
} |
#endif |
- // Disable stub call restrictions to always allow calls to abort. |
- AllowStubCallsScope allow_scope(this, true); |
- |
push(rax); |
movq(kScratchRegister, p0, RelocInfo::NONE); |
push(kScratchRegister); |
@@ -458,20 +456,28 @@ |
reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(p1 - p0))), |
RelocInfo::NONE); |
push(kScratchRegister); |
- CallRuntime(Runtime::kAbort, 2); |
- // will not return here |
+ |
+ 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); |
+ } |
+ // Control will not return here. |
int3(); |
} |
void MacroAssembler::CallStub(CodeStub* stub, unsigned ast_id) { |
- ASSERT(allow_stub_calls()); // calls are not allowed in some stubs |
+ ASSERT(AllowThisStubCall(stub)); // Calls are not allowed in some stubs |
Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id); |
} |
MaybeObject* MacroAssembler::TryCallStub(CodeStub* stub) { |
- ASSERT(allow_stub_calls()); // Calls are not allowed in some stubs. |
+ ASSERT(AllowThisStubCall(stub)); // Calls are not allowed in some stubs. |
MaybeObject* result = stub->TryGetCode(); |
if (!result->IsFailure()) { |
call(Handle<Code>(Code::cast(result->ToObjectUnchecked())), |
@@ -482,13 +488,12 @@ |
void MacroAssembler::TailCallStub(CodeStub* stub) { |
- ASSERT(allow_stub_calls()); // Calls are not allowed in some stubs. |
+ ASSERT(stub->CompilingCallsToThisStubIsGCSafe() || allow_stub_calls_); |
Jump(stub->GetCode(), RelocInfo::CODE_TARGET); |
} |
MaybeObject* MacroAssembler::TryTailCallStub(CodeStub* stub) { |
- ASSERT(allow_stub_calls()); // Calls are not allowed in some stubs. |
MaybeObject* result = stub->TryGetCode(); |
if (!result->IsFailure()) { |
jmp(Handle<Code>(Code::cast(result->ToObjectUnchecked())), |
@@ -504,6 +509,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) { |
addq(rsp, Immediate(num_arguments * kPointerSize)); |
@@ -795,8 +806,8 @@ |
void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, |
InvokeFlag flag, |
const CallWrapper& call_wrapper) { |
- // Calls are not allowed in some stubs. |
- ASSERT(flag == JUMP_FUNCTION || allow_stub_calls()); |
+ // You can't call a builtin without a valid frame. |
+ ASSERT(flag == JUMP_FUNCTION || has_frame()); |
// Rely on the assertion to check that the number of provided |
// arguments match the expected number of arguments. Fake a |
@@ -2787,10 +2798,10 @@ |
#ifdef ENABLE_DEBUGGER_SUPPORT |
void MacroAssembler::DebugBreak() { |
- ASSERT(allow_stub_calls()); |
Set(rax, 0); // No arguments. |
LoadAddress(rbx, ExternalReference(Runtime::kDebugBreak, isolate())); |
CEntryStub ces(1); |
+ ASSERT(AllowThisStubCall(&ces)); |
Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); |
} |
#endif // ENABLE_DEBUGGER_SUPPORT |
@@ -2816,6 +2827,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, |
@@ -2847,6 +2861,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; |
Register dummy = rax; |
InvokePrologue(expected, |
@@ -2877,6 +2894,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()); |
+ |
ASSERT(function.is(rdi)); |
movq(rdx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); |
movq(rsi, FieldOperand(function, JSFunction::kContextOffset)); |
@@ -2896,6 +2916,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()); |
+ |
ASSERT(function->is_compiled()); |
// Get the function and setup the context. |
Move(rdi, Handle<JSFunction>(function)); |
@@ -3858,6 +3881,7 @@ |
void MacroAssembler::CallCFunction(Register function, int num_arguments) { |
+ ASSERT(has_frame()); |
// Check stack alignment. |
if (emit_debug_code()) { |
CheckStackAlignment(); |