Reviewers: fschneider,
Description:
Small change to stack checks in unoptimized code.
The stack checks include a loop nesting depth encoded in the code stream
after the call to the stack check stub. Change the code to jump around this
instruction as well as the call when the stack check is OK.
Please review this at http://codereview.chromium.org/6005014/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge/build/ia32
Affected files:
M src/arm/full-codegen-arm.cc
M src/ia32/deoptimizer-ia32.cc
M src/ia32/full-codegen-ia32.cc
M src/x64/full-codegen-x64.cc
Index: src/arm/full-codegen-arm.cc
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index
0275730aed73a82c00e73a9cfe0b2310e64ac8c3..338e39cbe823ddbe4f32556268284ca01c770727
100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -221,10 +221,17 @@ void
FullCodeGenerator::EmitStackCheck(IterationStatement* stmt) {
__ b(hs, &ok);
StackCheckStub stub;
__ CallStub(&stub);
+ // Record a mapping of this PC offset to the OSR id. This is used to
find
+ // the AST id from the unoptimized code in order to use it as a key into
+ // the deoptimization input data found in the optimized code.
+ RecordStackCheck(stmt->OsrEntryId());
+
__ bind(&ok);
PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
+ // Record a mapping of the OSR id to this PC. This is used if the OSR
+ // entry becomes the target of a bailout. We don't expect it to be, but
+ // we want it to work if it is.
PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS);
- RecordStackCheck(stmt->OsrEntryId());
}
Index: src/ia32/deoptimizer-ia32.cc
diff --git a/src/ia32/deoptimizer-ia32.cc b/src/ia32/deoptimizer-ia32.cc
index
d95df3e7ea3d72664e71b4d7e64624dd39064130..ceba2494a35b30c7d8f24b4a1c4d27cc38d2e8a9
100644
--- a/src/ia32/deoptimizer-ia32.cc
+++ b/src/ia32/deoptimizer-ia32.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -105,23 +105,25 @@ void Deoptimizer::DeoptimizeFunction(JSFunction*
function) {
void Deoptimizer::PatchStackCheckCode(RelocInfo* rinfo,
Code* replacement_code) {
- // The stack check code matches the pattern (on ia32, for example):
+ // The stack check code matches the pattern:
//
// cmp esp, <limit>
// jae ok
// call <stack guard>
+ // test eax, <loop nesting depth>
// ok: ...
//
- // We will patch the code to:
+ // We will patch away the branch so the code is:
//
// cmp esp, <limit> ;; Not changed
// nop
// nop
// call <on-stack replacment>
+ // test eax, <loop nesting depth>
// ok:
Address call_target_address = rinfo->pc();
ASSERT(*(call_target_address - 3) == 0x73 && // jae
- *(call_target_address - 2) == 0x05 && // offset
+ *(call_target_address - 2) == 0x07 && // offset
*(call_target_address - 1) == 0xe8); // call
*(call_target_address - 3) = 0x90; // nop
*(call_target_address - 2) = 0x90; // nop
@@ -130,12 +132,14 @@ void Deoptimizer::PatchStackCheckCode(RelocInfo*
rinfo,
void Deoptimizer::RevertStackCheckCode(RelocInfo* rinfo, Code* check_code)
{
+ // Replace the nops from patching (Deoptimizer::PatchStackCheckCode) to
+ // restore the conditional branch.
Address call_target_address = rinfo->pc();
ASSERT(*(call_target_address - 3) == 0x90 && // nop
*(call_target_address - 2) == 0x90 && // nop
*(call_target_address - 1) == 0xe8); // call
*(call_target_address - 3) = 0x73; // jae
- *(call_target_address - 2) = 0x05; // offset
+ *(call_target_address - 2) = 0x07; // offset
rinfo->set_target_address(check_code->entry());
}
Index: src/ia32/full-codegen-ia32.cc
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index
b038b7d577d5c678fd6fb008e35328662ea764a9..6e86ad5bf3a95fadb4dbabda9bf6b10497a2de3f
100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -264,16 +264,24 @@ void
FullCodeGenerator::EmitStackCheck(IterationStatement* stmt) {
__ j(above_equal, &ok, taken);
StackCheckStub stub;
__ CallStub(&stub);
- __ bind(&ok);
- PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
- PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS);
+ // Record a mapping of this PC offset to the OSR id. This is used to
find
+ // the AST id from the unoptimized code in order to use it as a key into
+ // the deoptimization input data found in the optimized code.
RecordStackCheck(stmt->OsrEntryId());
- // Loop stack checks can be patched to perform on-stack
- // replacement. In order to decide whether or not to perform OSR we
- // embed the loop depth in a test instruction after the call so we
- // can extract it from the OSR builtin.
+
+ // Loop stack checks can be patched to perform on-stack replacement. In
+ // order to decide whether or not to perform OSR we embed the loop depth
+ // in a test instruction after the call so we can extract it from the OSR
+ // builtin.
ASSERT(loop_depth() > 0);
__ test(eax, Immediate(Min(loop_depth(), Code::kMaxLoopNestingMarker)));
+
+ __ bind(&ok);
+ PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
+ // Record a mapping of the OSR id to this PC. This is used if the OSR
+ // entry becomes the target of a bailout. We don't expect it to be, but
+ // we want it to work if it is.
+ PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS);
}
Index: src/x64/full-codegen-x64.cc
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index
66bc4ede96c85bce4ba491cc10f5ee88b71b3aef..7ac9faf71640b280dcb326785e1e8af4146a39a6
100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -210,10 +210,17 @@ void
FullCodeGenerator::EmitStackCheck(IterationStatement* stmt) {
__ j(above_equal, &ok);
StackCheckStub stub;
__ CallStub(&stub);
+ // Record a mapping of this PC offset to the OSR id. This is used to
find
+ // the AST id from the unoptimized code in order to use it as a key into
+ // the deoptimization input data found in the optimized code.
+ RecordStackCheck(stmt->OsrEntryId());
+
__ bind(&ok);
PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
+ // Record a mapping of the OSR id to this PC. This is used if the OSR
+ // entry becomes the target of a bailout. We don't expect it to be, but
+ // we want it to work if it is.
PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS);
- RecordStackCheck(stmt->OsrEntryId());
}
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev