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:
machenbach 2017-02-16 02:39:58 -08:00 committed by Commit bot
parent 712800a636
commit 4d942ac741
7 changed files with 82 additions and 101 deletions

View File

@ -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: {

View File

@ -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

View File

@ -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(

View File

@ -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 {

View File

@ -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_; }

View File

@ -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;
}
}

View 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));
}
}
})()