ff4e4ab4b6
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/758681 Reviewed-by: Adam Klein <adamk@chromium.org> Commit-Queue: Ross McIlroy <rmcilroy@chromium.org> Cr-Commit-Position: refs/heads/master@{#49276}
206 lines
6.9 KiB
C++
206 lines
6.9 KiB
C++
// 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.
|
|
|
|
#include "src/compilation-info.h"
|
|
|
|
#include "src/api.h"
|
|
#include "src/ast/ast.h"
|
|
#include "src/ast/scopes.h"
|
|
#include "src/debug/debug.h"
|
|
#include "src/isolate.h"
|
|
#include "src/objects-inl.h"
|
|
#include "src/parsing/parse-info.h"
|
|
#include "src/source-position.h"
|
|
|
|
namespace v8 {
|
|
namespace internal {
|
|
|
|
// TODO(mvstanton): the Code::OPTIMIZED_FUNCTION constant below is
|
|
// bogus, it's just that I've eliminated Code::FUNCTION and there isn't
|
|
// a "better" value to put in this place.
|
|
CompilationInfo::CompilationInfo(Zone* zone, Isolate* isolate,
|
|
ParseInfo* parse_info,
|
|
FunctionLiteral* literal)
|
|
: CompilationInfo({}, Code::OPTIMIZED_FUNCTION, BASE, isolate, zone) {
|
|
// NOTE: The parse_info passed here represents the global information gathered
|
|
// during parsing, but does not represent specific details of the actual
|
|
// function literal being compiled for this CompilationInfo. As such,
|
|
// parse_info->literal() might be different from literal, and only global
|
|
// details of the script being parsed are relevant to this CompilationInfo.
|
|
DCHECK_NOT_NULL(literal);
|
|
literal_ = literal;
|
|
source_range_map_ = parse_info->source_range_map();
|
|
|
|
if (parse_info->is_eval()) MarkAsEval();
|
|
if (parse_info->is_native()) MarkAsNative();
|
|
if (parse_info->will_serialize()) MarkAsSerializing();
|
|
if (parse_info->collect_type_profile()) MarkAsCollectTypeProfile();
|
|
}
|
|
|
|
CompilationInfo::CompilationInfo(Zone* zone, Isolate* isolate,
|
|
Handle<SharedFunctionInfo> shared,
|
|
Handle<JSFunction> closure)
|
|
: CompilationInfo({}, Code::OPTIMIZED_FUNCTION, OPTIMIZE, isolate, zone) {
|
|
shared_info_ = shared;
|
|
closure_ = closure;
|
|
optimization_id_ = isolate->NextOptimizationId();
|
|
|
|
if (FLAG_function_context_specialization) MarkAsFunctionContextSpecializing();
|
|
if (FLAG_turbo_splitting) MarkAsSplittingEnabled();
|
|
|
|
// Collect source positions for optimized code when profiling or if debugger
|
|
// is active, to be able to get more precise source positions at the price of
|
|
// more memory consumption.
|
|
if (isolate_->NeedsSourcePositionsForProfiling()) {
|
|
MarkAsSourcePositionsEnabled();
|
|
}
|
|
}
|
|
|
|
CompilationInfo::CompilationInfo(Vector<const char> debug_name,
|
|
Isolate* isolate, Zone* zone,
|
|
Code::Kind code_kind)
|
|
: CompilationInfo(debug_name, code_kind, STUB, isolate, zone) {}
|
|
|
|
CompilationInfo::CompilationInfo(Vector<const char> debug_name,
|
|
Code::Kind code_kind, Mode mode,
|
|
Isolate* isolate, Zone* zone)
|
|
: isolate_(isolate),
|
|
literal_(nullptr),
|
|
source_range_map_(nullptr),
|
|
flags_(0),
|
|
code_kind_(code_kind),
|
|
stub_key_(0),
|
|
mode_(mode),
|
|
osr_offset_(BailoutId::None()),
|
|
feedback_vector_spec_(zone),
|
|
zone_(zone),
|
|
deferred_handles_(nullptr),
|
|
dependencies_(isolate, zone),
|
|
bailout_reason_(kNoReason),
|
|
parameter_count_(0),
|
|
optimization_id_(-1),
|
|
debug_name_(debug_name) {}
|
|
|
|
CompilationInfo::~CompilationInfo() {
|
|
if (GetFlag(kDisableFutureOptimization) && has_shared_info()) {
|
|
shared_info()->DisableOptimization(bailout_reason());
|
|
}
|
|
dependencies()->Rollback();
|
|
}
|
|
|
|
DeclarationScope* CompilationInfo::scope() const {
|
|
DCHECK_NOT_NULL(literal_);
|
|
return literal_->scope();
|
|
}
|
|
|
|
int CompilationInfo::num_parameters() const {
|
|
return !IsStub() ? scope()->num_parameters() : parameter_count_;
|
|
}
|
|
|
|
int CompilationInfo::num_parameters_including_this() const {
|
|
return num_parameters() + (is_this_defined() ? 1 : 0);
|
|
}
|
|
|
|
bool CompilationInfo::is_this_defined() const { return !IsStub(); }
|
|
|
|
void CompilationInfo::set_deferred_handles(
|
|
std::shared_ptr<DeferredHandles> deferred_handles) {
|
|
DCHECK_NULL(deferred_handles_);
|
|
deferred_handles_.swap(deferred_handles);
|
|
}
|
|
|
|
void CompilationInfo::set_deferred_handles(DeferredHandles* deferred_handles) {
|
|
DCHECK_NULL(deferred_handles_);
|
|
deferred_handles_.reset(deferred_handles);
|
|
}
|
|
|
|
void CompilationInfo::ReopenHandlesInNewHandleScope() {
|
|
if (!shared_info_.is_null()) {
|
|
shared_info_ = Handle<SharedFunctionInfo>(*shared_info_);
|
|
}
|
|
if (!closure_.is_null()) {
|
|
closure_ = Handle<JSFunction>(*closure_);
|
|
}
|
|
}
|
|
|
|
bool CompilationInfo::has_simple_parameters() {
|
|
return scope()->has_simple_parameters();
|
|
}
|
|
|
|
std::unique_ptr<char[]> CompilationInfo::GetDebugName() const {
|
|
if (literal()) {
|
|
return literal()->GetDebugName();
|
|
}
|
|
if (!shared_info().is_null()) {
|
|
return shared_info()->DebugName()->ToCString();
|
|
}
|
|
Vector<const char> name_vec = debug_name_;
|
|
if (name_vec.is_empty()) name_vec = ArrayVector("unknown");
|
|
std::unique_ptr<char[]> name(new char[name_vec.length() + 1]);
|
|
memcpy(name.get(), name_vec.start(), name_vec.length());
|
|
name[name_vec.length()] = '\0';
|
|
return name;
|
|
}
|
|
|
|
StackFrame::Type CompilationInfo::GetOutputStackFrameType() const {
|
|
switch (code_kind()) {
|
|
case Code::STUB:
|
|
case Code::BYTECODE_HANDLER:
|
|
case Code::BUILTIN:
|
|
return StackFrame::STUB;
|
|
case Code::WASM_FUNCTION:
|
|
return StackFrame::WASM_COMPILED;
|
|
case Code::JS_TO_WASM_FUNCTION:
|
|
return StackFrame::JS_TO_WASM;
|
|
case Code::WASM_TO_JS_FUNCTION:
|
|
return StackFrame::WASM_TO_JS;
|
|
case Code::WASM_INTERPRETER_ENTRY:
|
|
return StackFrame::WASM_INTERPRETER_ENTRY;
|
|
default:
|
|
UNIMPLEMENTED();
|
|
return StackFrame::NONE;
|
|
}
|
|
}
|
|
|
|
int CompilationInfo::GetDeclareGlobalsFlags() const {
|
|
return DeclareGlobalsEvalFlag::encode(is_eval()) |
|
|
DeclareGlobalsNativeFlag::encode(is_native());
|
|
}
|
|
|
|
SourcePositionTableBuilder::RecordingMode
|
|
CompilationInfo::SourcePositionRecordingMode() const {
|
|
return is_native() ? SourcePositionTableBuilder::OMIT_SOURCE_POSITIONS
|
|
: SourcePositionTableBuilder::RECORD_SOURCE_POSITIONS;
|
|
}
|
|
|
|
bool CompilationInfo::has_context() const { return !closure().is_null(); }
|
|
|
|
Context* CompilationInfo::context() const {
|
|
return has_context() ? closure()->context() : nullptr;
|
|
}
|
|
|
|
bool CompilationInfo::has_native_context() const {
|
|
return !closure().is_null() && (closure()->native_context() != nullptr);
|
|
}
|
|
|
|
Context* CompilationInfo::native_context() const {
|
|
return has_native_context() ? closure()->native_context() : nullptr;
|
|
}
|
|
|
|
bool CompilationInfo::has_global_object() const { return has_native_context(); }
|
|
|
|
JSGlobalObject* CompilationInfo::global_object() const {
|
|
return has_global_object() ? native_context()->global_object() : nullptr;
|
|
}
|
|
|
|
int CompilationInfo::AddInlinedFunction(
|
|
Handle<SharedFunctionInfo> inlined_function, SourcePosition pos) {
|
|
int id = static_cast<int>(inlined_functions_.size());
|
|
inlined_functions_.push_back(InlinedFunctionHolder(inlined_function, pos));
|
|
return id;
|
|
}
|
|
|
|
} // namespace internal
|
|
} // namespace v8
|