Revert of Allow a ParseInfo without a script for %SetCode users (patchset #5 id:220001 of https://codereview.chromium.org/2684033007/ )
Reason for revert:
Please remove the file in status file too. Breaks presubmit:
https://build.chromium.org/p/client.v8/builders/V8%20Linux%20-%20presubmit/builds/14754
Or lets call it post-submit :(
Original issue's description:
> This is a workaround for the fact that %SetCode can "lose" the script for a js native. If the js native is re-initialized (for a Realm or something), then the source SharedFunctionInfo won't have a script anymore. Nonetheless, we may want to optimize the function. If we've compiled bytecode, then we can compile optimized code without a script.
>
> Here, we carve out a special exception for this case, so that we can turn on the --mark-shared-functions-for-tier-up.
>
> BUG=v8:5946
> R=leszeks@chromium.org
>
> Review-Url: https://codereview.chromium.org/2684033007
> Cr-Commit-Position: refs/heads/master@{#43240}
> Committed: 4123a3dd79
TBR=leszeks@chromium.org,mstarzinger@chromium.org,marja@chromium.org,mvstanton@chromium.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:5946
Review-Url: https://codereview.chromium.org/2703553002
Cr-Commit-Position: refs/heads/master@{#43242}
This commit is contained in:
parent
712800a636
commit
4d942ac741
@ -348,8 +348,10 @@ bool UseTurboFan(Handle<SharedFunctionInfo> shared) {
|
||||
passes_turbo_filter;
|
||||
}
|
||||
|
||||
bool ShouldUseIgnition(Handle<SharedFunctionInfo> shared,
|
||||
bool marked_as_debug) {
|
||||
bool ShouldUseIgnition(CompilationInfo* info) {
|
||||
DCHECK(info->has_shared_info());
|
||||
Handle<SharedFunctionInfo> shared = info->shared_info();
|
||||
|
||||
// Code which can't be supported by the old pipeline should use Ignition.
|
||||
if (shared->must_use_ignition_turbo()) return true;
|
||||
|
||||
@ -368,7 +370,7 @@ bool ShouldUseIgnition(Handle<SharedFunctionInfo> shared,
|
||||
|
||||
// When requesting debug code as a replacement for existing code, we provide
|
||||
// the same kind as the existing code (to prevent implicit tier-change).
|
||||
if (marked_as_debug && shared->is_compiled()) {
|
||||
if (info->is_debug() && shared->is_compiled()) {
|
||||
return !shared->HasBaselineCode();
|
||||
}
|
||||
|
||||
@ -379,11 +381,6 @@ bool ShouldUseIgnition(Handle<SharedFunctionInfo> shared,
|
||||
return FLAG_ignition;
|
||||
}
|
||||
|
||||
bool ShouldUseIgnition(CompilationInfo* info) {
|
||||
DCHECK(info->has_shared_info());
|
||||
return ShouldUseIgnition(info->shared_info(), info->is_debug());
|
||||
}
|
||||
|
||||
bool UseAsmWasm(DeclarationScope* scope, Handle<SharedFunctionInfo> shared_info,
|
||||
bool is_debug) {
|
||||
return FLAG_validate_asm && scope->asm_module() &&
|
||||
@ -848,12 +845,8 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function,
|
||||
DCHECK(!isolate->has_pending_exception());
|
||||
PostponeInterruptsScope postpone(isolate);
|
||||
bool use_turbofan = UseTurboFan(shared) || ignition_osr;
|
||||
bool has_script = shared->script()->IsScript();
|
||||
// BUG(5946): This DCHECK is necessary to make certain that we won't tolerate
|
||||
// the lack of a script without bytecode.
|
||||
DCHECK_IMPLIES(!has_script, ShouldUseIgnition(shared, false));
|
||||
std::unique_ptr<CompilationJob> job(
|
||||
use_turbofan ? compiler::Pipeline::NewCompilationJob(function, has_script)
|
||||
use_turbofan ? compiler::Pipeline::NewCompilationJob(function)
|
||||
: new HCompilationJob(function));
|
||||
CompilationInfo* info = job->info();
|
||||
ParseInfo* parse_info = info->parse_info();
|
||||
@ -1076,10 +1069,17 @@ MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) {
|
||||
|
||||
switch (Compiler::NextCompilationTier(*function)) {
|
||||
case Compiler::BASELINE: {
|
||||
// We don't try to handle baseline here because GetBaselineCode()
|
||||
// doesn't handle top-level code. We aren't supporting
|
||||
// the hybrid pipeline going forward (where Ignition is a first
|
||||
// tier followed by full-code).
|
||||
if (FLAG_trace_opt) {
|
||||
PrintF("[recompiling function ");
|
||||
function->ShortPrint();
|
||||
PrintF(
|
||||
" to baseline eagerly (shared function marked for tier up)]\n");
|
||||
}
|
||||
|
||||
Handle<Code> code;
|
||||
if (GetBaselineCode(function).ToHandle(&code)) {
|
||||
return code;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Compiler::OPTIMIZED: {
|
||||
|
@ -545,13 +545,13 @@ PipelineStatistics* CreatePipelineStatistics(CompilationInfo* info,
|
||||
|
||||
class PipelineCompilationJob final : public CompilationJob {
|
||||
public:
|
||||
PipelineCompilationJob(ParseInfo* parse_info, Handle<JSFunction> function)
|
||||
PipelineCompilationJob(Isolate* isolate, Handle<JSFunction> function)
|
||||
// Note that the CompilationInfo is not initialized at the time we pass it
|
||||
// to the CompilationJob constructor, but it is not dereferenced there.
|
||||
: CompilationJob(parse_info->isolate(), &info_, "TurboFan"),
|
||||
parse_info_(parse_info),
|
||||
zone_stats_(parse_info->isolate()->allocator()),
|
||||
info_(parse_info_.get()->zone(), parse_info_.get(), function),
|
||||
: CompilationJob(isolate, &info_, "TurboFan"),
|
||||
parse_info_(handle(function->shared())),
|
||||
zone_stats_(isolate->allocator()),
|
||||
info_(parse_info_.zone(), &parse_info_, function),
|
||||
pipeline_statistics_(CreatePipelineStatistics(info(), &zone_stats_)),
|
||||
data_(&zone_stats_, info(), pipeline_statistics_.get()),
|
||||
pipeline_(&data_),
|
||||
@ -563,7 +563,7 @@ class PipelineCompilationJob final : public CompilationJob {
|
||||
Status FinalizeJobImpl() final;
|
||||
|
||||
private:
|
||||
std::unique_ptr<ParseInfo> parse_info_;
|
||||
ParseInfo parse_info_;
|
||||
ZoneStats zone_stats_;
|
||||
CompilationInfo info_;
|
||||
std::unique_ptr<PipelineStatistics> pipeline_statistics_;
|
||||
@ -1750,16 +1750,8 @@ Handle<Code> Pipeline::GenerateCodeForTesting(
|
||||
}
|
||||
|
||||
// static
|
||||
CompilationJob* Pipeline::NewCompilationJob(Handle<JSFunction> function,
|
||||
bool has_script) {
|
||||
Handle<SharedFunctionInfo> shared = handle(function->shared());
|
||||
ParseInfo* parse_info;
|
||||
if (!has_script) {
|
||||
parse_info = ParseInfo::AllocateWithoutScript(shared);
|
||||
} else {
|
||||
parse_info = new ParseInfo(shared);
|
||||
}
|
||||
return new PipelineCompilationJob(parse_info, function);
|
||||
CompilationJob* Pipeline::NewCompilationJob(Handle<JSFunction> function) {
|
||||
return new PipelineCompilationJob(function->GetIsolate(), function);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -34,8 +34,7 @@ class SourcePositionTable;
|
||||
class Pipeline : public AllStatic {
|
||||
public:
|
||||
// Returns a new compilation job for the given function.
|
||||
static CompilationJob* NewCompilationJob(Handle<JSFunction> function,
|
||||
bool has_script);
|
||||
static CompilationJob* NewCompilationJob(Handle<JSFunction> function);
|
||||
|
||||
// Returns a new compilation job for the WebAssembly compilation info.
|
||||
static CompilationJob* NewWasmCompilationJob(
|
||||
|
@ -100,46 +100,6 @@ ParseInfo::~ParseInfo() {
|
||||
ast_value_factory_ = nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
ParseInfo* ParseInfo::AllocateWithoutScript(Handle<SharedFunctionInfo> shared) {
|
||||
Isolate* isolate = shared->GetIsolate();
|
||||
ParseInfo* p = new ParseInfo(isolate->allocator());
|
||||
p->isolate_ = isolate;
|
||||
|
||||
p->set_toplevel(shared->is_toplevel());
|
||||
p->set_allow_lazy_parsing(FLAG_lazy_inner_functions);
|
||||
p->set_hash_seed(isolate->heap()->HashSeed());
|
||||
p->set_is_named_expression(shared->is_named_expression());
|
||||
p->set_calls_eval(shared->scope_info()->CallsEval());
|
||||
p->set_compiler_hints(shared->compiler_hints());
|
||||
p->set_start_position(shared->start_position());
|
||||
p->set_end_position(shared->end_position());
|
||||
p->function_literal_id_ = shared->function_literal_id();
|
||||
p->set_stack_limit(isolate->stack_guard()->real_climit());
|
||||
p->set_unicode_cache(isolate->unicode_cache());
|
||||
p->set_language_mode(shared->language_mode());
|
||||
p->set_shared_info(shared);
|
||||
p->set_module(shared->kind() == FunctionKind::kModule);
|
||||
|
||||
// BUG(5946): This function exists as a workaround until we can
|
||||
// get rid of %SetCode in our native functions. The ParseInfo
|
||||
// is explicitly set up for the case that:
|
||||
// a) you have a native built-in,
|
||||
// b) it's being run for the 2nd-Nth time in an isolate,
|
||||
// c) we've already compiled bytecode and therefore don't need
|
||||
// to parse.
|
||||
// We tolerate a ParseInfo without a Script in this case.
|
||||
p->set_native(true);
|
||||
p->set_eval(false);
|
||||
|
||||
Handle<HeapObject> scope_info(shared->outer_scope_info());
|
||||
if (!scope_info->IsTheHole(isolate) &&
|
||||
Handle<ScopeInfo>::cast(scope_info)->length() > 0) {
|
||||
p->set_outer_scope_info(Handle<ScopeInfo>::cast(scope_info));
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
DeclarationScope* ParseInfo::scope() const { return literal()->scope(); }
|
||||
|
||||
bool ParseInfo::is_declaration() const {
|
||||
|
@ -42,8 +42,6 @@ class V8_EXPORT_PRIVATE ParseInfo {
|
||||
|
||||
~ParseInfo();
|
||||
|
||||
static ParseInfo* AllocateWithoutScript(Handle<SharedFunctionInfo> shared);
|
||||
|
||||
Zone* zone() const { return zone_.get(); }
|
||||
|
||||
std::shared_ptr<Zone> zone_shared() const { return zone_; }
|
||||
|
@ -11,16 +11,10 @@ namespace internal {
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const SourcePositionInfo& pos) {
|
||||
Handle<SharedFunctionInfo> function(pos.function);
|
||||
String* name = nullptr;
|
||||
if (function->script()->IsScript()) {
|
||||
Script* script = Script::cast(function->script());
|
||||
if (script->name()->IsString()) {
|
||||
name = String::cast(script->name());
|
||||
}
|
||||
}
|
||||
Handle<Script> script(Script::cast(function->script()));
|
||||
out << "<";
|
||||
if (name != nullptr) {
|
||||
out << name->ToCString(DISALLOW_NULLS).get();
|
||||
if (script->name()->IsString()) {
|
||||
out << String::cast(script->name())->ToCString(DISALLOW_NULLS).get();
|
||||
} else {
|
||||
out << "unknown";
|
||||
}
|
||||
@ -84,15 +78,12 @@ std::vector<SourcePositionInfo> SourcePosition::InliningStack(
|
||||
|
||||
void SourcePosition::Print(std::ostream& out,
|
||||
SharedFunctionInfo* function) const {
|
||||
Script* script = Script::cast(function->script());
|
||||
Object* source_name = script->name();
|
||||
Script::PositionInfo pos;
|
||||
Object* source_name = nullptr;
|
||||
if (function->script()->IsScript()) {
|
||||
Script* script = Script::cast(function->script());
|
||||
source_name = script->name();
|
||||
script->GetPositionInfo(ScriptOffset(), &pos, Script::WITH_OFFSET);
|
||||
}
|
||||
script->GetPositionInfo(ScriptOffset(), &pos, Script::WITH_OFFSET);
|
||||
out << "<";
|
||||
if (source_name != nullptr && source_name->IsString()) {
|
||||
if (source_name->IsString()) {
|
||||
out << String::cast(source_name)
|
||||
->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL)
|
||||
.get();
|
||||
@ -126,14 +117,12 @@ void SourcePosition::Print(std::ostream& out, Code* code) const {
|
||||
SourcePositionInfo::SourcePositionInfo(SourcePosition pos,
|
||||
Handle<SharedFunctionInfo> f)
|
||||
: position(pos), function(f) {
|
||||
if (function->script()->IsScript()) {
|
||||
Handle<Script> script(Script::cast(function->script()));
|
||||
Script::PositionInfo info;
|
||||
if (Script::GetPositionInfo(script, pos.ScriptOffset(), &info,
|
||||
Script::WITH_OFFSET)) {
|
||||
line = info.line;
|
||||
column = info.column;
|
||||
}
|
||||
Handle<Script> script(Script::cast(function->script()));
|
||||
Script::PositionInfo info;
|
||||
if (Script::GetPositionInfo(script, pos.ScriptOffset(), &info,
|
||||
Script::WITH_OFFSET)) {
|
||||
line = info.line;
|
||||
column = info.column;
|
||||
}
|
||||
}
|
||||
|
||||
|
43
test/mjsunit/shared-function-tier-up-ignition.js
Normal file
43
test/mjsunit/shared-function-tier-up-ignition.js
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright 2016 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
// Flags: --mark-shared-functions-for-tier-up --allow-natives-syntax
|
||||
// Flags: --ignition-staging --no-turbo
|
||||
// Flags: --crankshaft --no-always-opt
|
||||
|
||||
// If we are always or never optimizing it is useless.
|
||||
assertFalse(isAlwaysOptimize());
|
||||
assertFalse(isNeverOptimize());
|
||||
|
||||
(function() {
|
||||
var sum = 0;
|
||||
var i = 0;
|
||||
for (var i = 0; i < 5; ++i) {
|
||||
var f = function(x) {
|
||||
return 2 * x;
|
||||
}
|
||||
sum += f(i);
|
||||
|
||||
if (i == 1) {
|
||||
// f must be interpreted code.
|
||||
assertTrue(isInterpreted(f));
|
||||
|
||||
// Allow it to run twice (i = 0, 1), then tier-up to baseline.
|
||||
%BaselineFunctionOnNextCall(f);
|
||||
} else if (i == 2) {
|
||||
// Tier-up at i = 2 should only go up to baseline.
|
||||
assertTrue(isBaselined(f));
|
||||
|
||||
} else if (i == 3) {
|
||||
// Now f must be baseline code.
|
||||
assertTrue(isBaselined(f));
|
||||
|
||||
// Run two more times (i = 2, 3), then tier-up to optimized.
|
||||
%OptimizeFunctionOnNextCall(f);
|
||||
} else if (i == 4) {
|
||||
// Tier-up at i = 4 should now go up to crankshaft.
|
||||
assertTrue(isCrankshafted(f));
|
||||
}
|
||||
}
|
||||
})()
|
Loading…
Reference in New Issue
Block a user