db7f61d694
Bug: v8:7790 Change-Id: I9d1853a65ad5430e5bc38727ebf9fcd6aa40c819 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1599605 Commit-Queue: Maya Lekova <mslekova@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Cr-Commit-Position: refs/heads/master@{#61386}
277 lines
9.2 KiB
C++
277 lines
9.2 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/optimized-compilation-info.h"
|
|
|
|
#include "src/api.h"
|
|
#include "src/debug/debug.h"
|
|
#include "src/isolate.h"
|
|
#include "src/objects-inl.h"
|
|
#include "src/objects/shared-function-info.h"
|
|
#include "src/source-position.h"
|
|
#include "src/tracing/trace-event.h"
|
|
#include "src/tracing/traced-value.h"
|
|
#include "src/wasm/function-compiler.h"
|
|
|
|
namespace v8 {
|
|
namespace internal {
|
|
|
|
OptimizedCompilationInfo::OptimizedCompilationInfo(
|
|
Zone* zone, Isolate* isolate, Handle<SharedFunctionInfo> shared,
|
|
Handle<JSFunction> closure)
|
|
: OptimizedCompilationInfo(Code::OPTIMIZED_FUNCTION, zone) {
|
|
DCHECK(shared->is_compiled());
|
|
bytecode_array_ = handle(shared->GetBytecodeArray(), isolate);
|
|
shared_info_ = shared;
|
|
closure_ = closure;
|
|
optimization_id_ = isolate->NextOptimizationId();
|
|
|
|
// 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->NeedsDetailedOptimizedCodeLineInfo()) {
|
|
MarkAsSourcePositionsEnabled();
|
|
}
|
|
|
|
SetTracingFlags(shared->PassesFilter(FLAG_trace_turbo_filter));
|
|
}
|
|
|
|
OptimizedCompilationInfo::OptimizedCompilationInfo(
|
|
Vector<const char> debug_name, Zone* zone, Code::Kind code_kind)
|
|
: OptimizedCompilationInfo(code_kind, zone) {
|
|
debug_name_ = debug_name;
|
|
|
|
SetTracingFlags(
|
|
PassesFilter(debug_name, CStrVector(FLAG_trace_turbo_filter)));
|
|
}
|
|
|
|
OptimizedCompilationInfo::OptimizedCompilationInfo(Code::Kind code_kind,
|
|
Zone* zone)
|
|
: code_kind_(code_kind), zone_(zone) {
|
|
ConfigureFlags();
|
|
}
|
|
|
|
void OptimizedCompilationInfo::ConfigureFlags() {
|
|
if (FLAG_untrusted_code_mitigations) SetFlag(kUntrustedCodeMitigations);
|
|
|
|
switch (code_kind_) {
|
|
case Code::OPTIMIZED_FUNCTION:
|
|
SetFlag(kCalledWithCodeStartRegister);
|
|
SetFlag(kSwitchJumpTableEnabled);
|
|
if (FLAG_function_context_specialization) {
|
|
MarkAsFunctionContextSpecializing();
|
|
}
|
|
if (FLAG_turbo_splitting) {
|
|
MarkAsSplittingEnabled();
|
|
}
|
|
if (FLAG_untrusted_code_mitigations) {
|
|
MarkAsPoisoningRegisterArguments();
|
|
}
|
|
if (FLAG_analyze_environment_liveness) {
|
|
// TODO(yangguo): Disable this in case of debugging for crbug.com/826613
|
|
MarkAsAnalyzeEnvironmentLiveness();
|
|
}
|
|
break;
|
|
case Code::BYTECODE_HANDLER:
|
|
SetFlag(kCalledWithCodeStartRegister);
|
|
break;
|
|
case Code::BUILTIN:
|
|
case Code::STUB:
|
|
#if ENABLE_GDB_JIT_INTERFACE && DEBUG
|
|
MarkAsSourcePositionsEnabled();
|
|
#endif // ENABLE_GDB_JIT_INTERFACE && DEBUG
|
|
break;
|
|
case Code::WASM_FUNCTION:
|
|
case Code::WASM_TO_CAPI_FUNCTION:
|
|
SetFlag(kSwitchJumpTableEnabled);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (FLAG_turbo_control_flow_aware_allocation) {
|
|
MarkAsTurboControlFlowAwareAllocation();
|
|
} else {
|
|
MarkAsTurboPreprocessRanges();
|
|
}
|
|
}
|
|
|
|
OptimizedCompilationInfo::~OptimizedCompilationInfo() {
|
|
if (GetFlag(kDisableFutureOptimization) && has_shared_info()) {
|
|
shared_info()->DisableOptimization(bailout_reason());
|
|
}
|
|
}
|
|
|
|
void OptimizedCompilationInfo::set_deferred_handles(
|
|
std::shared_ptr<DeferredHandles> deferred_handles) {
|
|
DCHECK_NULL(deferred_handles_);
|
|
deferred_handles_.swap(deferred_handles);
|
|
}
|
|
|
|
void OptimizedCompilationInfo::set_deferred_handles(
|
|
DeferredHandles* deferred_handles) {
|
|
DCHECK_NULL(deferred_handles_);
|
|
deferred_handles_.reset(deferred_handles);
|
|
}
|
|
|
|
void OptimizedCompilationInfo::ReopenHandlesInNewHandleScope(Isolate* isolate) {
|
|
if (!shared_info_.is_null()) {
|
|
shared_info_ = Handle<SharedFunctionInfo>(*shared_info_, isolate);
|
|
}
|
|
if (!bytecode_array_.is_null()) {
|
|
bytecode_array_ = Handle<BytecodeArray>(*bytecode_array_, isolate);
|
|
}
|
|
if (!closure_.is_null()) {
|
|
closure_ = Handle<JSFunction>(*closure_, isolate);
|
|
}
|
|
}
|
|
|
|
void OptimizedCompilationInfo::AbortOptimization(BailoutReason reason) {
|
|
DCHECK_NE(reason, BailoutReason::kNoReason);
|
|
if (bailout_reason_ == BailoutReason::kNoReason) {
|
|
TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
|
|
"V8.AbortOptimization", TRACE_EVENT_SCOPE_THREAD,
|
|
"reason", GetBailoutReason(reason), "function",
|
|
shared_info()->TraceIDRef());
|
|
bailout_reason_ = reason;
|
|
}
|
|
SetFlag(kDisableFutureOptimization);
|
|
}
|
|
|
|
void OptimizedCompilationInfo::RetryOptimization(BailoutReason reason) {
|
|
DCHECK_NE(reason, BailoutReason::kNoReason);
|
|
if (GetFlag(kDisableFutureOptimization)) return;
|
|
TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
|
|
"V8.RetryOptimization", TRACE_EVENT_SCOPE_THREAD,
|
|
"reason", GetBailoutReason(reason), "function",
|
|
shared_info()->TraceIDRef());
|
|
bailout_reason_ = reason;
|
|
}
|
|
|
|
std::unique_ptr<char[]> OptimizedCompilationInfo::GetDebugName() const {
|
|
if (!shared_info().is_null()) {
|
|
return shared_info()->DebugName()->ToCString();
|
|
}
|
|
Vector<const char> name_vec = debug_name_;
|
|
if (name_vec.empty()) name_vec = ArrayVector("unknown");
|
|
std::unique_ptr<char[]> name(new char[name_vec.length() + 1]);
|
|
memcpy(name.get(), name_vec.begin(), name_vec.length());
|
|
name[name_vec.length()] = '\0';
|
|
return name;
|
|
}
|
|
|
|
StackFrame::Type OptimizedCompilationInfo::GetOutputStackFrameType() const {
|
|
switch (code_kind()) {
|
|
case Code::STUB:
|
|
case Code::BYTECODE_HANDLER:
|
|
case Code::BUILTIN:
|
|
return StackFrame::STUB;
|
|
case Code::WASM_FUNCTION:
|
|
case Code::WASM_TO_CAPI_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;
|
|
}
|
|
}
|
|
|
|
void OptimizedCompilationInfo::SetWasmCompilationResult(
|
|
std::unique_ptr<wasm::WasmCompilationResult> wasm_compilation_result) {
|
|
wasm_compilation_result_ = std::move(wasm_compilation_result);
|
|
}
|
|
|
|
std::unique_ptr<wasm::WasmCompilationResult>
|
|
OptimizedCompilationInfo::ReleaseWasmCompilationResult() {
|
|
return std::move(wasm_compilation_result_);
|
|
}
|
|
|
|
bool OptimizedCompilationInfo::has_context() const {
|
|
return !closure().is_null();
|
|
}
|
|
|
|
Context OptimizedCompilationInfo::context() const {
|
|
DCHECK(has_context());
|
|
return closure()->context();
|
|
}
|
|
|
|
bool OptimizedCompilationInfo::has_native_context() const {
|
|
return !closure().is_null() && !closure()->native_context().is_null();
|
|
}
|
|
|
|
Context OptimizedCompilationInfo::native_context() const {
|
|
DCHECK(has_native_context());
|
|
return closure()->native_context();
|
|
}
|
|
|
|
bool OptimizedCompilationInfo::has_global_object() const {
|
|
return has_native_context();
|
|
}
|
|
|
|
JSGlobalObject OptimizedCompilationInfo::global_object() const {
|
|
DCHECK(has_global_object());
|
|
return native_context()->global_object();
|
|
}
|
|
|
|
int OptimizedCompilationInfo::AddInlinedFunction(
|
|
Handle<SharedFunctionInfo> inlined_function,
|
|
Handle<BytecodeArray> inlined_bytecode, SourcePosition pos) {
|
|
int id = static_cast<int>(inlined_functions_.size());
|
|
inlined_functions_.push_back(
|
|
InlinedFunctionHolder(inlined_function, inlined_bytecode, pos));
|
|
return id;
|
|
}
|
|
|
|
void OptimizedCompilationInfo::SetTracingFlags(bool passes_filter) {
|
|
if (!passes_filter) return;
|
|
if (FLAG_trace_turbo) SetFlag(kTraceTurboJson);
|
|
if (FLAG_trace_turbo_graph) SetFlag(kTraceTurboGraph);
|
|
if (FLAG_trace_turbo_scheduled) SetFlag(kTraceTurboScheduled);
|
|
}
|
|
|
|
OptimizedCompilationInfo::InlinedFunctionHolder::InlinedFunctionHolder(
|
|
Handle<SharedFunctionInfo> inlined_shared_info,
|
|
Handle<BytecodeArray> inlined_bytecode, SourcePosition pos)
|
|
: shared_info(inlined_shared_info), bytecode_array(inlined_bytecode) {
|
|
position.position = pos;
|
|
// initialized when generating the deoptimization literals
|
|
position.inlined_function_id = DeoptimizationData::kNotInlinedIndex;
|
|
}
|
|
|
|
std::unique_ptr<v8::tracing::TracedValue>
|
|
OptimizedCompilationInfo::ToTracedValue() {
|
|
auto value = v8::tracing::TracedValue::Create();
|
|
value->SetBoolean("osr", is_osr());
|
|
value->SetBoolean("functionContextSpecialized",
|
|
is_function_context_specializing());
|
|
if (has_shared_info()) {
|
|
value->SetValue("function", shared_info()->TraceIDRef());
|
|
}
|
|
if (bailout_reason() != BailoutReason::kNoReason) {
|
|
value->SetString("bailoutReason", GetBailoutReason(bailout_reason()));
|
|
value->SetBoolean("disableFutureOptimization",
|
|
is_disable_future_optimization());
|
|
} else {
|
|
value->SetInteger("optimizationId", optimization_id());
|
|
value->BeginArray("inlinedFunctions");
|
|
for (auto const& inlined_function : inlined_functions()) {
|
|
value->BeginDictionary();
|
|
value->SetValue("function", inlined_function.shared_info->TraceIDRef());
|
|
// TODO(bmeurer): Also include the source position from the
|
|
// {inlined_function} here as dedicated "sourcePosition" field.
|
|
value->EndDictionary();
|
|
}
|
|
value->EndArray();
|
|
}
|
|
return value;
|
|
}
|
|
|
|
} // namespace internal
|
|
} // namespace v8
|