Commit 4eddbaca authored by wingo@igalia.com's avatar wingo@igalia.com

Assign bailout and type feedback IDs in a post-pass

This will allow us to move expressions from one function to another, for
example when the parser determines that a given cover grammar instance
is actually the default value initializer for an arrow function.

This is a re-land of https://codereview.chromium.org/636403003/ with a
fix for the arm64 code generator.

R=svenpanne@chromium.org
BUG=

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24769 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent b830c274
......@@ -433,6 +433,8 @@ source_set("v8_base") {
"src/assembler.h",
"src/assert-scope.h",
"src/assert-scope.cc",
"src/ast-numbering.cc",
"src/ast-numbering.h",
"src/ast-value-factory.cc",
"src/ast-value-factory.h",
"src/ast.cc",
......
......@@ -299,24 +299,24 @@ void FullCodeGenerator::Generate() {
}
VisitDeclarations(scope()->declarations());
}
}
{ Comment cmnt(masm_, "[ Stack check");
PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS);
Label ok;
DCHECK(jssp.Is(__ StackPointer()));
__ CompareRoot(jssp, Heap::kStackLimitRootIndex);
__ B(hs, &ok);
PredictableCodeSizeScope predictable(masm_,
Assembler::kCallSizeWithRelocation);
__ Call(isolate()->builtins()->StackCheck(), RelocInfo::CODE_TARGET);
__ Bind(&ok);
}
{ Comment cmnt(masm_, "[ Stack check");
PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS);
Label ok;
DCHECK(jssp.Is(__ StackPointer()));
__ CompareRoot(jssp, Heap::kStackLimitRootIndex);
__ B(hs, &ok);
PredictableCodeSizeScope predictable(masm_,
Assembler::kCallSizeWithRelocation);
__ Call(isolate()->builtins()->StackCheck(), RelocInfo::CODE_TARGET);
__ Bind(&ok);
}
{ Comment cmnt(masm_, "[ Body");
DCHECK(loop_depth() == 0);
VisitStatements(function()->body());
DCHECK(loop_depth() == 0);
{ Comment cmnt(masm_, "[ Body");
DCHECK(loop_depth() == 0);
VisitStatements(function()->body());
DCHECK(loop_depth() == 0);
}
}
// Always emit a 'return undefined' in case control fell off the end of
......
This diff is collapsed.
// Copyright 2014 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.
#ifndef V8_AST_NUMBERING_H_
#define V8_AST_NUMBERING_H_
namespace v8 {
namespace internal {
namespace AstNumbering {
// Assign type feedback IDs and bailout IDs to an AST node tree.
//
bool Renumber(FunctionLiteral* function, Zone* zone);
}
}
} // namespace v8::internal
#endif // V8_AST_NUMBERING_H_
......@@ -282,6 +282,8 @@ class AstValueFactory {
#undef F
}
Zone* zone() const { return zone_; }
const AstRawString* GetOneByteString(Vector<const uint8_t> literal);
const AstRawString* GetOneByteString(const char* string) {
return GetOneByteString(Vector<const uint8_t>(
......
......@@ -59,9 +59,8 @@ bool Expression::IsUndefinedLiteral(Isolate* isolate) const {
}
VariableProxy::VariableProxy(Zone* zone, Variable* var, int position,
IdGen* id_gen)
: Expression(zone, position, 0, id_gen),
VariableProxy::VariableProxy(Zone* zone, Variable* var, int position)
: Expression(zone, position),
is_this_(var->is_this()),
is_assigned_(false),
is_resolved_(false),
......@@ -73,8 +72,8 @@ VariableProxy::VariableProxy(Zone* zone, Variable* var, int position,
VariableProxy::VariableProxy(Zone* zone, const AstRawString* name, bool is_this,
Interface* interface, int position, IdGen* id_gen)
: Expression(zone, position, 0, id_gen),
Interface* interface, int position)
: Expression(zone, position),
is_this_(is_this),
is_assigned_(false),
is_resolved_(false),
......@@ -98,8 +97,8 @@ void VariableProxy::BindTo(Variable* var) {
Assignment::Assignment(Zone* zone, Token::Value op, Expression* target,
Expression* value, int pos, IdGen* id_gen)
: Expression(zone, pos, num_ids(), id_gen),
Expression* value, int pos)
: Expression(zone, pos),
is_uninitialized_(false),
key_type_(ELEMENT),
store_mode_(STANDARD_STORE),
......@@ -990,8 +989,8 @@ RegExpAlternative::RegExpAlternative(ZoneList<RegExpTree*>* nodes)
CaseClause::CaseClause(Zone* zone, Expression* label,
ZoneList<Statement*>* statements, int pos, IdGen* id_gen)
: Expression(zone, pos, num_ids(), id_gen),
ZoneList<Statement*>* statements, int pos)
: Expression(zone, pos),
label_(label),
statements_(statements),
compare_type_(Type::None(zone)) {}
......
This diff is collapsed.
......@@ -6,6 +6,7 @@
#include "src/compiler.h"
#include "src/ast-numbering.h"
#include "src/bootstrapper.h"
#include "src/codegen.h"
#include "src/compilation-cache.h"
......@@ -746,6 +747,7 @@ static bool CompileOptimizedPrologue(CompilationInfo* info) {
if (!Parser::Parse(info)) return false;
if (!Rewriter::Rewrite(info)) return false;
if (!Scope::Analyze(info)) return false;
if (!AstNumbering::Renumber(info->function(), info->zone())) return false;
DCHECK(info->scope() != NULL);
return true;
}
......
......@@ -391,8 +391,6 @@ class CompilationInfo {
ast_value_factory_owned_ = owned;
}
AstNode::IdGen* ast_node_id_gen() { return &ast_node_id_gen_; }
protected:
CompilationInfo(Handle<Script> script,
Zone* zone);
......@@ -512,7 +510,6 @@ class CompilationInfo {
AstValueFactory* ast_value_factory_;
bool ast_value_factory_owned_;
AstNode::IdGen ast_node_id_gen_;
// This flag is used by the main thread to track whether this compilation
// should be abandoned due to dependency change.
......
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/ast.h"
#include "src/ast-numbering.h"
#include "src/compiler/access-builder.h"
#include "src/compiler/ast-graph-builder.h"
#include "src/compiler/common-operator.h"
......@@ -63,6 +65,7 @@ static void Parse(Handle<JSFunction> function, CompilationInfoWithZone* info) {
CHECK(Parser::Parse(info));
CHECK(Rewriter::Rewrite(info));
CHECK(Scope::Analyze(info));
CHECK(AstNumbering::Renumber(info->function(), info->zone()));
CHECK(Compiler::EnsureDeoptimizationSupport(info));
}
......
......@@ -4,6 +4,8 @@
#include "src/v8.h"
#include "src/ast.h"
#include "src/ast-numbering.h"
#include "src/code-factory.h"
#include "src/codegen.h"
#include "src/compiler.h"
......@@ -306,6 +308,11 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
TimerEventScope<TimerEventCompileFullCode> timer(info->isolate());
if (!AstNumbering::Renumber(info->function(), info->zone())) {
DCHECK(!isolate->has_pending_exception());
return false;
}
Handle<Script> script = info->script();
if (!script->IsUndefined() && !script->source()->IsUndefined()) {
int len = String::cast(script->source())->length();
......
......@@ -9,6 +9,7 @@
#include "src/v8.h"
#include "src/allocation-site-scopes.h"
#include "src/ast-numbering.h"
#include "src/full-codegen.h"
#include "src/hydrogen-bce.h"
#include "src/hydrogen-bch.h"
......@@ -7830,7 +7831,8 @@ bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target,
// step, but don't transfer ownership to target_info.
target_info.SetAstValueFactory(top_info()->ast_value_factory(), false);
Handle<SharedFunctionInfo> target_shared(target->shared());
if (!Parser::Parse(&target_info) || !Scope::Analyze(&target_info)) {
if (!Parser::Parse(&target_info) || !Scope::Analyze(&target_info) ||
!AstNumbering::Renumber(target_info.function(), target_info.zone())) {
if (target_info.isolate()->has_pending_exception()) {
// Parse or scope error, never optimize this function.
SetStackOverflow();
......
......@@ -736,8 +736,7 @@ FunctionLiteral* ParserTraits::ParseFunctionLiteral(
Parser::Parser(CompilationInfo* info, ParseInfo* parse_info)
: ParserBase<ParserTraits>(&scanner_, parse_info->stack_limit,
info->extension(), NULL, info->zone(),
info->ast_node_id_gen(), this),
info->extension(), NULL, info->zone(), this),
scanner_(parse_info->unicode_cache),
reusable_preparser_(NULL),
original_scope_(NULL),
......@@ -879,7 +878,7 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, Scope** scope,
// Enters 'scope'.
AstNodeFactory<AstConstructionVisitor> function_factory(
zone(), ast_value_factory(), info->ast_node_id_gen());
ast_value_factory());
FunctionState function_state(&function_state_, &scope_, *scope,
&function_factory);
......@@ -994,7 +993,7 @@ FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) {
}
original_scope_ = scope;
AstNodeFactory<AstConstructionVisitor> function_factory(
zone(), ast_value_factory(), info()->ast_node_id_gen());
ast_value_factory());
FunctionState function_state(&function_state_, &scope_, scope,
&function_factory);
DCHECK(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT);
......@@ -3496,7 +3495,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// Parse function body.
{
AstNodeFactory<AstConstructionVisitor> function_factory(
zone(), ast_value_factory(), info()->ast_node_id_gen());
ast_value_factory());
FunctionState function_state(&function_state_, &scope_, scope,
&function_factory);
scope_->SetScopeName(function_name);
......
......@@ -104,11 +104,11 @@ PreParser::PreParseResult PreParser::PreParseLazyFunction(
log_ = log;
// Lazy functions always have trivial outer scopes (no with/catch scopes).
PreParserScope top_scope(scope_, GLOBAL_SCOPE);
PreParserFactory top_factory(NULL, NULL, NULL);
PreParserFactory top_factory(NULL);
FunctionState top_state(&function_state_, &scope_, &top_scope, &top_factory);
scope_->SetStrictMode(strict_mode);
PreParserScope function_scope(scope_, FUNCTION_SCOPE);
PreParserFactory function_factory(NULL, NULL, NULL);
PreParserFactory function_factory(NULL);
FunctionState function_state(&function_state_, &scope_, &function_scope,
&function_factory);
function_state.set_is_generator(is_generator);
......@@ -813,7 +813,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
// Parse function body.
ScopeType outer_scope_type = scope_->type();
PreParserScope function_scope(scope_, FUNCTION_SCOPE);
PreParserFactory factory(NULL, NULL, NULL);
PreParserFactory factory(NULL);
FunctionState function_state(&function_state_, &scope_, &function_scope,
&factory);
function_state.set_is_generator(IsGeneratorFunction(kind));
......
......@@ -70,7 +70,6 @@ class ParserBase : public Traits {
ParserBase(Scanner* scanner, uintptr_t stack_limit, v8::Extension* extension,
ParserRecorder* log, typename Traits::Type::Zone* zone,
AstNode::IdGen* ast_node_id_gen,
typename Traits::Type::Parser this_object)
: Traits(this_object),
parenthesized_function_(false),
......@@ -87,8 +86,7 @@ class ParserBase : public Traits {
allow_natives_syntax_(false),
allow_arrow_functions_(false),
allow_harmony_object_literals_(false),
zone_(zone),
ast_node_id_gen_(ast_node_id_gen) {}
zone_(zone) {}
// Getters that indicate whether certain syntactical constructs are
// allowed to be parsed by this instance of the parser.
......@@ -277,7 +275,6 @@ class ParserBase : public Traits {
void set_stack_overflow() { stack_overflow_ = true; }
Mode mode() const { return mode_; }
typename Traits::Type::Zone* zone() const { return zone_; }
AstNode::IdGen* ast_node_id_gen() const { return ast_node_id_gen_; }
INLINE(Token::Value peek()) {
if (stack_overflow_) return Token::ILLEGAL;
......@@ -580,7 +577,6 @@ class ParserBase : public Traits {
bool allow_harmony_object_literals_;
typename Traits::Type::Zone* zone_; // Only used by Parser.
AstNode::IdGen* ast_node_id_gen_;
};
......@@ -972,7 +968,7 @@ class PreParserScope {
class PreParserFactory {
public:
PreParserFactory(void*, void*, void*) {}
explicit PreParserFactory(void* unused_value_factory) {}
PreParserExpression NewStringLiteral(PreParserIdentifier identifier,
int pos) {
return PreParserExpression::Default();
......@@ -1417,7 +1413,7 @@ class PreParser : public ParserBase<PreParserTraits> {
};
PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit)
: ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, NULL,
: ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL,
this) {}
// Pre-parse the program from the character stream; returns true on
......@@ -1426,7 +1422,7 @@ class PreParser : public ParserBase<PreParserTraits> {
// during parsing.
PreParseResult PreParseProgram() {
PreParserScope scope(scope_, GLOBAL_SCOPE);
PreParserFactory factory(NULL, NULL, NULL);
PreParserFactory factory(NULL);
FunctionState top_scope(&function_state_, &scope_, &scope, &factory);
bool ok = true;
int start_position = scanner()->peek_location().beg_pos;
......@@ -2616,8 +2612,7 @@ typename ParserBase<Traits>::ExpressionT ParserBase<
int handler_count = 0;
{
typename Traits::Type::Factory function_factory(
zone(), this->ast_value_factory(), ast_node_id_gen_);
typename Traits::Type::Factory function_factory(this->ast_value_factory());
FunctionState function_state(&function_state_, &scope_,
Traits::Type::ptr_to_scope(scope),
&function_factory);
......
......@@ -15,15 +15,13 @@ namespace internal {
class Processor: public AstVisitor {
public:
Processor(Variable* result, Zone* zone, AstNode::IdGen* ast_node_id_gen)
Processor(Variable* result, AstValueFactory* ast_value_factory)
: result_(result),
result_assigned_(false),
is_set_(false),
in_try_(false),
// Passing a null AstValueFactory is fine, because Processor doesn't
// need to create strings or literals.
factory_(zone, NULL, ast_node_id_gen) {
InitializeAstVisitor(zone);
factory_(ast_value_factory) {
InitializeAstVisitor(ast_value_factory->zone());
}
virtual ~Processor() { }
......@@ -240,7 +238,7 @@ bool Rewriter::Rewrite(CompilationInfo* info) {
scope->NewTemporary(info->ast_value_factory()->dot_result_string());
// The name string must be internalized at this point.
DCHECK(!result->name().is_null());
Processor processor(result, info->zone(), info->ast_node_id_gen());
Processor processor(result, info->ast_value_factory());
processor.Process(body);
if (processor.HasStackOverflow()) return false;
......
......@@ -275,8 +275,7 @@ bool Scope::Analyze(CompilationInfo* info) {
// Allocate the variables.
{
AstNodeFactory<AstNullVisitor> ast_node_factory(
info->zone(), info->ast_value_factory(), info->ast_node_id_gen());
AstNodeFactory<AstNullVisitor> ast_node_factory(info->ast_value_factory());
if (!top->AllocateVariables(info, &ast_node_factory)) return false;
}
......
......@@ -8,6 +8,7 @@
#include "src/v8.h"
#include "test/cctest/cctest.h"
#include "src/ast-numbering.h"
#include "src/compiler.h"
#include "src/compiler/linkage.h"
#include "src/compiler/pipeline.h"
......@@ -166,6 +167,7 @@ class FunctionTester : public InitializedHandleScope {
}
CHECK(Rewriter::Rewrite(&info));
CHECK(Scope::Analyze(&info));
CHECK(AstNumbering::Renumber(info.function(), info.zone()));
CHECK(Compiler::EnsureDeoptimizationSupport(&info));
Pipeline pipeline(&info);
......@@ -215,6 +217,7 @@ class FunctionTester : public InitializedHandleScope {
Handle<Code>(function->shared()->code()));
CHECK(Rewriter::Rewrite(&info));
CHECK(Scope::Analyze(&info));
CHECK(AstNumbering::Renumber(info.function(), info.zone()));
CHECK(Compiler::EnsureDeoptimizationSupport(&info));
Pipeline pipeline(&info);
......
......@@ -16,6 +16,7 @@
#include "src/compiler/register-allocator.h"
#include "src/compiler/schedule.h"
#include "src/ast-numbering.h"
#include "src/full-codegen.h"
#include "src/parser.h"
#include "src/rewriter.h"
......@@ -48,6 +49,7 @@ class DeoptCodegenTester {
info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
CHECK(Rewriter::Rewrite(&info));
CHECK(Scope::Analyze(&info));
CHECK(AstNumbering::Renumber(info.function(), info.zone()));
CHECK(Compiler::EnsureDeoptimizationSupport(&info));
DCHECK(info.shared_info()->has_deoptimization_support());
......
......@@ -5,6 +5,7 @@
#include "src/v8.h"
#include "test/cctest/cctest.h"
#include "src/ast-numbering.h"
#include "src/compiler.h"
#include "src/compiler/pipeline.h"
#include "src/handles.h"
......@@ -25,6 +26,7 @@ TEST(PipelineAdd) {
CHECK(Parser::Parse(&info));
CHECK(Rewriter::Rewrite(&info));
CHECK(Scope::Analyze(&info));
CHECK(AstNumbering::Renumber(info.function(), info.zone()));
CHECK_NE(NULL, info.scope());
Pipeline pipeline(&info);
......
......@@ -40,8 +40,8 @@ TEST(List) {
Isolate* isolate = CcTest::i_isolate();
Zone zone(isolate);
AstNode::IdGen id_gen;
AstNodeFactory<AstNullVisitor> factory(&zone, NULL, &id_gen);
AstValueFactory value_factory(&zone, 0);
AstNodeFactory<AstNullVisitor> factory(&value_factory);
AstNode* node = factory.NewEmptyStatement(RelocInfo::kNoPosition);
list->Add(node);
CHECK_EQ(1, list->length());
......
......@@ -31,6 +31,8 @@
#include "src/v8.h"
#include "src/ast.h"
#include "src/ast-numbering.h"
#include "src/ast-value-factory.h"
#include "src/compiler.h"
#include "src/execution.h"
......@@ -3273,6 +3275,7 @@ TEST(InnerAssignment) {
CHECK(parser.Parse());
CHECK(i::Rewriter::Rewrite(&info));
CHECK(i::Scope::Analyze(&info));
CHECK(i::AstNumbering::Renumber(info.function(), info.zone()));
CHECK(info.function() != NULL);
i::Scope* scope = info.function()->scope();
......
......@@ -349,6 +349,8 @@
'../../src/assert-scope.cc',
'../../src/ast-value-factory.cc',
'../../src/ast-value-factory.h',
'../../src/ast-numbering.cc',
'../../src/ast-numbering.h',
'../../src/ast.cc',
'../../src/ast.h',
'../../src/background-parsing-task.cc',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment