VM: Don't depend on unoptimized code when inlining and creating deoptimization info.
This is the first of two steps of removing the requirement to have unoptimized code when optimizing a function. This would allow optimizing a function without generating unoptimized code first. The only remaining dependency is block reordering (BlockScheduler::AssignWeights) since the edge counters are currently found in the PC descriptors array associated with unoptimized code. BUG= R=asiva@google.com, iposva@google.com Review URL: https://codereview.chromium.org//1314143002 .
This commit is contained in:
@@ -389,15 +389,16 @@ void FlowGraphCompiler::EmitSourceLine(Instruction* instr) {
|
||||
if ((instr->token_pos() == Scanner::kNoSourcePos) || (instr->env() == NULL)) {
|
||||
return;
|
||||
}
|
||||
const Function& function =
|
||||
Function::Handle(instr->env()->code().function());
|
||||
const Script& s = Script::Handle(function.script());
|
||||
const Script& script =
|
||||
Script::Handle(zone(), instr->env()->function().script());
|
||||
intptr_t line_nr;
|
||||
intptr_t column_nr;
|
||||
s.GetTokenLocation(instr->token_pos(), &line_nr, &column_nr);
|
||||
const String& line = String::Handle(s.GetLine(line_nr));
|
||||
script.GetTokenLocation(instr->token_pos(), &line_nr, &column_nr);
|
||||
const String& line = String::Handle(zone(), script.GetLine(line_nr));
|
||||
assembler()->Comment("Line %" Pd " in '%s':\n %s",
|
||||
line_nr, function.ToFullyQualifiedCString(), line.ToCString());
|
||||
line_nr,
|
||||
instr->env()->function().ToFullyQualifiedCString(),
|
||||
line.ToCString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -101,11 +101,9 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
Zone* zone = compiler->zone();
|
||||
|
||||
// Current PP, FP, and PC.
|
||||
builder->AddPp(Function::Handle(zone, current->code().function()), slot_ix++);
|
||||
builder->AddPp(current->function(), slot_ix++);
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
builder->AddReturnAddress(Function::Handle(zone, current->code().function()),
|
||||
deopt_id(),
|
||||
slot_ix++);
|
||||
builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++);
|
||||
|
||||
// Callee's PC marker is not used anymore. Pass Function::null() to set to 0.
|
||||
builder->AddPcMarker(Function::Handle(zone), slot_ix++);
|
||||
@@ -126,20 +124,18 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
current = current->outer();
|
||||
while (current != NULL) {
|
||||
// PP, FP, and PC.
|
||||
builder->AddPp(
|
||||
Function::Handle(zone, current->code().function()), slot_ix++);
|
||||
builder->AddPp(current->function(), slot_ix++);
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
|
||||
// For any outer environment the deopt id is that of the call instruction
|
||||
// which is recorded in the outer environment.
|
||||
builder->AddReturnAddress(
|
||||
Function::Handle(zone, current->code().function()),
|
||||
current->function(),
|
||||
Isolate::ToDeoptAfter(current->deopt_id()),
|
||||
slot_ix++);
|
||||
|
||||
// PC marker.
|
||||
builder->AddPcMarker(Function::Handle(zone, previous->code().function()),
|
||||
slot_ix++);
|
||||
builder->AddPcMarker(previous->function(), slot_ix++);
|
||||
|
||||
// The values of outgoing arguments can be changed from the inlined call so
|
||||
// we must read them from the previous environment.
|
||||
@@ -171,8 +167,7 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
builder->AddCallerPc(slot_ix++);
|
||||
|
||||
// PC marker.
|
||||
builder->AddPcMarker(Function::Handle(zone, previous->code().function()),
|
||||
slot_ix++);
|
||||
builder->AddPcMarker(previous->function(), slot_ix++);
|
||||
|
||||
// For the outermost environment, set the incoming arguments.
|
||||
for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) {
|
||||
|
||||
@@ -98,12 +98,10 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
Zone* zone = compiler->zone();
|
||||
|
||||
// Current PP, FP, and PC.
|
||||
builder->AddPp(Function::Handle(zone, current->code().function()), slot_ix++);
|
||||
builder->AddPp(current->function(), slot_ix++);
|
||||
builder->AddPcMarker(Function::Handle(zone), slot_ix++);
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
builder->AddReturnAddress(Function::Handle(zone, current->code().function()),
|
||||
deopt_id(),
|
||||
slot_ix++);
|
||||
builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++);
|
||||
|
||||
// Emit all values that are needed for materialization as a part of the
|
||||
// expression stack for the bottom-most frame. This guarantees that GC
|
||||
@@ -121,16 +119,14 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
current = current->outer();
|
||||
while (current != NULL) {
|
||||
// PP, FP, and PC.
|
||||
builder->AddPp(Function::Handle(
|
||||
zone, current->code().function()), slot_ix++);
|
||||
builder->AddPcMarker(Function::Handle(zone, previous->code().function()),
|
||||
slot_ix++);
|
||||
builder->AddPp(current->function(), slot_ix++);
|
||||
builder->AddPcMarker(previous->function(), slot_ix++);
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
|
||||
// For any outer environment the deopt id is that of the call instruction
|
||||
// which is recorded in the outer environment.
|
||||
builder->AddReturnAddress(
|
||||
Function::Handle(zone, current->code().function()),
|
||||
current->function(),
|
||||
Isolate::ToDeoptAfter(current->deopt_id()),
|
||||
slot_ix++);
|
||||
|
||||
@@ -161,8 +157,7 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
// For the outermost environment, set caller PC, caller PP, and caller FP.
|
||||
builder->AddCallerPp(slot_ix++);
|
||||
// PC marker.
|
||||
builder->AddPcMarker(Function::Handle(zone, previous->code().function()),
|
||||
slot_ix++);
|
||||
builder->AddPcMarker(previous->function(), slot_ix++);
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
builder->AddCallerPc(slot_ix++);
|
||||
|
||||
|
||||
@@ -107,9 +107,7 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
|
||||
// Current FP and PC.
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
builder->AddReturnAddress(Function::Handle(zone, current->code().function()),
|
||||
deopt_id(),
|
||||
slot_ix++);
|
||||
builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++);
|
||||
|
||||
// Emit all values that are needed for materialization as a part of the
|
||||
// expression stack for the bottom-most frame. This guarantees that GC
|
||||
@@ -124,8 +122,7 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
}
|
||||
|
||||
// Current PC marker and caller FP.
|
||||
builder->AddPcMarker(Function::Handle(
|
||||
zone, current->code().function()), slot_ix++);
|
||||
builder->AddPcMarker(current->function(), slot_ix++);
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
|
||||
Environment* previous = current;
|
||||
@@ -134,7 +131,7 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
// For any outer environment the deopt id is that of the call instruction
|
||||
// which is recorded in the outer environment.
|
||||
builder->AddReturnAddress(
|
||||
Function::Handle(zone, current->code().function()),
|
||||
current->function(),
|
||||
Isolate::ToDeoptAfter(current->deopt_id()),
|
||||
slot_ix++);
|
||||
|
||||
@@ -156,8 +153,7 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
}
|
||||
|
||||
// PC marker and caller FP.
|
||||
builder->AddPcMarker(Function::Handle(zone, current->code().function()),
|
||||
slot_ix++);
|
||||
builder->AddPcMarker(current->function(), slot_ix++);
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
|
||||
// Iterate on the outer environment.
|
||||
|
||||
@@ -97,11 +97,9 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
Zone* zone = compiler->zone();
|
||||
|
||||
// Current PP, FP, and PC.
|
||||
builder->AddPp(Function::Handle(zone, current->code().function()), slot_ix++);
|
||||
builder->AddPp(current->function(), slot_ix++);
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
builder->AddReturnAddress(Function::Handle(zone, current->code().function()),
|
||||
deopt_id(),
|
||||
slot_ix++);
|
||||
builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++);
|
||||
|
||||
// Callee's PC marker is not used anymore. Pass Code::null() to set to 0.
|
||||
builder->AddPcMarker(Function::Handle(zone), slot_ix++);
|
||||
@@ -122,20 +120,18 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
current = current->outer();
|
||||
while (current != NULL) {
|
||||
// PP, FP, and PC.
|
||||
builder->AddPp(
|
||||
Function::Handle(zone, current->code().function()), slot_ix++);
|
||||
builder->AddPp(current->function(), slot_ix++);
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
|
||||
// For any outer environment the deopt id is that of the call instruction
|
||||
// which is recorded in the outer environment.
|
||||
builder->AddReturnAddress(
|
||||
Function::Handle(zone, current->code().function()),
|
||||
current->function(),
|
||||
Isolate::ToDeoptAfter(current->deopt_id()),
|
||||
slot_ix++);
|
||||
|
||||
// PC marker.
|
||||
builder->AddPcMarker(Function::Handle(zone, previous->code().function()),
|
||||
slot_ix++);
|
||||
builder->AddPcMarker(previous->function(), slot_ix++);
|
||||
|
||||
// The values of outgoing arguments can be changed from the inlined call so
|
||||
// we must read them from the previous environment.
|
||||
@@ -167,8 +163,7 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
builder->AddCallerPc(slot_ix++);
|
||||
|
||||
// PC marker.
|
||||
builder->AddPcMarker(Function::Handle(zone, previous->code().function()),
|
||||
slot_ix++);
|
||||
builder->AddPcMarker(previous->function(), slot_ix++);
|
||||
|
||||
// For the outermost environment, set the incoming arguments.
|
||||
for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) {
|
||||
|
||||
@@ -101,12 +101,10 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
Zone* zone = compiler->zone();
|
||||
|
||||
// Current PP, FP, and PC.
|
||||
builder->AddPp(Function::Handle(zone, current->code().function()), slot_ix++);
|
||||
builder->AddPp(current->function(), slot_ix++);
|
||||
builder->AddPcMarker(Function::Handle(zone), slot_ix++);
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
builder->AddReturnAddress(Function::Handle(zone, current->code().function()),
|
||||
deopt_id(),
|
||||
slot_ix++);
|
||||
builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++);
|
||||
|
||||
// Emit all values that are needed for materialization as a part of the
|
||||
// expression stack for the bottom-most frame. This guarantees that GC
|
||||
@@ -124,16 +122,14 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
current = current->outer();
|
||||
while (current != NULL) {
|
||||
// PP, FP, and PC.
|
||||
builder->AddPp(Function::Handle(zone, current->code().function()),
|
||||
slot_ix++);
|
||||
builder->AddPcMarker(Function::Handle(zone, previous->code().function()),
|
||||
slot_ix++);
|
||||
builder->AddPp(current->function(), slot_ix++);
|
||||
builder->AddPcMarker(previous->function(), slot_ix++);
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
|
||||
// For any outer environment the deopt id is that of the call instruction
|
||||
// which is recorded in the outer environment.
|
||||
builder->AddReturnAddress(
|
||||
Function::Handle(zone, current->code().function()),
|
||||
current->function(),
|
||||
Isolate::ToDeoptAfter(current->deopt_id()),
|
||||
slot_ix++);
|
||||
|
||||
@@ -164,8 +160,7 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
// For the outermost environment, set caller PC, caller PP, and caller FP.
|
||||
builder->AddCallerPp(slot_ix++);
|
||||
// PC marker.
|
||||
builder->AddPcMarker(Function::Handle(zone, previous->code().function()),
|
||||
slot_ix++);
|
||||
builder->AddPcMarker(previous->function(), slot_ix++);
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
builder->AddCallerPc(slot_ix++);
|
||||
|
||||
|
||||
@@ -82,10 +82,10 @@ DECLARE_FLAG(bool, verify_compiler);
|
||||
|
||||
|
||||
// Test if a call is recursive by looking in the deoptimization environment.
|
||||
static bool IsCallRecursive(const Code& code, Definition* call) {
|
||||
static bool IsCallRecursive(const Function& function, Definition* call) {
|
||||
Environment* env = call->env();
|
||||
while (env != NULL) {
|
||||
if (code.raw() == env->code().raw()) {
|
||||
if (function.raw() == env->function().raw()) {
|
||||
return true;
|
||||
}
|
||||
env = env->outer();
|
||||
@@ -667,7 +667,7 @@ class CallSiteInliner : public ValueObject {
|
||||
// Abort if this is a recursive occurrence.
|
||||
Definition* call = call_data->call;
|
||||
// Added 'volatile' works around a possible GCC 4.9 compiler bug.
|
||||
volatile bool is_recursive_call = IsCallRecursive(unoptimized_code, call);
|
||||
volatile bool is_recursive_call = IsCallRecursive(function, call);
|
||||
if (is_recursive_call &&
|
||||
inlining_recursion_depth_ >= FLAG_inlining_recursion_depth_threshold) {
|
||||
TRACE_INLINING(ISL_Print(" Bailout: recursive function\n"));
|
||||
|
||||
@@ -8015,7 +8015,7 @@ class Environment : public ZoneAllocated {
|
||||
return count;
|
||||
}
|
||||
|
||||
const Code& code() const { return parsed_function_.code(); }
|
||||
const Function& function() const { return parsed_function_.function(); }
|
||||
|
||||
Environment* DeepCopy(Zone* zone) const {
|
||||
return DeepCopy(zone, Length());
|
||||
|
||||
Reference in New Issue
Block a user