Commit ff4e4ab4 authored by Ross McIlroy's avatar Ross McIlroy Committed by Commit Bot

[Ast] Teach Ast Printer to print raw literal values.

Converts the ast prettyprinter to printing literals from the raw values
rather than internalized on-heap strings. This enables ast printing before
internalizing, and means we can avoid use of the isolate in the interpreter's
off-thread phase.

Also removes --print-builtin-ast and relies on just --print-ast to print
everything.

Finally, converts FunctionLiteral's debug_name function to return a
char[] which is created from the raw name literal where it exists, rather
than relying on the value having been internalized.

BUG=v8:5203

Change-Id: Ib69f754e254736f415db38713e6209465817e6f1
Reviewed-on: https://chromium-review.googlesource.com/758681Reviewed-by: 's avatarAdam Klein <adamk@chromium.org>
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49276}
parent 9a98ee9a
...@@ -168,6 +168,20 @@ void AstConsString::Internalize(Isolate* isolate) { ...@@ -168,6 +168,20 @@ void AstConsString::Internalize(Isolate* isolate) {
set_string(tmp); set_string(tmp);
} }
std::forward_list<const AstRawString*> AstConsString::ToRawStrings() const {
std::forward_list<const AstRawString*> result;
if (IsEmpty()) {
return result;
}
result.emplace_front(segment_.string);
for (AstConsString::Segment* current = segment_.next; current != nullptr;
current = current->next) {
result.emplace_front(current->string);
}
return result;
}
AstStringConstants::AstStringConstants(Isolate* isolate, uint32_t hash_seed) AstStringConstants::AstStringConstants(Isolate* isolate, uint32_t hash_seed)
: zone_(isolate->allocator(), ZONE_NAME), : zone_(isolate->allocator(), ZONE_NAME),
string_table_(AstRawString::Compare), string_table_(AstRawString::Compare),
......
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
#ifndef V8_AST_AST_VALUE_FACTORY_H_ #ifndef V8_AST_AST_VALUE_FACTORY_H_
#define V8_AST_AST_VALUE_FACTORY_H_ #define V8_AST_AST_VALUE_FACTORY_H_
#include <forward_list>
#include "src/base/hashmap.h" #include "src/base/hashmap.h"
#include "src/conversions.h" #include "src/conversions.h"
#include "src/factory.h" #include "src/factory.h"
...@@ -151,6 +153,8 @@ class AstConsString final : public ZoneObject { ...@@ -151,6 +153,8 @@ class AstConsString final : public ZoneObject {
return Handle<String>(string_); return Handle<String>(string_);
} }
std::forward_list<const AstRawString*> ToRawStrings() const;
private: private:
friend class AstValueFactory; friend class AstValueFactory;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "src/ast/ast.h" #include "src/ast/ast.h"
#include <cmath> // For isfinite. #include <cmath> // For isfinite.
#include <vector>
#include "src/ast/compile-time-value.h" #include "src/ast/compile-time-value.h"
#include "src/ast/prettyprinter.h" #include "src/ast/prettyprinter.h"
...@@ -248,6 +249,34 @@ bool FunctionLiteral::NeedsHomeObject(Expression* expr) { ...@@ -248,6 +249,34 @@ bool FunctionLiteral::NeedsHomeObject(Expression* expr) {
return expr->AsFunctionLiteral()->scope()->NeedsHomeObject(); return expr->AsFunctionLiteral()->scope()->NeedsHomeObject();
} }
std::unique_ptr<char[]> FunctionLiteral::GetDebugName() const {
const AstConsString* cons_string;
if (raw_name_ != nullptr && !raw_name_->IsEmpty()) {
cons_string = raw_name_;
} else if (raw_inferred_name_ != nullptr && !raw_inferred_name_->IsEmpty()) {
cons_string = raw_inferred_name_;
} else if (!inferred_name_.is_null()) {
AllowHandleDereference allow_deref;
return inferred_name_->ToCString();
} else {
return std::unique_ptr<char[]>(new char{'\0'});
}
// TODO(rmcilroy): Deal with two-character strings.
std::vector<char> result_vec;
std::forward_list<const AstRawString*> strings = cons_string->ToRawStrings();
for (const AstRawString* string : strings) {
if (!string->is_one_byte()) break;
for (int i = 0; i < string->length(); i++) {
result_vec.push_back(string->raw_data()[i]);
}
}
std::unique_ptr<char[]> result(new char[result_vec.size() + 1]);
memcpy(result.get(), result_vec.data(), result_vec.size());
result[result_vec.size()] = '\0';
return result;
}
ObjectLiteralProperty::ObjectLiteralProperty(Expression* key, Expression* value, ObjectLiteralProperty::ObjectLiteralProperty(Expression* key, Expression* value,
Kind kind, bool is_computed_name) Kind kind, bool is_computed_name)
: LiteralProperty(key, value, is_computed_name), : LiteralProperty(key, value, is_computed_name),
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef V8_AST_AST_H_ #ifndef V8_AST_AST_H_
#define V8_AST_AST_H_ #define V8_AST_AST_H_
#include <memory>
#include "src/ast/ast-value-factory.h" #include "src/ast/ast-value-factory.h"
#include "src/ast/modules.h" #include "src/ast/modules.h"
#include "src/ast/variables.h" #include "src/ast/variables.h"
...@@ -2266,12 +2268,8 @@ class FunctionLiteral final : public Expression { ...@@ -2266,12 +2268,8 @@ class FunctionLiteral final : public Expression {
return false; return false;
} }
Handle<String> debug_name() const { // Returns either name or inferred name as a cstring.
if (raw_name_ != nullptr && !raw_name_->IsEmpty()) { std::unique_ptr<char[]> GetDebugName() const;
return raw_name_->string();
}
return inferred_name();
}
Handle<String> inferred_name() const { Handle<String> inferred_name() const {
if (!inferred_name_.is_null()) { if (!inferred_name_.is_null()) {
...@@ -2292,6 +2290,8 @@ class FunctionLiteral final : public Expression { ...@@ -2292,6 +2290,8 @@ class FunctionLiteral final : public Expression {
raw_inferred_name_ = nullptr; raw_inferred_name_ = nullptr;
} }
const AstConsString* raw_inferred_name() { return raw_inferred_name_; }
void set_raw_inferred_name(const AstConsString* raw_inferred_name) { void set_raw_inferred_name(const AstConsString* raw_inferred_name) {
DCHECK_NOT_NULL(raw_inferred_name); DCHECK_NOT_NULL(raw_inferred_name);
raw_inferred_name_ = raw_inferred_name; raw_inferred_name_ = raw_inferred_name;
...@@ -2550,6 +2550,7 @@ class ClassLiteral final : public Expression { ...@@ -2550,6 +2550,7 @@ class ClassLiteral final : public Expression {
class NativeFunctionLiteral final : public Expression { class NativeFunctionLiteral final : public Expression {
public: public:
Handle<String> name() const { return name_->string(); } Handle<String> name() const { return name_->string(); }
const AstRawString* raw_name() const { return name_; }
v8::Extension* extension() const { return extension_; } v8::Extension* extension() const { return extension_; }
private: private:
......
This diff is collapsed.
...@@ -64,7 +64,7 @@ class CallPrinter final : public AstVisitor<CallPrinter> { ...@@ -64,7 +64,7 @@ class CallPrinter final : public AstVisitor<CallPrinter> {
class AstPrinter final : public AstVisitor<AstPrinter> { class AstPrinter final : public AstVisitor<AstPrinter> {
public: public:
explicit AstPrinter(Isolate* isolate); explicit AstPrinter(uintptr_t stack_limit);
~AstPrinter(); ~AstPrinter();
// The following routines print a node into a string. // The following routines print a node into a string.
...@@ -89,7 +89,8 @@ class AstPrinter final : public AstVisitor<AstPrinter> { ...@@ -89,7 +89,8 @@ class AstPrinter final : public AstVisitor<AstPrinter> {
void PrintLabels(ZoneList<const AstRawString*>* labels); void PrintLabels(ZoneList<const AstRawString*>* labels);
void PrintLiteral(const AstRawString* value, bool quote); void PrintLiteral(const AstRawString* value, bool quote);
void PrintLiteral(MaybeHandle<Object> maybe_value, bool quote); void PrintLiteral(const AstConsString* value, bool quote);
void PrintLiteral(Literal* literal, bool quote);
void PrintIndented(const char* txt); void PrintIndented(const char* txt);
void PrintIndentedVisit(const char* s, AstNode* node); void PrintIndentedVisit(const char* s, AstNode* node);
...@@ -98,11 +99,13 @@ class AstPrinter final : public AstVisitor<AstPrinter> { ...@@ -98,11 +99,13 @@ class AstPrinter final : public AstVisitor<AstPrinter> {
void PrintParameters(DeclarationScope* scope); void PrintParameters(DeclarationScope* scope);
void PrintArguments(ZoneList<Expression*>* arguments); void PrintArguments(ZoneList<Expression*>* arguments);
void PrintCaseClause(CaseClause* clause); void PrintCaseClause(CaseClause* clause);
void PrintLiteralIndented(const char* info, MaybeHandle<Object> maybe_value, void PrintLiteralIndented(const char* info, Literal* literal, bool quote);
void PrintLiteralIndented(const char* info, const AstRawString* value,
bool quote); bool quote);
void PrintLiteralWithModeIndented(const char* info, void PrintLiteralIndented(const char* info, const AstConsString* value,
Variable* var, bool quote);
Handle<Object> value); void PrintLiteralWithModeIndented(const char* info, Variable* var,
const AstRawString* value);
void PrintLabelsIndented(ZoneList<const AstRawString*>* labels); void PrintLabelsIndented(ZoneList<const AstRawString*>* labels);
void PrintObjectProperties(ZoneList<ObjectLiteral::Property*>* properties); void PrintObjectProperties(ZoneList<ObjectLiteral::Property*>* properties);
void PrintClassProperties(ZoneList<ClassLiteral::Property*>* properties); void PrintClassProperties(ZoneList<ClassLiteral::Property*>* properties);
...@@ -112,7 +115,6 @@ class AstPrinter final : public AstVisitor<AstPrinter> { ...@@ -112,7 +115,6 @@ class AstPrinter final : public AstVisitor<AstPrinter> {
DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
Isolate* isolate_;
char* output_; // output string buffer char* output_; // output string buffer
int size_; // output_ size int size_; // output_ size
int pos_; // current printing position int pos_; // current printing position
......
...@@ -130,8 +130,7 @@ bool CompilationInfo::has_simple_parameters() { ...@@ -130,8 +130,7 @@ bool CompilationInfo::has_simple_parameters() {
std::unique_ptr<char[]> CompilationInfo::GetDebugName() const { std::unique_ptr<char[]> CompilationInfo::GetDebugName() const {
if (literal()) { if (literal()) {
AllowHandleDereference allow_deref; return literal()->GetDebugName();
return literal()->debug_name()->ToCString();
} }
if (!shared_info().is_null()) { if (!shared_info().is_null()) {
return shared_info()->DebugName()->ToCString(); return shared_info()->DebugName()->ToCString();
......
...@@ -1042,7 +1042,6 @@ DEFINE_BOOL(enable_slow_asserts, false, ...@@ -1042,7 +1042,6 @@ DEFINE_BOOL(enable_slow_asserts, false,
// codegen-ia32.cc / codegen-arm.cc / macro-assembler-*.cc // codegen-ia32.cc / codegen-arm.cc / macro-assembler-*.cc
DEFINE_BOOL(print_ast, false, "print source AST") DEFINE_BOOL(print_ast, false, "print source AST")
DEFINE_BOOL(print_builtin_ast, false, "print source AST for builtins")
DEFINE_BOOL(trap_on_abort, false, "replace aborts by breakpoints") DEFINE_BOOL(trap_on_abort, false, "replace aborts by breakpoints")
// compiler.cc // compiler.cc
......
...@@ -163,20 +163,7 @@ void Interpreter::IterateDispatchTable(RootVisitor* v) { ...@@ -163,20 +163,7 @@ void Interpreter::IterateDispatchTable(RootVisitor* v) {
namespace { namespace {
void MaybePrintAst(ParseInfo* parse_info, CompilationInfo* compilation_info) { void MaybePrintAst(ParseInfo* parse_info, CompilationInfo* compilation_info) {
Isolate* isolate = compilation_info->isolate(); if (!FLAG_print_ast) return;
bool print_ast = isolate->bootstrapper()->IsActive() ? FLAG_print_builtin_ast
: FLAG_print_ast;
if (!print_ast) return;
// Requires internalizing the AST, so make sure we are on the main thread and
// allow handle dereference and allocations.
// TODO(rmcilroy): Make ast-printer print ast raw strings instead of
// internalized strings to avoid internalizing here.
DCHECK(ThreadId::Current().Equals(isolate->thread_id()));
AllowHandleDereference allow_deref;
AllowHandleAllocation allow_handles;
AllowHeapAllocation allow_gc;
parse_info->ast_value_factory()->Internalize(isolate);
OFStream os(stdout); OFStream os(stdout);
std::unique_ptr<char[]> name = compilation_info->GetDebugName(); std::unique_ptr<char[]> name = compilation_info->GetDebugName();
...@@ -184,7 +171,8 @@ void MaybePrintAst(ParseInfo* parse_info, CompilationInfo* compilation_info) { ...@@ -184,7 +171,8 @@ void MaybePrintAst(ParseInfo* parse_info, CompilationInfo* compilation_info) {
<< compilation_info->GetDebugName().get() << "]" << std::endl; << compilation_info->GetDebugName().get() << "]" << std::endl;
#ifdef DEBUG #ifdef DEBUG
os << "--- AST ---" << std::endl os << "--- AST ---" << std::endl
<< AstPrinter(isolate).PrintProgram(compilation_info->literal()) << AstPrinter(parse_info->stack_limit())
.PrintProgram(compilation_info->literal())
<< std::endl; << std::endl;
#endif // DEBUG #endif // DEBUG
} }
......
...@@ -778,7 +778,7 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info, ...@@ -778,7 +778,7 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
double ms = timer.Elapsed().InMillisecondsF(); double ms = timer.Elapsed().InMillisecondsF();
// We need to make sure that the debug-name is available. // We need to make sure that the debug-name is available.
ast_value_factory()->Internalize(isolate); ast_value_factory()->Internalize(isolate);
std::unique_ptr<char[]> name_chars = result->debug_name()->ToCString(); std::unique_ptr<char[]> name_chars = result->GetDebugName();
PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms); PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
} }
return result; return result;
......
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