Pass a BailoutReason to Runtime::kAbort.

BUG=
R=rmcilroy@chromium.org, ulan@chromium.org

Review URL: https://codereview.chromium.org/168903004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19442 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
jacob.bramley@arm.com 2014-02-18 13:03:24 +00:00
parent fb82addec0
commit 847aad8059
7 changed files with 51 additions and 94 deletions

View File

@ -4315,51 +4315,46 @@ void MacroAssembler::Abort(BailoutReason reason) {
}
#endif
Label msg_address;
Adr(x0, &msg_address);
// Abort is used in some contexts where csp is the stack pointer. In order to
// simplify the CallRuntime code, make sure that jssp is the stack pointer.
// There is no risk of register corruption here because Abort doesn't return.
Register old_stack_pointer = StackPointer();
SetStackPointer(jssp);
Mov(jssp, old_stack_pointer);
if (use_real_aborts()) {
// Split the message pointer into two SMI to avoid the GC
// trying to scan the string.
STATIC_ASSERT((kSmiShift == 32) && (kSmiTag == 0));
SmiTag(x1, x0);
Bic(x0, x0, kSmiShiftMask);
Push(x0, x1);
Mov(x0, Operand(Smi::FromInt(reason)));
Push(x0);
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);
CallRuntime(Runtime::kAbort, 1);
} else {
CallRuntime(Runtime::kAbort, 2);
CallRuntime(Runtime::kAbort, 1);
}
} else {
// Call Printf directly, to report the error. The message is in x0, which is
// the first argument to Printf.
if (!csp.Is(StackPointer())) {
Bic(csp, StackPointer(), 0xf);
}
// Load the string to pass to Printf.
Label msg_address;
Adr(x0, &msg_address);
// Call Printf directly to report the error.
CallPrintf();
// The CallPrintf will return, so this point is actually reachable in this
// context. However:
// - We're already executing an abort (which shouldn't be reachable in
// valid code).
// - We need a way to stop execution on both the simulator and real
// hardware, and Unreachable() is the best option.
// We need a way to stop execution on both the simulator and real hardware,
// and Unreachable() is the best option.
Unreachable();
// Emit the message string directly in the instruction stream.
{
BlockConstPoolScope scope(this);
Bind(&msg_address);
EmitStringData(GetBailoutReason(reason));
}
}
// Emit the message string directly in the instruction stream.
{
BlockConstPoolScope scope(this);
Bind(&msg_address);
// TODO(jbramley): Since the reason is an enum, why do we still encode the
// string (and a pointer to it) in the instruction stream?
EmitStringData(GetBailoutReason(reason));
}
SetStackPointer(old_stack_pointer);
}

View File

