| Index: src/ia32/macro-assembler-ia32.cc
|
| ===================================================================
|
| --- src/ia32/macro-assembler-ia32.cc (revision 9277)
|
| +++ src/ia32/macro-assembler-ia32.cc (working copy)
|
| @@ -44,7 +44,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());
|
| @@ -1367,13 +1368,13 @@
|
|
|
|
|
| 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.
|
| Object* result;
|
| { MaybeObject* maybe_result = stub->TryGetCode();
|
| if (!maybe_result->ToObject(&result)) return maybe_result;
|
| @@ -1384,13 +1385,12 @@
|
|
|
|
|
| void MacroAssembler::TailCallStub(CodeStub* stub) {
|
| - ASSERT(allow_stub_calls()); // Calls are not allowed in some stubs.
|
| + ASSERT(stub->CompilingCallsToThisStubIsGCSafe() || allow_stub_calls_);
|
| jmp(stub->GetCode(), RelocInfo::CODE_TARGET);
|
| }
|
|
|
|
|
| MaybeObject* MacroAssembler::TryTailCallStub(CodeStub* stub) {
|
| - ASSERT(allow_stub_calls()); // Calls are not allowed in some stubs.
|
| Object* result;
|
| { MaybeObject* maybe_result = stub->TryGetCode();
|
| if (!maybe_result->ToObject(&result)) return maybe_result;
|
| @@ -1406,6 +1406,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(Operand(esp), Immediate(num_arguments * kPointerSize));
|
| @@ -1784,6 +1790,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, Label::kNear, call_wrapper,
|
| @@ -1809,6 +1818,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;
|
| Operand dummy(eax);
|
| InvokePrologue(expected, actual, code, dummy, &done, flag, Label::kNear,
|
| @@ -1832,6 +1844,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(fun.is(edi));
|
| mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
|
| mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
|
| @@ -1849,6 +1864,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.
|
| mov(edi, Immediate(Handle<JSFunction>(function)));
|
| @@ -1872,8 +1890,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
|
| @@ -1884,6 +1902,7 @@
|
| expected, expected, flag, call_wrapper, CALL_AS_METHOD);
|
| }
|
|
|
| +
|
| void MacroAssembler::GetBuiltinFunction(Register target,
|
| Builtins::JavaScript id) {
|
| // Load the JavaScript builtin function from the builtins object.
|
| @@ -1893,6 +1912,7 @@
|
| JSBuiltinsObject::OffsetOfFunctionWithId(id)));
|
| }
|
|
|
| +
|
| void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
|
| ASSERT(!target.is(edi));
|
| // Load the JavaScript builtin function from the builtins object.
|
| @@ -2148,13 +2168,19 @@
|
| RecordComment(msg);
|
| }
|
| #endif
|
| - // Disable stub call restrictions to always allow calls to abort.
|
| - AllowStubCallsScope allow_scope(this, true);
|
|
|
| push(eax);
|
| push(Immediate(p0));
|
| push(Immediate(reinterpret_cast<intptr_t>(Smi::FromInt(p1 - p0))));
|
| - 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
|
| int3();
|
| }
|
| @@ -2253,6 +2279,7 @@
|
|
|
| void MacroAssembler::CallCFunction(Register function,
|
| int num_arguments) {
|
| + ASSERT(has_frame());
|
| // Check stack alignment.
|
| if (emit_debug_code()) {
|
| CheckStackAlignment();
|
|
|