[objects] Merge SFI outer_scope_info and feedback_metadata
Merge the outer_scope_info and feedback_metadata fields on SharedFunctionInfo. outer_scope_info is only used during parsing, and feedback_metadata is only available after compilation, so the two never exist at the same time. Thus, they can share a field slot. The exception is un-compiling and re-compiling a function, where we need the outer_scope_info again. Fortunately, the outer_scope_info can be re-calculated from the SFI's scope_info. Bug: v8:7606 Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng Change-Id: I6b97fefe859e89df75ad870da4a0bfa4b869772a Reviewed-on: https://chromium-review.googlesource.com/992432 Reviewed-by: Igor Sheludko <ishell@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/master@{#52454}
This commit is contained in:
parent
48d1525daf
commit
6bd1d3c280
14
src/api.cc
14
src/api.cc
@ -734,10 +734,14 @@ StartupData SnapshotCreator::CreateBlob(
|
||||
|
||||
i::HeapIterator heap_iterator(isolate->heap());
|
||||
while (i::HeapObject* current_obj = heap_iterator.next()) {
|
||||
// Complete in-object slack tracking for all functions.
|
||||
if (current_obj->IsJSFunction()) {
|
||||
i::JSFunction* fun = i::JSFunction::cast(current_obj);
|
||||
|
||||
// Complete in-object slack tracking for all functions.
|
||||
fun->CompleteInobjectSlackTrackingIfActive();
|
||||
|
||||
// Also, clear out feedback vectors.
|
||||
fun->feedback_cell()->set_value(isolate->heap()->undefined_value());
|
||||
}
|
||||
|
||||
// Clear out re-compilable data from all shared function infos. Any
|
||||
@ -746,12 +750,8 @@ StartupData SnapshotCreator::CreateBlob(
|
||||
if (current_obj->IsSharedFunctionInfo() &&
|
||||
function_code_handling == FunctionCodeHandling::kClear) {
|
||||
i::SharedFunctionInfo* shared = i::SharedFunctionInfo::cast(current_obj);
|
||||
if (shared->HasBytecodeArray()) {
|
||||
shared->ClearBytecodeArray();
|
||||
} else if (shared->HasAsmWasmData()) {
|
||||
shared->ClearAsmWasmData();
|
||||
} else if (shared->HasPreParsedScopeData()) {
|
||||
shared->ClearPreParsedScopeData();
|
||||
if (shared->CanFlushCompiled()) {
|
||||
shared->FlushCompiled();
|
||||
}
|
||||
DCHECK(shared->HasCodeObject() || shared->HasBuiltinId() ||
|
||||
shared->IsApiFunction());
|
||||
|
@ -77,8 +77,7 @@ UnoptimizedCompileJob::UnoptimizedCompileJob(Isolate* isolate,
|
||||
trace_compiler_dispatcher_jobs_(FLAG_trace_compiler_dispatcher_jobs) {
|
||||
DCHECK(!shared_->is_toplevel());
|
||||
// TODO(rmcilroy): Handle functions with non-empty outer scope info.
|
||||
DCHECK(shared_->outer_scope_info()->IsTheHole(isolate) ||
|
||||
ScopeInfo::cast(shared_->outer_scope_info())->length() == 0);
|
||||
DCHECK(!shared_->HasOuterScopeInfo());
|
||||
HandleScope scope(isolate);
|
||||
Handle<Script> script(Script::cast(shared_->script()), isolate);
|
||||
Handle<String> source(String::cast(script->source()), isolate);
|
||||
@ -206,9 +205,8 @@ void UnoptimizedCompileJob::PrepareOnMainThread(Isolate* isolate) {
|
||||
|
||||
parser_.reset(new Parser(parse_info_.get()));
|
||||
MaybeHandle<ScopeInfo> outer_scope_info;
|
||||
if (!shared_->outer_scope_info()->IsTheHole(isolate) &&
|
||||
ScopeInfo::cast(shared_->outer_scope_info())->length() > 0) {
|
||||
outer_scope_info = handle(ScopeInfo::cast(shared_->outer_scope_info()));
|
||||
if (shared_->HasOuterScopeInfo()) {
|
||||
outer_scope_info = handle(shared_->GetOuterScopeInfo());
|
||||
}
|
||||
parser_->DeserializeScopeChain(parse_info_.get(), outer_scope_info);
|
||||
|
||||
|
@ -283,9 +283,10 @@ void OptimizedCompilationJob::RecordFunctionCompilation(
|
||||
time_taken_to_execute_.InMillisecondsF() +
|
||||
time_taken_to_finalize_.InMillisecondsF();
|
||||
|
||||
LogFunctionCompilation(tag, compilation_info()->shared_info(),
|
||||
parse_info()->script(), abstract_code, true,
|
||||
time_taken_ms, isolate);
|
||||
Handle<Script> script(
|
||||
Script::cast(compilation_info()->shared_info()->script()));
|
||||
LogFunctionCompilation(tag, compilation_info()->shared_info(), script,
|
||||
abstract_code, true, time_taken_ms, isolate);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -293,27 +294,6 @@ void OptimizedCompilationJob::RecordFunctionCompilation(
|
||||
|
||||
namespace {
|
||||
|
||||
void EnsureFeedbackMetadata(UnoptimizedCompilationInfo* compilation_info,
|
||||
Handle<SharedFunctionInfo> shared_info,
|
||||
Isolate* isolate) {
|
||||
// If no type feedback metadata exists, create it. At this point the
|
||||
// AstNumbering pass has already run. Note the snapshot can contain outdated
|
||||
// vectors for a different configuration, hence we also recreate a new vector
|
||||
// when the function is not compiled (i.e. no code was serialized).
|
||||
|
||||
if (shared_info->feedback_metadata()->is_empty() ||
|
||||
!shared_info->is_compiled()) {
|
||||
Handle<FeedbackMetadata> feedback_metadata = FeedbackMetadata::New(
|
||||
isolate, compilation_info->feedback_vector_spec());
|
||||
shared_info->set_feedback_metadata(*feedback_metadata);
|
||||
}
|
||||
|
||||
// It's very important that recompiles do not alter the structure of the type
|
||||
// feedback vector. Verify that the structure fits the function literal.
|
||||
CHECK(!shared_info->feedback_metadata()->SpecDiffersFrom(
|
||||
compilation_info->feedback_vector_spec()));
|
||||
}
|
||||
|
||||
bool UseAsmWasm(FunctionLiteral* literal, bool asm_wasm_broken) {
|
||||
// Check whether asm.js validation is enabled.
|
||||
if (!FLAG_validate_asm) return false;
|
||||
@ -335,23 +315,25 @@ void InstallUnoptimizedCode(UnoptimizedCompilationInfo* compilation_info,
|
||||
DCHECK_EQ(shared_info->language_mode(),
|
||||
compilation_info->literal()->language_mode());
|
||||
|
||||
// Ensure feedback metadata is installed.
|
||||
EnsureFeedbackMetadata(compilation_info, shared_info, isolate);
|
||||
|
||||
// Update the shared function info with the scope info.
|
||||
Handle<ScopeInfo> scope_info = compilation_info->scope()->scope_info();
|
||||
shared_info->set_scope_info(*scope_info);
|
||||
Scope* outer_scope = compilation_info->scope()->GetOuterScopeWithContext();
|
||||
if (outer_scope)
|
||||
shared_info->set_outer_scope_info(*outer_scope->scope_info());
|
||||
|
||||
if (compilation_info->has_bytecode_array()) {
|
||||
DCHECK(!shared_info->HasBytecodeArray()); // Only compiled once.
|
||||
DCHECK(!compilation_info->has_asm_wasm_data());
|
||||
DCHECK(!shared_info->HasFeedbackMetadata());
|
||||
|
||||
Handle<FeedbackMetadata> feedback_metadata = FeedbackMetadata::New(
|
||||
isolate, compilation_info->feedback_vector_spec());
|
||||
|
||||
shared_info->set_bytecode_array(*compilation_info->bytecode_array());
|
||||
shared_info->set_feedback_metadata(*feedback_metadata);
|
||||
} else {
|
||||
DCHECK(compilation_info->has_asm_wasm_data());
|
||||
shared_info->set_asm_wasm_data(*compilation_info->asm_wasm_data());
|
||||
shared_info->set_feedback_metadata(
|
||||
isolate->heap()->empty_feedback_metadata());
|
||||
}
|
||||
|
||||
// Install coverage info on the shared function info.
|
||||
@ -690,7 +672,6 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function,
|
||||
std::unique_ptr<OptimizedCompilationJob> job(
|
||||
compiler::Pipeline::NewCompilationJob(function, has_script));
|
||||
OptimizedCompilationInfo* compilation_info = job->compilation_info();
|
||||
ParseInfo* parse_info = job->parse_info();
|
||||
|
||||
compilation_info->SetOptimizingForOsr(osr_offset, osr_frame);
|
||||
|
||||
@ -734,7 +715,6 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function,
|
||||
|
||||
// Reopen handles in the new CompilationHandleScope.
|
||||
compilation_info->ReopenHandlesInNewHandleScope();
|
||||
parse_info->ReopenHandlesInNewHandleScope();
|
||||
|
||||
if (mode == ConcurrencyMode::kConcurrent) {
|
||||
if (GetOptimizedCodeLater(job.get(), isolate)) {
|
||||
@ -843,9 +823,8 @@ MaybeHandle<SharedFunctionInfo> FinalizeTopLevel(
|
||||
DCHECK_EQ(kNoSourcePosition,
|
||||
parse_info->literal()->function_token_position());
|
||||
Handle<SharedFunctionInfo> shared_info =
|
||||
isolate->factory()->NewSharedFunctionInfoForLiteral(parse_info->literal(),
|
||||
parse_info->script());
|
||||
shared_info->set_is_toplevel(true);
|
||||
isolate->factory()->NewSharedFunctionInfoForLiteral(
|
||||
parse_info->literal(), parse_info->script(), true);
|
||||
|
||||
// Finalize compilation of the unoptimized bytecode or asm-js data.
|
||||
if (!FinalizeUnoptimizedCode(parse_info, isolate, shared_info,
|
||||
@ -1900,12 +1879,8 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
|
||||
|
||||
// Allocate a shared function info object which will be compiled lazily.
|
||||
Handle<SharedFunctionInfo> result =
|
||||
isolate->factory()->NewSharedFunctionInfoForLiteral(literal, script);
|
||||
result->set_is_toplevel(false);
|
||||
Scope* outer_scope = literal->scope()->GetOuterScopeWithContext();
|
||||
if (outer_scope) {
|
||||
result->set_outer_scope_info(*outer_scope->scope_info());
|
||||
}
|
||||
isolate->factory()->NewSharedFunctionInfoForLiteral(literal, script,
|
||||
false);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -268,12 +268,11 @@ class UnoptimizedCompilationJob : public CompilationJob {
|
||||
// Each of the three phases can either fail or succeed.
|
||||
class OptimizedCompilationJob : public CompilationJob {
|
||||
public:
|
||||
OptimizedCompilationJob(uintptr_t stack_limit, ParseInfo* parse_info,
|
||||
OptimizedCompilationJob(uintptr_t stack_limit,
|
||||
OptimizedCompilationInfo* compilation_info,
|
||||
const char* compiler_name,
|
||||
State initial_state = State::kReadyToPrepare)
|
||||
: CompilationJob(stack_limit, initial_state),
|
||||
parse_info_(parse_info),
|
||||
compilation_info_(compilation_info),
|
||||
compiler_name_(compiler_name) {}
|
||||
|
||||
@ -299,7 +298,6 @@ class OptimizedCompilationJob : public CompilationJob {
|
||||
void RecordFunctionCompilation(CodeEventListener::LogEventsAndTags tag,
|
||||
Isolate* isolate) const;
|
||||
|
||||
ParseInfo* parse_info() const { return parse_info_; }
|
||||
OptimizedCompilationInfo* compilation_info() const {
|
||||
return compilation_info_;
|
||||
}
|
||||
@ -312,8 +310,6 @@ class OptimizedCompilationJob : public CompilationJob {
|
||||
virtual Status FinalizeJobImpl(Isolate* isolate) = 0;
|
||||
|
||||
private:
|
||||
// TODO(rmcilroy): Remove parse_info.
|
||||
ParseInfo* parse_info_;
|
||||
OptimizedCompilationInfo* compilation_info_;
|
||||
base::TimeDelta time_taken_to_prepare_;
|
||||
base::TimeDelta time_taken_to_execute_;
|
||||
|
@ -744,21 +744,21 @@ PipelineStatistics* CreatePipelineStatistics(Handle<Script> script,
|
||||
|
||||
class PipelineCompilationJob final : public OptimizedCompilationJob {
|
||||
public:
|
||||
PipelineCompilationJob(ParseInfo* parse_info,
|
||||
Handle<SharedFunctionInfo> shared_info,
|
||||
PipelineCompilationJob(Handle<SharedFunctionInfo> shared_info,
|
||||
Handle<JSFunction> function)
|
||||
// Note that the OptimizedCompilationInfo is not initialized at the time
|
||||
// we pass it to the CompilationJob constructor, but it is not
|
||||
// dereferenced there.
|
||||
: OptimizedCompilationJob(parse_info->stack_limit(), parse_info,
|
||||
&compilation_info_, "TurboFan"),
|
||||
parse_info_(parse_info),
|
||||
: OptimizedCompilationJob(
|
||||
function->GetIsolate()->stack_guard()->real_climit(),
|
||||
&compilation_info_, "TurboFan"),
|
||||
zone_(function->GetIsolate()->allocator(), ZONE_NAME),
|
||||
zone_stats_(function->GetIsolate()->allocator()),
|
||||
compilation_info_(parse_info_.get()->zone(), function->GetIsolate(),
|
||||
shared_info, function),
|
||||
pipeline_statistics_(
|
||||
CreatePipelineStatistics(parse_info_->script(), compilation_info(),
|
||||
function->GetIsolate(), &zone_stats_)),
|
||||
compilation_info_(&zone_, function->GetIsolate(), shared_info,
|
||||
function),
|
||||
pipeline_statistics_(CreatePipelineStatistics(
|
||||
handle(Script::cast(shared_info->script())), compilation_info(),
|
||||
function->GetIsolate(), &zone_stats_)),
|
||||
data_(&zone_stats_, function->GetIsolate(), compilation_info(),
|
||||
pipeline_statistics_.get()),
|
||||
pipeline_(&data_),
|
||||
@ -773,7 +773,7 @@ class PipelineCompilationJob final : public OptimizedCompilationJob {
|
||||
void RegisterWeakObjectsInOptimizedCode(Handle<Code> code, Isolate* isolate);
|
||||
|
||||
private:
|
||||
std::unique_ptr<ParseInfo> parse_info_;
|
||||
Zone zone_;
|
||||
ZoneStats zone_stats_;
|
||||
OptimizedCompilationInfo compilation_info_;
|
||||
std::unique_ptr<PipelineStatistics> pipeline_statistics_;
|
||||
@ -889,8 +889,8 @@ class PipelineWasmCompilationJob final : public OptimizedCompilationJob {
|
||||
OptimizedCompilationInfo* info, Isolate* isolate, JSGraph* jsgraph,
|
||||
CallDescriptor* call_descriptor, SourcePositionTable* source_positions,
|
||||
WasmCompilationData* wasm_compilation_data, bool asmjs_origin)
|
||||
: OptimizedCompilationJob(isolate->stack_guard()->real_climit(), nullptr,
|
||||
info, "TurboFan", State::kReadyToExecute),
|
||||
: OptimizedCompilationJob(isolate->stack_guard()->real_climit(), info,
|
||||
"TurboFan", State::kReadyToExecute),
|
||||
zone_stats_(isolate->allocator()),
|
||||
pipeline_statistics_(CreatePipelineStatistics(
|
||||
Handle<Script>::null(), info, isolate, &zone_stats_)),
|
||||
@ -2075,13 +2075,7 @@ Handle<Code> Pipeline::GenerateCodeForTesting(
|
||||
OptimizedCompilationJob* 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, shared, function);
|
||||
return new PipelineCompilationJob(shared, function);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -826,7 +826,7 @@ void LiveEdit::ReplaceFunctionCode(
|
||||
if (shared_info->is_compiled()) {
|
||||
// Clear old bytecode. This will trigger self-healing if we do not install
|
||||
// new bytecode.
|
||||
shared_info->ClearBytecodeArray();
|
||||
shared_info->FlushCompiled();
|
||||
shared_info->set_bytecode_array(new_shared_info->bytecode_array());
|
||||
|
||||
if (shared_info->HasBreakInfo()) {
|
||||
@ -835,16 +835,12 @@ void LiveEdit::ReplaceFunctionCode(
|
||||
handle(shared_info->GetDebugInfo()));
|
||||
}
|
||||
shared_info->set_scope_info(new_shared_info->scope_info());
|
||||
shared_info->set_outer_scope_info(new_shared_info->outer_scope_info());
|
||||
shared_info->set_feedback_metadata(new_shared_info->feedback_metadata());
|
||||
shared_info->DisableOptimization(BailoutReason::kLiveEdit);
|
||||
// Update the type feedback vector, if needed.
|
||||
Handle<FeedbackMetadata> new_feedback_metadata(
|
||||
new_shared_info->feedback_metadata());
|
||||
shared_info->set_feedback_metadata(*new_feedback_metadata);
|
||||
} else {
|
||||
// Use an empty FeedbackMetadata.
|
||||
Handle<FeedbackMetadata> feedback_metadata = FeedbackMetadata::New(isolate);
|
||||
shared_info->set_feedback_metadata(*feedback_metadata);
|
||||
// There should not be any feedback metadata. Keep the outer scope info the
|
||||
// same.
|
||||
DCHECK(!shared_info->HasFeedbackMetadata());
|
||||
}
|
||||
|
||||
int start_position = compile_info_wrapper.GetStartPosition();
|
||||
|
@ -2545,11 +2545,11 @@ void Factory::ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object,
|
||||
}
|
||||
|
||||
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForLiteral(
|
||||
FunctionLiteral* literal, Handle<Script> script) {
|
||||
FunctionLiteral* literal, Handle<Script> script, bool is_toplevel) {
|
||||
FunctionKind kind = literal->kind();
|
||||
Handle<SharedFunctionInfo> shared = NewSharedFunctionInfoForBuiltin(
|
||||
literal->name(), Builtins::kCompileLazy, kind);
|
||||
SharedFunctionInfo::InitFromFunctionLiteral(shared, literal);
|
||||
SharedFunctionInfo::InitFromFunctionLiteral(shared, literal, is_toplevel);
|
||||
SharedFunctionInfo::SetScript(shared, script, false);
|
||||
return shared;
|
||||
}
|
||||
@ -2577,14 +2577,16 @@ Handle<JSMessageObject> Factory::NewJSMessageObject(
|
||||
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForApiFunction(
|
||||
MaybeHandle<String> maybe_name,
|
||||
Handle<FunctionTemplateInfo> function_template_info, FunctionKind kind) {
|
||||
return NewSharedFunctionInfo(maybe_name, function_template_info,
|
||||
Builtins::kNoBuiltinId, kind);
|
||||
Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(
|
||||
maybe_name, function_template_info, Builtins::kNoBuiltinId, kind);
|
||||
return shared;
|
||||
}
|
||||
|
||||
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForBuiltin(
|
||||
MaybeHandle<String> maybe_name, int builtin_index, FunctionKind kind) {
|
||||
return NewSharedFunctionInfo(maybe_name, MaybeHandle<Code>(), builtin_index,
|
||||
kind);
|
||||
Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(
|
||||
maybe_name, MaybeHandle<Code>(), builtin_index, kind);
|
||||
return shared;
|
||||
}
|
||||
|
||||
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
|
||||
@ -2621,12 +2623,19 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
|
||||
} else {
|
||||
share->set_builtin_id(Builtins::kIllegal);
|
||||
}
|
||||
share->set_outer_scope_info(*the_hole_value());
|
||||
// Generally functions won't have feedback, unless they have been created
|
||||
// from a FunctionLiteral. Those can just reset this field to keep the
|
||||
// SharedFunctionInfo in a consistent state.
|
||||
if (maybe_builtin_index == Builtins::kCompileLazy) {
|
||||
share->set_raw_outer_scope_info_or_feedback_metadata(*the_hole_value(),
|
||||
SKIP_WRITE_BARRIER);
|
||||
} else {
|
||||
share->set_raw_outer_scope_info_or_feedback_metadata(
|
||||
*empty_feedback_metadata(), SKIP_WRITE_BARRIER);
|
||||
}
|
||||
share->set_script(*undefined_value(), SKIP_WRITE_BARRIER);
|
||||
share->set_debug_info(Smi::kZero, SKIP_WRITE_BARRIER);
|
||||
share->set_function_identifier(*undefined_value(), SKIP_WRITE_BARRIER);
|
||||
share->set_feedback_metadata(isolate()->heap()->empty_feedback_metadata(),
|
||||
SKIP_WRITE_BARRIER);
|
||||
share->set_function_literal_id(FunctionLiteral::kIdTypeInvalid);
|
||||
#if V8_SFI_HAS_UNIQUE_ID
|
||||
share->set_unique_id(isolate()->GetNextUniqueSharedFunctionInfoId());
|
||||
|
@ -805,7 +805,7 @@ class V8_EXPORT_PRIVATE Factory final {
|
||||
FunctionKind kind = kNormalFunction);
|
||||
|
||||
Handle<SharedFunctionInfo> NewSharedFunctionInfoForLiteral(
|
||||
FunctionLiteral* literal, Handle<Script> script);
|
||||
FunctionLiteral* literal, Handle<Script> script, bool is_toplevel);
|
||||
|
||||
static bool IsFunctionModeWithPrototype(FunctionMode function_mode) {
|
||||
return (function_mode & kWithPrototypeBits) != 0;
|
||||
|
@ -1910,8 +1910,8 @@ void AccessorAssembler::BranchIfStrictMode(Node* vector, Node* slot,
|
||||
Label* if_strict) {
|
||||
Node* sfi =
|
||||
LoadObjectField(vector, FeedbackVector::kSharedFunctionInfoOffset);
|
||||
Node* metadata =
|
||||
LoadObjectField(sfi, SharedFunctionInfo::kFeedbackMetadataOffset);
|
||||
TNode<FeedbackMetadata> metadata = CAST(LoadObjectField(
|
||||
sfi, SharedFunctionInfo::kOuterScopeInfoOrFeedbackMetadataOffset));
|
||||
Node* slot_int = SmiToInt32(slot);
|
||||
|
||||
// See VectorICComputer::index().
|
||||
|
@ -864,10 +864,9 @@ void SharedFunctionInfo::SharedFunctionInfoVerify() {
|
||||
|
||||
VerifyObjectField(kFunctionDataOffset);
|
||||
VerifyObjectField(kDebugInfoOffset);
|
||||
VerifyObjectField(kFeedbackMetadataOffset);
|
||||
VerifyObjectField(kOuterScopeInfoOrFeedbackMetadataOffset);
|
||||
VerifyObjectField(kFunctionIdentifierOffset);
|
||||
VerifyObjectField(kNameOrScopeInfoOffset);
|
||||
VerifyObjectField(kOuterScopeInfoOffset);
|
||||
VerifyObjectField(kScriptOffset);
|
||||
|
||||
Object* value = name_or_scope_info();
|
||||
@ -885,6 +884,15 @@ void SharedFunctionInfo::SharedFunctionInfoVerify() {
|
||||
CHECK(function_identifier()->IsUndefined(isolate) || HasBuiltinFunctionId() ||
|
||||
HasInferredName());
|
||||
|
||||
if (!is_compiled()) {
|
||||
CHECK(!HasFeedbackMetadata());
|
||||
CHECK(outer_scope_info()->IsScopeInfo() ||
|
||||
outer_scope_info()->IsTheHole(isolate));
|
||||
} else if (HasBytecodeArray()) {
|
||||
CHECK(HasFeedbackMetadata());
|
||||
CHECK(feedback_metadata()->IsFeedbackMetadata());
|
||||
}
|
||||
|
||||
int expected_map_index = Context::FunctionMapIndex(
|
||||
language_mode(), kind(), true, HasSharedName(), needs_home_object());
|
||||
CHECK_EQ(expected_map_index, function_map_index());
|
||||
|
@ -1286,9 +1286,16 @@ void SharedFunctionInfo::SharedFunctionInfoPrint(std::ostream& os) { // NOLINT
|
||||
os << "\n - no debug info";
|
||||
}
|
||||
os << "\n - scope info: " << Brief(scope_info());
|
||||
if (HasOuterScopeInfo()) {
|
||||
os << "\n - outer scope info: " << Brief(GetOuterScopeInfo());
|
||||
}
|
||||
os << "\n - length: " << length();
|
||||
os << "\n - feedback_metadata: ";
|
||||
feedback_metadata()->FeedbackMetadataPrint(os);
|
||||
if (HasFeedbackMetadata()) {
|
||||
feedback_metadata()->FeedbackMetadataPrint(os);
|
||||
} else {
|
||||
os << "<none>";
|
||||
}
|
||||
os << "\n";
|
||||
}
|
||||
|
||||
|
@ -13872,7 +13872,8 @@ void SharedFunctionInfo::DisableOptimization(BailoutReason reason) {
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::InitFromFunctionLiteral(
|
||||
Handle<SharedFunctionInfo> shared_info, FunctionLiteral* lit) {
|
||||
Handle<SharedFunctionInfo> shared_info, FunctionLiteral* lit,
|
||||
bool is_toplevel) {
|
||||
// When adding fields here, make sure DeclarationScope::AnalyzePartially is
|
||||
// updated accordingly.
|
||||
shared_info->set_internal_formal_parameter_count(lit->parameter_count());
|
||||
@ -13899,6 +13900,16 @@ void SharedFunctionInfo::InitFromFunctionLiteral(
|
||||
IsClassConstructor(lit->kind()));
|
||||
shared_info->set_requires_instance_fields_initializer(
|
||||
lit->requires_instance_fields_initializer());
|
||||
|
||||
shared_info->set_is_toplevel(is_toplevel);
|
||||
DCHECK(shared_info->outer_scope_info()->IsTheHole(shared_info->GetIsolate()));
|
||||
if (!is_toplevel) {
|
||||
Scope* outer_scope = lit->scope()->GetOuterScopeWithContext();
|
||||
if (outer_scope) {
|
||||
shared_info->set_outer_scope_info(*outer_scope->scope_info());
|
||||
}
|
||||
}
|
||||
|
||||
// For lazy parsed functions, the following flags will be inaccurate since we
|
||||
// don't have the information yet. They're set later in
|
||||
// SetSharedFunctionFlagsFromLiteral (compiler.cc), when the function is
|
||||
|
@ -25,8 +25,6 @@ DEFINE_DEOPT_ELEMENT_ACCESSORS(SharedFunctionInfo, Object)
|
||||
|
||||
ACCESSORS(SharedFunctionInfo, name_or_scope_info, Object,
|
||||
kNameOrScopeInfoOffset)
|
||||
ACCESSORS(SharedFunctionInfo, feedback_metadata, FeedbackMetadata,
|
||||
kFeedbackMetadataOffset)
|
||||
ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
|
||||
ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
|
||||
ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
|
||||
@ -331,8 +329,56 @@ void SharedFunctionInfo::set_scope_info(ScopeInfo* scope_info,
|
||||
reinterpret_cast<Object*>(scope_info), mode);
|
||||
}
|
||||
|
||||
ACCESSORS(SharedFunctionInfo, outer_scope_info, HeapObject,
|
||||
kOuterScopeInfoOffset)
|
||||
ACCESSORS(SharedFunctionInfo, raw_outer_scope_info_or_feedback_metadata,
|
||||
HeapObject, kOuterScopeInfoOrFeedbackMetadataOffset)
|
||||
|
||||
HeapObject* SharedFunctionInfo::outer_scope_info() const {
|
||||
DCHECK(!is_compiled());
|
||||
DCHECK(!HasFeedbackMetadata());
|
||||
return raw_outer_scope_info_or_feedback_metadata();
|
||||
}
|
||||
|
||||
bool SharedFunctionInfo::HasOuterScopeInfo() const {
|
||||
ScopeInfo* outer_info = nullptr;
|
||||
if (!is_compiled()) {
|
||||
if (!outer_scope_info()->IsScopeInfo()) return false;
|
||||
outer_info = ScopeInfo::cast(outer_scope_info());
|
||||
} else {
|
||||
if (!scope_info()->HasOuterScopeInfo()) return false;
|
||||
outer_info = scope_info()->OuterScopeInfo();
|
||||
}
|
||||
return outer_info->length() > 0;
|
||||
}
|
||||
|
||||
ScopeInfo* SharedFunctionInfo::GetOuterScopeInfo() const {
|
||||
DCHECK(HasOuterScopeInfo());
|
||||
if (!is_compiled()) return ScopeInfo::cast(outer_scope_info());
|
||||
return scope_info()->OuterScopeInfo();
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::set_outer_scope_info(HeapObject* value,
|
||||
WriteBarrierMode mode) {
|
||||
DCHECK(!is_compiled());
|
||||
DCHECK(raw_outer_scope_info_or_feedback_metadata()->IsTheHole(GetIsolate()));
|
||||
DCHECK(value->IsScopeInfo() || value->IsTheHole(GetIsolate()));
|
||||
return set_raw_outer_scope_info_or_feedback_metadata(value, mode);
|
||||
}
|
||||
|
||||
bool SharedFunctionInfo::HasFeedbackMetadata() const {
|
||||
return raw_outer_scope_info_or_feedback_metadata()->IsFeedbackMetadata();
|
||||
}
|
||||
|
||||
FeedbackMetadata* SharedFunctionInfo::feedback_metadata() const {
|
||||
DCHECK(HasFeedbackMetadata());
|
||||
return FeedbackMetadata::cast(raw_outer_scope_info_or_feedback_metadata());
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::set_feedback_metadata(FeedbackMetadata* value,
|
||||
WriteBarrierMode mode) {
|
||||
DCHECK(!HasFeedbackMetadata());
|
||||
DCHECK(value->IsFeedbackMetadata());
|
||||
return set_raw_outer_scope_info_or_feedback_metadata(value, mode);
|
||||
}
|
||||
|
||||
bool SharedFunctionInfo::is_compiled() const {
|
||||
Object* data = function_data();
|
||||
@ -384,12 +430,6 @@ void SharedFunctionInfo::set_bytecode_array(BytecodeArray* bytecode) {
|
||||
set_function_data(bytecode);
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::ClearBytecodeArray() {
|
||||
DCHECK(function_data() == Smi::FromEnum(Builtins::kCompileLazy) ||
|
||||
HasBytecodeArray());
|
||||
set_builtin_id(Builtins::kCompileLazy);
|
||||
}
|
||||
|
||||
bool SharedFunctionInfo::HasAsmWasmData() const {
|
||||
return function_data()->IsFixedArray();
|
||||
}
|
||||
@ -405,11 +445,6 @@ void SharedFunctionInfo::set_asm_wasm_data(FixedArray* data) {
|
||||
set_function_data(data);
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::ClearAsmWasmData() {
|
||||
DCHECK(HasAsmWasmData());
|
||||
set_builtin_id(Builtins::kCompileLazy);
|
||||
}
|
||||
|
||||
bool SharedFunctionInfo::HasBuiltinId() const {
|
||||
return function_data()->IsSmi();
|
||||
}
|
||||
@ -494,6 +529,36 @@ bool SharedFunctionInfo::IsSubjectToDebugging() {
|
||||
return IsUserJavaScript() && !HasAsmWasmData();
|
||||
}
|
||||
|
||||
bool SharedFunctionInfo::CanFlushCompiled() const {
|
||||
bool can_decompile =
|
||||
(HasBytecodeArray() || HasAsmWasmData() || HasPreParsedScopeData());
|
||||
return can_decompile;
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::FlushCompiled() {
|
||||
DisallowHeapAllocation no_gc;
|
||||
|
||||
DCHECK(CanFlushCompiled());
|
||||
|
||||
Oddball* the_hole = GetIsolate()->heap()->the_hole_value();
|
||||
|
||||
if (is_compiled()) {
|
||||
HeapObject* outer_scope_info = the_hole;
|
||||
if (!is_toplevel()) {
|
||||
if (scope_info()->HasOuterScopeInfo()) {
|
||||
outer_scope_info = scope_info()->OuterScopeInfo();
|
||||
}
|
||||
}
|
||||
// Raw setter to avoid validity checks, since we're performing the unusual
|
||||
// task of decompiling.
|
||||
set_raw_outer_scope_info_or_feedback_metadata(outer_scope_info);
|
||||
} else {
|
||||
DCHECK(outer_scope_info()->IsScopeInfo() || is_toplevel());
|
||||
}
|
||||
|
||||
set_builtin_id(Builtins::kCompileLazy);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
|
@ -92,9 +92,18 @@ class SharedFunctionInfo : public HeapObject {
|
||||
// Start position of this function in the script source.
|
||||
inline int StartPosition() const;
|
||||
|
||||
// The outer scope info for the purpose of parsing this function, or the hole
|
||||
// value if it isn't yet known.
|
||||
DECL_ACCESSORS(outer_scope_info, HeapObject)
|
||||
// [outer scope info | feedback metadata] Shared storage for outer scope info
|
||||
// (on uncompiled functions) and feedback metadata (on compiled functions).
|
||||
DECL_ACCESSORS(raw_outer_scope_info_or_feedback_metadata, HeapObject)
|
||||
|
||||
// Get the outer scope info whether this function is compiled or not.
|
||||
inline bool HasOuterScopeInfo() const;
|
||||
inline ScopeInfo* GetOuterScopeInfo() const;
|
||||
|
||||
// [feedback metadata] Metadata template for feedback vectors of instances of
|
||||
// this function.
|
||||
inline bool HasFeedbackMetadata() const;
|
||||
DECL_ACCESSORS(feedback_metadata, FeedbackMetadata)
|
||||
|
||||
// Returns if this function has been compiled to native code yet.
|
||||
inline bool is_compiled() const;
|
||||
@ -119,11 +128,6 @@ class SharedFunctionInfo : public HeapObject {
|
||||
// function. The value is only reliable when the function has been compiled.
|
||||
DECL_INT_ACCESSORS(expected_nof_properties)
|
||||
|
||||
// [feedback_metadata] - describes ast node feedback from full-codegen and
|
||||
// (increasingly) from crankshafted code where sufficient feedback isn't
|
||||
// available.
|
||||
DECL_ACCESSORS(feedback_metadata, FeedbackMetadata)
|
||||
|
||||
// [function_literal_id] - uniquely identifies the FunctionLiteral this
|
||||
// SharedFunctionInfo represents within its script, or -1 if this
|
||||
// SharedFunctionInfo object doesn't correspond to a parsed FunctionLiteral.
|
||||
@ -151,11 +155,9 @@ class SharedFunctionInfo : public HeapObject {
|
||||
inline bool HasBytecodeArray() const;
|
||||
inline BytecodeArray* bytecode_array() const;
|
||||
inline void set_bytecode_array(BytecodeArray* bytecode);
|
||||
inline void ClearBytecodeArray();
|
||||
inline bool HasAsmWasmData() const;
|
||||
inline FixedArray* asm_wasm_data() const;
|
||||
inline void set_asm_wasm_data(FixedArray* data);
|
||||
inline void ClearAsmWasmData();
|
||||
// A brief note to clear up possible confusion:
|
||||
// builtin_id corresponds to the auto-generated
|
||||
// Builtins::Name id, while builtin_function_id corresponds to
|
||||
@ -364,6 +366,14 @@ class SharedFunctionInfo : public HeapObject {
|
||||
// Whether this function is defined in user-provided JavaScript code.
|
||||
inline bool IsUserJavaScript();
|
||||
|
||||
// True if one can flush compiled code from this function, in such a way that
|
||||
// it can later be re-compiled.
|
||||
inline bool CanFlushCompiled() const;
|
||||
|
||||
// Flush compiled data from this function, setting it back to CompileLazy and
|
||||
// clearing any feedback metadata.
|
||||
inline void FlushCompiled();
|
||||
|
||||
// Check whether or not this function is inlineable.
|
||||
bool IsInlineable();
|
||||
|
||||
@ -377,7 +387,7 @@ class SharedFunctionInfo : public HeapObject {
|
||||
|
||||
// Initialize a SharedFunctionInfo from a parsed function literal.
|
||||
static void InitFromFunctionLiteral(Handle<SharedFunctionInfo> shared_info,
|
||||
FunctionLiteral* lit);
|
||||
FunctionLiteral* lit, bool is_toplevel);
|
||||
|
||||
// Sets the expected number of properties based on estimate from parser.
|
||||
void SetExpectedNofPropertiesFromEstimate(FunctionLiteral* literal);
|
||||
@ -443,28 +453,27 @@ class SharedFunctionInfo : public HeapObject {
|
||||
#endif
|
||||
|
||||
// Layout description.
|
||||
#define SHARED_FUNCTION_INFO_FIELDS(V) \
|
||||
/* Pointer fields. */ \
|
||||
V(kStartOfPointerFieldsOffset, 0) \
|
||||
V(kFunctionDataOffset, kPointerSize) \
|
||||
V(kNameOrScopeInfoOffset, kPointerSize) \
|
||||
V(kOuterScopeInfoOffset, kPointerSize) \
|
||||
V(kScriptOffset, kPointerSize) \
|
||||
V(kDebugInfoOffset, kPointerSize) \
|
||||
V(kFunctionIdentifierOffset, kPointerSize) \
|
||||
V(kFeedbackMetadataOffset, kPointerSize) \
|
||||
V(kEndOfPointerFieldsOffset, 0) \
|
||||
/* Raw data fields. */ \
|
||||
V(kFunctionLiteralIdOffset, kInt32Size) \
|
||||
V(kUniqueIdOffset, kUniqueIdFieldSize) \
|
||||
V(kLengthOffset, kInt32Size) \
|
||||
V(kFormalParameterCountOffset, kInt32Size) \
|
||||
V(kExpectedNofPropertiesOffset, kInt32Size) \
|
||||
V(kStartPositionAndTypeOffset, kInt32Size) \
|
||||
V(kEndPositionOffset, kInt32Size) \
|
||||
V(kFunctionTokenPositionOffset, kInt32Size) \
|
||||
V(kFlagsOffset, kInt32Size) \
|
||||
/* Total size. */ \
|
||||
#define SHARED_FUNCTION_INFO_FIELDS(V) \
|
||||
/* Pointer fields. */ \
|
||||
V(kStartOfPointerFieldsOffset, 0) \
|
||||
V(kFunctionDataOffset, kPointerSize) \
|
||||
V(kNameOrScopeInfoOffset, kPointerSize) \
|
||||
V(kOuterScopeInfoOrFeedbackMetadataOffset, kPointerSize) \
|
||||
V(kScriptOffset, kPointerSize) \
|
||||
V(kDebugInfoOffset, kPointerSize) \
|
||||
V(kFunctionIdentifierOffset, kPointerSize) \
|
||||
V(kEndOfPointerFieldsOffset, 0) \
|
||||
/* Raw data fields. */ \
|
||||
V(kFunctionLiteralIdOffset, kInt32Size) \
|
||||
V(kUniqueIdOffset, kUniqueIdFieldSize) \
|
||||
V(kLengthOffset, kInt32Size) \
|
||||
V(kFormalParameterCountOffset, kInt32Size) \
|
||||
V(kExpectedNofPropertiesOffset, kInt32Size) \
|
||||
V(kStartPositionAndTypeOffset, kInt32Size) \
|
||||
V(kEndPositionOffset, kInt32Size) \
|
||||
V(kFunctionTokenPositionOffset, kInt32Size) \
|
||||
V(kFlagsOffset, kInt32Size) \
|
||||
/* Total size. */ \
|
||||
V(kSize, 0)
|
||||
|
||||
DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize,
|
||||
@ -543,6 +552,10 @@ class SharedFunctionInfo : public HeapObject {
|
||||
// ScopeInfo.
|
||||
DECL_ACCESSORS(name_or_scope_info, Object)
|
||||
|
||||
// [outer scope info] The outer scope info, needed to lazily parse this
|
||||
// function.
|
||||
DECL_ACCESSORS(outer_scope_info, HeapObject)
|
||||
|
||||
inline void set_kind(FunctionKind kind);
|
||||
|
||||
inline void set_needs_home_object(bool value);
|
||||
|
@ -66,10 +66,8 @@ ParseInfo::ParseInfo(Handle<SharedFunctionInfo> shared)
|
||||
set_module(script->origin_options().IsModule());
|
||||
DCHECK(!(is_eval() && is_module()));
|
||||
|
||||
Handle<HeapObject> scope_info(shared->outer_scope_info());
|
||||
if (!scope_info->IsTheHole(isolate) &&
|
||||
Handle<ScopeInfo>::cast(scope_info)->length() > 0) {
|
||||
set_outer_scope_info(Handle<ScopeInfo>::cast(scope_info));
|
||||
if (shared->HasOuterScopeInfo()) {
|
||||
set_outer_scope_info(handle(shared->GetOuterScopeInfo()));
|
||||
}
|
||||
|
||||
// CollectTypeProfile uses its own feedback slots. If we have existing
|
||||
@ -77,9 +75,9 @@ ParseInfo::ParseInfo(Handle<SharedFunctionInfo> shared)
|
||||
// has the appropriate slots.
|
||||
set_collect_type_profile(
|
||||
isolate->is_collecting_type_profile() &&
|
||||
(shared->feedback_metadata()->is_empty()
|
||||
? script->IsUserJavaScript()
|
||||
: shared->feedback_metadata()->HasTypeProfileSlot()));
|
||||
(shared->HasFeedbackMetadata()
|
||||
? shared->feedback_metadata()->HasTypeProfileSlot()
|
||||
: script->IsUserJavaScript()));
|
||||
if (block_coverage_enabled() && script->IsUserJavaScript()) {
|
||||
AllocateSourceRangeMap();
|
||||
}
|
||||
@ -136,7 +134,7 @@ ParseInfo* ParseInfo::AllocateWithoutScript(Handle<SharedFunctionInfo> shared) {
|
||||
p->set_module(false);
|
||||
DCHECK_NE(shared->kind(), FunctionKind::kModule);
|
||||
|
||||
Handle<HeapObject> scope_info(shared->outer_scope_info());
|
||||
Handle<HeapObject> scope_info(shared->GetOuterScopeInfo());
|
||||
if (!scope_info->IsTheHole(isolate) &&
|
||||
Handle<ScopeInfo>::cast(scope_info)->length() > 0) {
|
||||
p->set_outer_scope_info(Handle<ScopeInfo>::cast(scope_info));
|
||||
|
@ -1186,12 +1186,12 @@ void V8HeapExplorer::ExtractSharedFunctionInfoReferences(
|
||||
SetInternalReference(obj, entry, "function_identifier",
|
||||
shared->function_identifier(),
|
||||
SharedFunctionInfo::kFunctionIdentifierOffset);
|
||||
SetInternalReference(obj, entry, "feedback_metadata",
|
||||
shared->feedback_metadata(),
|
||||
SharedFunctionInfo::kFeedbackMetadataOffset);
|
||||
SetInternalReference(
|
||||
obj, entry, "raw_outer_scope_info_or_feedback_metadata",
|
||||
shared->raw_outer_scope_info_or_feedback_metadata(),
|
||||
SharedFunctionInfo::kOuterScopeInfoOrFeedbackMetadataOffset);
|
||||
}
|
||||
|
||||
|
||||
void V8HeapExplorer::ExtractScriptReferences(int entry, Script* script) {
|
||||
HeapObject* obj = script;
|
||||
SetInternalReference(obj, entry,
|
||||
|
@ -132,7 +132,7 @@ RUNTIME_FUNCTION(Runtime_InstantiateAsmJs) {
|
||||
// Remove wasm data, mark as broken for asm->wasm, replace function code with
|
||||
// CompileLazy, and return a smi 0 to indicate failure.
|
||||
if (function->shared()->HasAsmWasmData()) {
|
||||
function->shared()->ClearAsmWasmData();
|
||||
function->shared()->FlushCompiled();
|
||||
}
|
||||
function->shared()->set_is_asm_wasm_broken(true);
|
||||
DCHECK(function->code() ==
|
||||
|
@ -116,7 +116,8 @@ RUNTIME_FUNCTION(Runtime_SetCode) {
|
||||
// of the target shared function info.
|
||||
target_shared->set_function_data(source_shared->function_data());
|
||||
target_shared->set_length(source_shared->GetLength());
|
||||
target_shared->set_feedback_metadata(source_shared->feedback_metadata());
|
||||
target_shared->set_raw_outer_scope_info_or_feedback_metadata(
|
||||
source_shared->raw_outer_scope_info_or_feedback_metadata());
|
||||
target_shared->set_internal_formal_parameter_count(
|
||||
source_shared->internal_formal_parameter_count());
|
||||
target_shared->set_raw_start_position_and_type(
|
||||
@ -128,7 +129,6 @@ RUNTIME_FUNCTION(Runtime_SetCode) {
|
||||
target_shared->set_function_literal_id(source_shared->function_literal_id());
|
||||
|
||||
target_shared->set_scope_info(source_shared->scope_info());
|
||||
target_shared->set_outer_scope_info(source_shared->outer_scope_info());
|
||||
|
||||
Handle<Object> source_script(source_shared->script(), isolate);
|
||||
if (source_script->IsScript()) {
|
||||
|
@ -138,9 +138,9 @@ Handle<JSFunction> FunctionTester::ForMachineGraph(Graph* graph,
|
||||
|
||||
Handle<JSFunction> FunctionTester::Compile(Handle<JSFunction> function) {
|
||||
Handle<SharedFunctionInfo> shared(function->shared());
|
||||
ParseInfo parse_info(shared);
|
||||
OptimizedCompilationInfo info(parse_info.zone(), function->GetIsolate(),
|
||||
shared, function);
|
||||
Zone zone(function->GetIsolate()->allocator(), ZONE_NAME);
|
||||
OptimizedCompilationInfo info(&zone, function->GetIsolate(), shared,
|
||||
function);
|
||||
|
||||
if (flags_ & OptimizedCompilationInfo::kInliningEnabled) {
|
||||
info.MarkAsInliningEnabled();
|
||||
@ -164,9 +164,9 @@ Handle<JSFunction> FunctionTester::Compile(Handle<JSFunction> function) {
|
||||
// and replace the JSFunction's code with the result.
|
||||
Handle<JSFunction> FunctionTester::CompileGraph(Graph* graph) {
|
||||
Handle<SharedFunctionInfo> shared(function->shared());
|
||||
ParseInfo parse_info(shared);
|
||||
OptimizedCompilationInfo info(parse_info.zone(), function->GetIsolate(),
|
||||
shared, function);
|
||||
Zone zone(function->GetIsolate()->allocator(), ZONE_NAME);
|
||||
OptimizedCompilationInfo info(&zone, function->GetIsolate(), shared,
|
||||
function);
|
||||
|
||||
Handle<Code> code =
|
||||
Pipeline::GenerateCodeForTesting(&info, function->GetIsolate(), graph);
|
||||
|
@ -4941,7 +4941,7 @@ static void RemoveCodeAndGC(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
Handle<Object> obj = v8::Utils::OpenHandle(*args[0]);
|
||||
Handle<JSFunction> fun = Handle<JSFunction>::cast(obj);
|
||||
fun->shared()->ClearBytecodeArray(); // Bytecode is code too.
|
||||
fun->shared()->FlushCompiled(); // Bytecode is code too.
|
||||
fun->set_code(*BUILTIN_CODE(isolate, CompileLazy));
|
||||
CcTest::CollectAllAvailableGarbage();
|
||||
}
|
||||
|
@ -123,7 +123,9 @@ class InterpreterTester {
|
||||
}
|
||||
if (!feedback_metadata_.is_null()) {
|
||||
function->set_feedback_cell(isolate_->heap()->many_closures_cell());
|
||||
function->shared()->set_feedback_metadata(
|
||||
// Set the raw feedback metadata to circumvent checks that we are not
|
||||
// overwriting existing metadata.
|
||||
function->shared()->set_raw_outer_scope_info_or_feedback_metadata(
|
||||
*feedback_metadata_.ToHandleChecked());
|
||||
JSFunction::EnsureFeedbackVector(function);
|
||||
}
|
||||
|
@ -46,7 +46,9 @@ Handle<FeedbackVector> NewFeedbackVector(Isolate* isolate, Spec* spec) {
|
||||
Handle<SharedFunctionInfo> shared =
|
||||
isolate->factory()->NewSharedFunctionInfoForBuiltin(
|
||||
isolate->factory()->empty_string(), Builtins::kIllegal);
|
||||
shared->set_feedback_metadata(*metadata);
|
||||
// Set the raw feedback metadata to circumvent checks that we are not
|
||||
// overwriting existing metadata.
|
||||
shared->set_raw_outer_scope_info_or_feedback_metadata(*metadata);
|
||||
return FeedbackVector::New(isolate, shared);
|
||||
}
|
||||
|
||||
|
@ -26,12 +26,12 @@ namespace {
|
||||
class BlockingCompilationJob : public OptimizedCompilationJob {
|
||||
public:
|
||||
BlockingCompilationJob(Isolate* isolate, Handle<JSFunction> function)
|
||||
: OptimizedCompilationJob(isolate->stack_guard()->real_climit(),
|
||||
&parse_info_, &info_, "BlockingCompilationJob",
|
||||
: OptimizedCompilationJob(isolate->stack_guard()->real_climit(), &info_,
|
||||
"BlockingCompilationJob",
|
||||
State::kReadyToExecute),
|
||||
shared_(function->shared()),
|
||||
parse_info_(shared_),
|
||||
info_(parse_info_.zone(), function->GetIsolate(), shared_, function),
|
||||
zone_(isolate->allocator(), ZONE_NAME),
|
||||
info_(&zone_, function->GetIsolate(), shared_, function),
|
||||
blocking_(false),
|
||||
semaphore_(0) {}
|
||||
~BlockingCompilationJob() override = default;
|
||||
@ -53,7 +53,7 @@ class BlockingCompilationJob : public OptimizedCompilationJob {
|
||||
|
||||
private:
|
||||
Handle<SharedFunctionInfo> shared_;
|
||||
ParseInfo parse_info_;
|
||||
Zone zone_;
|
||||
OptimizedCompilationInfo info_;
|
||||
base::AtomicValue<bool> blocking_;
|
||||
base::Semaphore semaphore_;
|
||||
|
@ -107,7 +107,9 @@ class JSCallReducerTest : public TypedGraphTest {
|
||||
Handle<SharedFunctionInfo> shared =
|
||||
isolate()->factory()->NewSharedFunctionInfoForBuiltin(
|
||||
isolate()->factory()->empty_string(), Builtins::kIllegal);
|
||||
shared->set_feedback_metadata(*metadata);
|
||||
// Set the raw feedback metadata to circumvent checks that we are not
|
||||
// overwriting existing metadata.
|
||||
shared->set_raw_outer_scope_info_or_feedback_metadata(*metadata);
|
||||
Handle<FeedbackVector> vector = FeedbackVector::New(isolate(), shared);
|
||||
VectorSlotPair feedback(vector, FeedbackSlot(0));
|
||||
return javascript()->Call(arity, CallFrequency(), feedback,
|
||||
|
@ -39,7 +39,9 @@ Handle<SharedFunctionInfo> CreateSharedFunctionInfo(
|
||||
isolate->factory()->NewStringFromAsciiChecked("f"),
|
||||
Builtins::kCompileLazy);
|
||||
shared->set_raw_end_position(source->length());
|
||||
shared->set_outer_scope_info(ScopeInfo::Empty(isolate));
|
||||
// Make sure we have an outer scope info, even though it's empty
|
||||
shared->set_raw_outer_scope_info_or_feedback_metadata(
|
||||
ScopeInfo::Empty(isolate));
|
||||
shared->set_function_literal_id(1);
|
||||
SharedFunctionInfo::SetScript(shared, script);
|
||||
return scope.CloseAndEscape(shared);
|
||||
|
Loading…
Reference in New Issue
Block a user