@ -2806,16 +2806,8 @@ void MacroAssembler::Check(Condition cond, BailoutReason reason) {
void MacroAssembler::Abort(BailoutReason reason) {
Label abort_start;
bind(&abort_start);
// We want to pass the msg string like a smi to avoid GC
// problems, however msg is not guaranteed to be aligned
// properly. Instead, we pass an aligned pointer that is
// a proper v8 smi, but also pass the alignment difference
// from the real pointer as a smi.
const char* msg = GetBailoutReason(reason);
intptr_t p1 = reinterpret_cast<intptr_t>(msg);
intptr_t p0 = (p1 & ~kSmiTagMask) + kSmiTag;
ASSERT(reinterpret_cast<Object*>(p0)->IsSmi());
#ifdef DEBUG
const char* msg = GetBailoutReason(reason);
if (msg != NULL) {
RecordComment("Abort message: ");
RecordComment(msg);
@ -2827,25 +2819,24 @@ void MacroAssembler::Abort(BailoutReason reason) {
}
#endif
mov(r0, Operand(p0));
push(r0);
mov(r0, Operand(Smi::FromInt(p1 - p0)));
mov(r0, Operand(Smi::FromInt(reason)));
push(r0);
// 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);
CallRuntime(Runtime::kAbort, 1);
} else {
CallRuntime(Runtime::kAbort, 2);
CallRuntime(Runtime::kAbort, 1);
}
// will not return here
if (is_const_pool_blocked()) {
// If the calling code cares about the exact number of
// instructions generated, we insert padding here to keep the size
// of the Abort macro constant.
static const int kExpectedAbortInstructions = 10;
static const int kExpectedAbortInstructions = 7;
int abort_instructions = InstructionsGeneratedSince(&abort_start);
ASSERT(abort_instructions <= kExpectedAbortInstructions);
while (abort_instructions++ < kExpectedAbortInstructions) {

View File

@ -2980,16 +2980,8 @@ void MacroAssembler::CheckStackAlignment() {
void MacroAssembler::Abort(BailoutReason reason) {
// We want to pass the msg string like a smi to avoid GC
// problems, however msg is not guaranteed to be aligned
// properly. Instead, we pass an aligned pointer that is
// a proper v8 smi, but also pass the alignment difference
// from the real pointer as a smi.
const char* msg = GetBailoutReason(reason);
intptr_t p1 = reinterpret_cast<intptr_t>(msg);
intptr_t p0 = (p1 & ~kSmiTagMask) + kSmiTag;
ASSERT(reinterpret_cast<Object*>(p0)->IsSmi());
#ifdef DEBUG
const char* msg = GetBailoutReason(reason);
if (msg != NULL) {
RecordComment("Abort message: ");
RecordComment(msg);
@ -3002,16 +2994,15 @@ void MacroAssembler::Abort(BailoutReason reason) {
#endif
push(eax);
push(Immediate(p0));
push(Immediate(reinterpret_cast<intptr_t>(Smi::FromInt(p1 - p0))));
push(Immediate(reinterpret_cast<intptr_t>(Smi::FromInt(reason))));
// 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);
CallRuntime(Runtime::kAbort, 1);
} else {
CallRuntime(Runtime::kAbort, 2);
CallRuntime(Runtime::kAbort, 1);
}
// will not return here
int3();

View File

@ -4346,16 +4346,8 @@ void MacroAssembler::Check(Condition cc, BailoutReason reason,
void MacroAssembler::Abort(BailoutReason reason) {
Label abort_start;
bind(&abort_start);
// We want to pass the msg string like a smi to avoid GC
// problems, however msg is not guaranteed to be aligned
// properly. Instead, we pass an aligned pointer that is
// a proper v8 smi, but also pass the alignment difference
// from the real pointer as a smi.
const char* msg = GetBailoutReason(reason);
intptr_t p1 = reinterpret_cast<intptr_t>(msg);
intptr_t p0 = (p1 & ~kSmiTagMask) + kSmiTag;
ASSERT(reinterpret_cast<Object*>(p0)->IsSmi());
#ifdef DEBUG
const char* msg = GetBailoutReason(reason);
if (msg != NULL) {
RecordComment("Abort message: ");
RecordComment(msg);
@ -4367,18 +4359,16 @@ void MacroAssembler::Abort(BailoutReason reason) {
}
#endif
li(a0, Operand(p0));
push(a0);
li(a0, Operand(Smi::FromInt(p1 - p0)));
li(a0, Operand(Smi::FromInt(reason)));
push(a0);
// 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);
CallRuntime(Runtime::kAbort, 1);
} else {
CallRuntime(Runtime::kAbort, 2);
CallRuntime(Runtime::kAbort, 1);
}
// Will not return here.
if (is_trampoline_pool_blocked()) {
@ -4386,8 +4376,8 @@ void MacroAssembler::Abort(BailoutReason reason) {
// instructions generated, we insert padding here to keep the size
// of the Abort macro constant.
// Currently in debug mode with debug_code enabled the number of
// generated instructions is 14, so we use this as a maximum value.
static const int kExpectedAbortInstructions = 14;
// generated instructions is 10, so we use this as a maximum value.
static const int kExpectedAbortInstructions = 10;
int abort_instructions = InstructionsGeneratedSince(&abort_start);
ASSERT(abort_instructions <= kExpectedAbortInstructions);
while (abort_instructions++ < kExpectedAbortInstructions) {

View File

@ -14275,9 +14275,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetV8Version) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_Abort) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 2);
OS::PrintError("abort: %s\n",
reinterpret_cast<char*>(args[0]) + args.smi_at(1));
ASSERT(args.length() == 1);
CONVERT_SMI_ARG_CHECKED(message_id, 0);
const char* message = GetBailoutReason(
static_cast<BailoutReason>(message_id));
OS::PrintError("abort: %s\n", message);
isolate->PrintStack(stderr);
OS::Abort();
UNREACHABLE();

View File

@ -442,7 +442,7 @@ namespace internal {
F(DebugTrace, 0, 1) \
F(TraceEnter, 0, 1) \
F(TraceExit, 1, 1) \
F(Abort, 2, 1) \
F(Abort, 1, 1) \
F(AbortJS, 1, 1) \
/* Logging */ \
F(Log, 2, 1) \

View File

@ -505,17 +505,8 @@ void MacroAssembler::NegativeZeroTest(Register result,
void MacroAssembler::Abort(BailoutReason reason) {
// We want to pass the msg string like a smi to avoid GC
// problems, however msg is not guaranteed to be aligned
// properly. Instead, we pass an aligned pointer that is
// a proper v8 smi, but also pass the alignment difference
// from the real pointer as a smi.
const char* msg = GetBailoutReason(reason);
intptr_t p1 = reinterpret_cast<intptr_t>(msg);
intptr_t p0 = (p1 & ~kSmiTagMask) + kSmiTag;
// Note: p0 might not be a valid Smi _value_, but it has a valid Smi tag.
ASSERT(reinterpret_cast<Object*>(p0)->IsSmi());
#ifdef DEBUG
const char* msg = GetBailoutReason(reason);
if (msg != NULL) {
RecordComment("Abort message: ");
RecordComment(msg);
@ -528,10 +519,7 @@ void MacroAssembler::Abort(BailoutReason reason) {
#endif
push(rax);
Move(kScratchRegister, reinterpret_cast<Smi*>(p0),
Assembler::RelocInfoNone());
push(kScratchRegister);
Move(kScratchRegister, Smi::FromInt(static_cast<int>(p1 - p0)),
Move(kScratchRegister, Smi::FromInt(static_cast<int>(reason)),
Assembler::RelocInfoNone());
push(kScratchRegister);
@ -539,9 +527,9 @@ void MacroAssembler::Abort(BailoutReason reason) {
// 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);
CallRuntime(Runtime::kAbort, 1);
} else {
CallRuntime(Runtime::kAbort, 2);
CallRuntime(Runtime::kAbort, 1);
}
// Control will not return here.
int3();