Commit 07537cdb authored by Ross McIlroy's avatar Ross McIlroy Committed by Commit Bot

Revert "[Compiler] Introduce IsCompiledScope which prevents flushing of compiled code"

This reverts commit 10ea3f8a.

Reason for revert: Causing failure on gc_stress bot: 
https://logs.chromium.org/logs/v8/buildbucket/cr-buildbucket.appspot.com/8928421099411850688/+/steps/Bisect_10ea3f8a/0/steps/Retry/0/logs/collections-construct../0

Original change's description:
> [Compiler] Introduce IsCompiledScope which prevents flushing of compiled code
> 
> Introduces a IsCompiledScope object which can be used to check whether a
> function is compiled, and ensure it remains compiled for the lifetime
> of the scope without being uncompiled by bytecode flushing. The Compile
> functions are modified to take a scope so that calling code can ensure
> the function remains compiled for the lifetime they require.
> 
> Also, don't allocate a feedback vector for asm-wasm code as this
> is never used, and will be reallocated if the asm-wasm code fails to
> instantiate the module and we fallback to regular JavaScript.
> 
> Also restructure Compiler::PostInstantiation() to allocate the feedback
> vector once, and do the optimized code check before optimizing for
> always opt.
> 
> BUG=v8:8395
> 
> Change-Id: I3f1a71143fcae3d1a0c01eefe91ebb4b8594221a
> Reviewed-on: https://chromium-review.googlesource.com/c/1352295
> Reviewed-by: Jakob Gruber <jgruber@chromium.org>
> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
> Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#57971}

TBR=rmcilroy@chromium.org,mstarzinger@chromium.org,jgruber@chromium.org

Change-Id: I1449a02a0aceb9757440757628e586df33972a40
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: v8:8395
Reviewed-on: https://chromium-review.googlesource.com/c/1357042Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57974}
parent d1b06814
......@@ -491,8 +491,7 @@ std::unique_ptr<UnoptimizedCompilationJob> GenerateUnoptimizedCode(
}
MaybeHandle<SharedFunctionInfo> GenerateUnoptimizedCodeForToplevel(
Isolate* isolate, ParseInfo* parse_info, AccountingAllocator* allocator,
IsCompiledScope* is_compiled_scope) {
Isolate* isolate, ParseInfo* parse_info, AccountingAllocator* allocator) {
EnsureSharedFunctionInfosArrayOnScript(parse_info, isolate);
parse_info->ast_value_factory()->Internalize(isolate);
......@@ -541,12 +540,6 @@ MaybeHandle<SharedFunctionInfo> GenerateUnoptimizedCodeForToplevel(
CompilationJob::FAILED) {
return MaybeHandle<SharedFunctionInfo>();
}
if (shared_info.is_identical_to(top_level)) {
// Ensure that the top level function is retained.
*is_compiled_scope = shared_info->is_compiled_scope();
DCHECK(is_compiled_scope->is_compiled());
}
}
// Character stream shouldn't be used again.
......@@ -900,9 +893,8 @@ MaybeHandle<SharedFunctionInfo> FinalizeTopLevel(
return shared_info;
}
MaybeHandle<SharedFunctionInfo> CompileToplevel(
ParseInfo* parse_info, Isolate* isolate,
IsCompiledScope* is_compiled_scope) {
MaybeHandle<SharedFunctionInfo> CompileToplevel(ParseInfo* parse_info,
Isolate* isolate) {
TimerEventScope<TimerEventCompileCode> top_level_timer(isolate);
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileCode");
DCHECK(ThreadId::Current().Equals(isolate->thread_id()));
......@@ -929,8 +921,8 @@ MaybeHandle<SharedFunctionInfo> CompileToplevel(
// Generate the unoptimized bytecode or asm-js data.
MaybeHandle<SharedFunctionInfo> shared_info =
GenerateUnoptimizedCodeForToplevel(
isolate, parse_info, isolate->allocator(), is_compiled_scope);
GenerateUnoptimizedCodeForToplevel(isolate, parse_info,
isolate->allocator());
if (shared_info.is_null()) {
FailWithPendingException(isolate, parse_info,
Compiler::ClearExceptionFlag::KEEP_EXCEPTION);
......@@ -1116,11 +1108,9 @@ bool Compiler::ParseAndAnalyze(ParseInfo* parse_info,
}
bool Compiler::Compile(Handle<SharedFunctionInfo> shared_info,
ClearExceptionFlag flag,
IsCompiledScope* is_compiled_scope) {
ClearExceptionFlag flag) {
// We should never reach here if the function is already compiled.
DCHECK(!shared_info->is_compiled());
DCHECK(!is_compiled_scope->is_compiled());
Isolate* isolate = shared_info->GetIsolate();
DCHECK(AllowCompilation::IsAllowed(isolate));
......@@ -1145,8 +1135,6 @@ bool Compiler::Compile(Handle<SharedFunctionInfo> shared_info,
if (!dispatcher->FinishNow(shared_info)) {
return FailWithPendingException(isolate, &parse_info, flag);
}
*is_compiled_scope = shared_info->is_compiled_scope();
DCHECK(is_compiled_scope->is_compiled());
return true;
}
......@@ -1183,13 +1171,10 @@ bool Compiler::Compile(Handle<SharedFunctionInfo> shared_info,
}
DCHECK(!isolate->has_pending_exception());
*is_compiled_scope = shared_info->is_compiled_scope();
DCHECK(is_compiled_scope->is_compiled());
return true;
}
bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag,
IsCompiledScope* is_compiled_scope) {
bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) {
// We should never reach here if the function is already compiled or optimized
DCHECK(!function->is_compiled());
DCHECK(!function->IsOptimized());
......@@ -1200,12 +1185,7 @@ bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag,
Handle<SharedFunctionInfo> shared_info = handle(function->shared(), isolate);
// Ensure shared function info is compiled.
*is_compiled_scope = shared_info->is_compiled_scope();
if (!is_compiled_scope->is_compiled() &&
!Compile(shared_info, flag, is_compiled_scope)) {
return false;
}
DCHECK(is_compiled_scope->is_compiled());
if (!shared_info->is_compiled() && !Compile(shared_info, flag)) return false;
Handle<Code> code = handle(shared_info->GetCode(), isolate);
// Allocate FeedbackVector for the JSFunction.
......@@ -1307,8 +1287,7 @@ bool Compiler::CompileOptimized(Handle<JSFunction> function,
MaybeHandle<SharedFunctionInfo> Compiler::CompileForLiveEdit(
ParseInfo* parse_info, Isolate* isolate) {
IsCompiledScope is_compiled_scope;
return CompileToplevel(parse_info, isolate, &is_compiled_scope);
return CompileToplevel(parse_info, isolate);
}
MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
......@@ -1346,12 +1325,10 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
Handle<SharedFunctionInfo> shared_info;
Handle<Script> script;
IsCompiledScope is_compiled_scope;
bool allow_eval_cache;
if (eval_result.has_shared()) {
shared_info = Handle<SharedFunctionInfo>(eval_result.shared(), isolate);
script = Handle<Script>(Script::cast(shared_info->script()), isolate);
is_compiled_scope = shared_info->is_compiled_scope();
allow_eval_cache = true;
} else {
ParseInfo parse_info(isolate);
......@@ -1385,8 +1362,7 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
}
DCHECK(!parse_info.is_module());
if (!CompileToplevel(&parse_info, isolate, &is_compiled_scope)
.ToHandle(&shared_info)) {
if (!CompileToplevel(&parse_info, isolate).ToHandle(&shared_info)) {
return MaybeHandle<JSFunction>();
}
allow_eval_cache = parse_info.allow_eval_cache();
......@@ -1424,7 +1400,6 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
new_feedback_cell, eval_scope_position);
}
}
DCHECK(is_compiled_scope.is_compiled());
return result;
}
......@@ -1727,7 +1702,6 @@ MaybeHandle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
// Do a lookup in the compilation cache but not for extensions.
MaybeHandle<SharedFunctionInfo> maybe_result;
IsCompiledScope is_compiled_scope;
if (extension == nullptr) {
bool can_consume_code_cache =
compile_options == ScriptCompiler::kConsumeCodeCache;
......@@ -1755,8 +1729,7 @@ MaybeHandle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
origin_options)
.ToHandle(&inner_result)) {
// Promote to per-isolate compilation cache.
is_compiled_scope = inner_result->is_compiled_scope();
DCHECK(is_compiled_scope.is_compiled());
DCHECK(inner_result->is_compiled());
compilation_cache->PutScript(source, isolate->native_context(),
language_mode, inner_result);
Handle<Script> script(Script::cast(inner_result->script()), isolate);
......@@ -1781,10 +1754,10 @@ MaybeHandle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
parse_info.set_language_mode(
stricter_language_mode(parse_info.language_mode(), language_mode));
maybe_result = CompileToplevel(&parse_info, isolate, &is_compiled_scope);
maybe_result = CompileToplevel(&parse_info, isolate);
Handle<SharedFunctionInfo> result;
if (extension == nullptr && maybe_result.ToHandle(&result)) {
DCHECK(is_compiled_scope.is_compiled());
DCHECK(result->is_compiled());
compilation_cache->PutScript(source, isolate->native_context(),
language_mode, result);
} else if (maybe_result.is_null() && natives != EXTENSION_CODE &&
......@@ -1839,7 +1812,6 @@ MaybeHandle<JSFunction> Compiler::GetWrappedFunction(
Handle<SharedFunctionInfo> wrapped;
Handle<Script> script;
IsCompiledScope is_compiled_scope;
if (!maybe_result.ToHandle(&wrapped)) {
ParseInfo parse_info(isolate);
script = NewScript(isolate, &parse_info, source, script_details,
......@@ -1856,7 +1828,7 @@ MaybeHandle<JSFunction> Compiler::GetWrappedFunction(
stricter_language_mode(parse_info.language_mode(), language_mode));
Handle<SharedFunctionInfo> top_level;
maybe_result = CompileToplevel(&parse_info, isolate, &is_compiled_scope);
maybe_result = CompileToplevel(&parse_info, isolate);
if (maybe_result.is_null()) isolate->ReportPendingMessages();
ASSIGN_RETURN_ON_EXCEPTION(isolate, top_level, maybe_result, JSFunction);
......@@ -1870,13 +1842,11 @@ MaybeHandle<JSFunction> Compiler::GetWrappedFunction(
}
DCHECK(!wrapped.is_null());
} else {
is_compiled_scope = wrapped->is_compiled_scope();
script = Handle<Script>(Script::cast(wrapped->script()), isolate);
}
DCHECK(is_compiled_scope.is_compiled());
return isolate->factory()->NewFunctionFromSharedFunctionInfo(wrapped, context,
NOT_TENURED);
NOT_TENURED);
}
MaybeHandle<SharedFunctionInfo>
......@@ -2032,13 +2002,22 @@ bool Compiler::FinalizeOptimizedCompilationJob(OptimizedCompilationJob* job,
void Compiler::PostInstantiation(Handle<JSFunction> function,
PretenureFlag pretenure) {
Isolate* isolate = function->GetIsolate();
Handle<SharedFunctionInfo> shared(function->shared(), isolate);
IsCompiledScope is_compiled_scope(shared->is_compiled_scope());
Handle<SharedFunctionInfo> shared(function->shared(), function->GetIsolate());
// If code is compiled to bytecode (i.e., isn't asm.js), then allocate a
// feedback and check for optimized code.
if (is_compiled_scope.is_compiled() && shared->HasBytecodeArray()) {
if (FLAG_always_opt && shared->allows_lazy_compilation() &&
!shared->optimization_disabled() && !shared->HasAsmWasmData() &&
shared->is_compiled()) {
JSFunction::EnsureFeedbackVector(function);
if (!function->IsOptimized()) {
// Only mark for optimization if we don't already have optimized code.
if (!function->HasOptimizedCode()) {
function->MarkForOptimization(ConcurrencyMode::kNotConcurrent);
}
}
}
if (shared->is_compiled() && !shared->HasAsmWasmData()) {
JSFunction::EnsureFeedbackVector(function);
Code code = function->has_feedback_vector()
......@@ -2050,18 +2029,13 @@ void Compiler::PostInstantiation(Handle<JSFunction> function,
DCHECK(function->shared()->is_compiled());
function->set_code(code);
}
if (FLAG_always_opt && shared->allows_lazy_compilation() &&
!shared->optimization_disabled() && !function->IsOptimized() &&
!function->HasOptimizedCode()) {
function->MarkForOptimization(ConcurrencyMode::kNotConcurrent);
}
}
if (shared->is_toplevel() || shared->is_wrapped()) {
// If it's a top-level script, report compilation to the debugger.
Handle<Script> script(Script::cast(shared->script()), isolate);
isolate->debug()->OnAfterCompile(script);
Handle<Script> script(
handle(Script::cast(shared->script()), function->GetIsolate()));
function->GetIsolate()->debug()->OnAfterCompile(script);
}
}
......
......@@ -21,7 +21,6 @@ namespace internal {
// Forward declarations.
class AstRawString;
class BackgroundCompileTask;
class IsCompiledScope;
class JavaScriptFrame;
class OptimizedCompilationInfo;
class OptimizedCompilationJob;
......@@ -58,10 +57,8 @@ class V8_EXPORT_PRIVATE Compiler : public AllStatic {
// given function holds (except for live-edit, which compiles the world).
static bool Compile(Handle<SharedFunctionInfo> shared,
ClearExceptionFlag flag,
IsCompiledScope* is_compiled_scope);
static bool Compile(Handle<JSFunction> function, ClearExceptionFlag flag,
IsCompiledScope* is_compiled_scope);
ClearExceptionFlag flag);
static bool Compile(Handle<JSFunction> function, ClearExceptionFlag flag);
static bool CompileOptimized(Handle<JSFunction> function, ConcurrencyMode);
V8_WARN_UNUSED_RESULT static MaybeHandle<SharedFunctionInfo>
......
......@@ -452,10 +452,8 @@ Reduction JSInliner::ReduceJSCall(Node* node) {
return NoChange();
}
IsCompiledScope is_compiled_scope(shared_info->is_compiled_scope());
if (!is_compiled_scope.is_compiled() &&
!Compiler::Compile(shared_info, Compiler::CLEAR_EXCEPTION,
&is_compiled_scope)) {
if (!shared_info->is_compiled() &&
!Compiler::Compile(shared_info, Compiler::CLEAR_EXCEPTION)) {
TRACE("Not inlining %s into %s because bytecode generation failed\n",
shared_info->DebugName()->ToCString().get(),
info_->shared_info()->DebugName()->ToCString().get());
......
......@@ -1272,9 +1272,7 @@ void Debug::InstallDebugBreakTrampoline() {
// By overwriting the function code with DebugBreakTrampoline, which tailcalls
// to shared code, we bypass CompileLazy. Perform CompileLazy here instead.
for (Handle<JSFunction> fun : needs_compile) {
IsCompiledScope is_compiled_scope;
Compiler::Compile(fun, Compiler::CLEAR_EXCEPTION, &is_compiled_scope);
DCHECK(is_compiled_scope.is_compiled());
Compiler::Compile(fun, Compiler::CLEAR_EXCEPTION);
fun->set_code(*trampoline);
}
}
......@@ -1322,7 +1320,6 @@ bool Debug::GetPossibleBreakpoints(Handle<Script> script, int start_position,
while (true) {
HandleScope scope(isolate_);
std::vector<Handle<SharedFunctionInfo>> candidates;
std::vector<IsCompiledScope> compiled_scopes;
SharedFunctionInfo::ScriptIterator iterator(isolate_, *script);
for (SharedFunctionInfo info = iterator.Next(); !info.is_null();
info = iterator.Next()) {
......@@ -1339,17 +1336,13 @@ bool Debug::GetPossibleBreakpoints(Handle<Script> script, int start_position,
for (const auto& candidate : candidates) {
// Code that cannot be compiled lazily are internal and not debuggable.
DCHECK(candidate->allows_lazy_compilation());
IsCompiledScope is_compiled_scope(candidate->is_compiled_scope());
if (!is_compiled_scope.is_compiled()) {
if (!Compiler::Compile(candidate, Compiler::CLEAR_EXCEPTION,
&is_compiled_scope)) {
if (!candidate->is_compiled()) {
if (!Compiler::Compile(candidate, Compiler::CLEAR_EXCEPTION)) {
return false;
} else {
was_compiled = true;
}
}
DCHECK(is_compiled_scope.is_compiled());
compiled_scopes.push_back(is_compiled_scope);
if (!EnsureBreakInfo(candidate)) return false;
PrepareFunctionForDebugExecution(candidate);
}
......@@ -1431,7 +1424,6 @@ Handle<Object> Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
// no point in looking for it by walking the heap.
SharedFunctionInfo shared;
IsCompiledScope is_compiled_scope;
{
SharedFunctionInfoFinder finder(position);
SharedFunctionInfo::ScriptIterator iterator(isolate_, *script);
......@@ -1442,8 +1434,7 @@ Handle<Object> Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
shared = finder.Result();
if (shared.is_null()) break;
// We found it if it's already compiled.
is_compiled_scope = shared->is_compiled_scope();
if (is_compiled_scope.is_compiled()) {
if (shared->is_compiled()) {
Handle<SharedFunctionInfo> shared_handle(shared, isolate_);
// If the iteration count is larger than 1, we had to compile the outer
// function in order to create this shared function info. So there can
......@@ -1460,10 +1451,8 @@ Handle<Object> Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
HandleScope scope(isolate_);
// Code that cannot be compiled lazily are internal and not debuggable.
DCHECK(shared->allows_lazy_compilation());
if (!Compiler::Compile(handle(shared, isolate_), Compiler::CLEAR_EXCEPTION,
&is_compiled_scope)) {
if (!Compiler::Compile(handle(shared, isolate_), Compiler::CLEAR_EXCEPTION))
break;
}
}
return isolate_->factory()->undefined_value();
}
......@@ -1476,10 +1465,8 @@ bool Debug::EnsureBreakInfo(Handle<SharedFunctionInfo> shared) {
if (!shared->IsSubjectToDebugging() && !CanBreakAtEntry(shared)) {
return false;
}
IsCompiledScope is_compiled_scope = shared->is_compiled_scope();
if (!is_compiled_scope.is_compiled() &&
!Compiler::Compile(shared, Compiler::CLEAR_EXCEPTION,
&is_compiled_scope)) {
if (!shared->is_compiled() &&
!Compiler::Compile(shared, Compiler::CLEAR_EXCEPTION)) {
return false;
}
CreateBreakInfo(shared);
......@@ -2150,13 +2137,10 @@ bool Debug::PerformSideEffectCheck(Handle<JSFunction> function,
Handle<Object> receiver) {
DCHECK_EQ(isolate_->debug_execution_mode(), DebugInfo::kSideEffects);
DisallowJavascriptExecution no_js(isolate_);
IsCompiledScope is_compiled_scope(function->shared()->is_compiled_scope());
if (!function->is_compiled() &&
!Compiler::Compile(function, Compiler::KEEP_EXCEPTION,
&is_compiled_scope)) {
!Compiler::Compile(function, Compiler::KEEP_EXCEPTION)) {
return false;
}
DCHECK(is_compiled_scope.is_compiled());
Handle<SharedFunctionInfo> shared(function->shared(), isolate_);
Handle<DebugInfo> debug_info = GetOrCreateDebugInfo(shared);
DebugInfo::SideEffectState side_effect_state =
......
......@@ -6237,14 +6237,12 @@ Handle<Object> JSFunction::GetName(Isolate* isolate,
Maybe<int> JSFunction::GetLength(Isolate* isolate,
Handle<JSFunction> function) {
int length = 0;
IsCompiledScope is_compiled_scope(function->shared()->is_compiled_scope());
if (is_compiled_scope.is_compiled()) {
if (function->shared()->is_compiled()) {
length = function->shared()->GetLength();
} else {
// If the function isn't compiled yet, the length is not computed
// correctly yet. Compile it now and return the right length.
if (Compiler::Compile(function, Compiler::KEEP_EXCEPTION,
&is_compiled_scope)) {
if (Compiler::Compile(function, Compiler::KEEP_EXCEPTION)) {
length = function->shared()->GetLength();
}
if (isolate->has_pending_exception()) return Nothing<int>();
......@@ -12685,11 +12683,9 @@ void JSFunction::MarkForOptimization(ConcurrencyMode mode) {
// static
void JSFunction::EnsureFeedbackVector(Handle<JSFunction> function) {
Isolate* const isolate = function->GetIsolate();
DCHECK(function->shared()->is_compiled());
if (function->feedback_cell()->value()->IsUndefined(isolate)) {
Handle<SharedFunctionInfo> shared(function->shared(), isolate);
if (!shared->HasAsmWasmData()) {
DCHECK(function->shared()->HasBytecodeArray());
Handle<FeedbackVector> feedback_vector =
FeedbackVector::New(isolate, shared);
if (function->feedback_cell() == isolate->heap()->many_closures_cell()) {
......@@ -13364,10 +13360,8 @@ void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) {
// The constructor should be compiled for the optimization hints to be
// available.
int expected_nof_properties = 0;
IsCompiledScope is_compiled_scope(function->shared()->is_compiled_scope());
if (is_compiled_scope.is_compiled() ||
Compiler::Compile(function, Compiler::CLEAR_EXCEPTION,
&is_compiled_scope)) {
if (function->shared()->is_compiled() ||
Compiler::Compile(function, Compiler::CLEAR_EXCEPTION)) {
DCHECK(function->shared()->is_compiled());
expected_nof_properties = function->shared()->expected_nof_properties();
}
......@@ -14220,10 +14214,8 @@ bool JSFunction::CalculateInstanceSizeForDerivedClass(
// The super constructor should be compiled for the number of expected
// properties to be available.
Handle<SharedFunctionInfo> shared(func->shared(), isolate);
IsCompiledScope is_compiled_scope(shared->is_compiled_scope());
if (is_compiled_scope.is_compiled() ||
Compiler::Compile(func, Compiler::CLEAR_EXCEPTION,
&is_compiled_scope)) {
if (shared->is_compiled() ||
Compiler::Compile(func, Compiler::CLEAR_EXCEPTION)) {
DCHECK(shared->is_compiled());
int count = shared->expected_nof_properties();
// Check that the estimate is sane.
......@@ -14232,7 +14224,7 @@ bool JSFunction::CalculateInstanceSizeForDerivedClass(
} else {
expected_nof_properties = JSObject::kMaxInObjectProperties;
}
} else {
} else if (!shared->is_compiled()) {
// In case there was a compilation error for the constructor we will
// throw an error during instantiation. Hence we directly return 0;
return false;
......
......@@ -71,13 +71,6 @@ uint32_t CompilationCacheShape::HashForObject(Isolate* isolate,
Smi::cast(val->get(JSRegExp::kFlagsIndex)));
}
InfoCellPair::InfoCellPair(SharedFunctionInfo shared,
FeedbackCell* feedback_cell)
: is_compiled_scope_(!shared.is_null() ? shared->is_compiled_scope()
: IsCompiledScope()),
shared_(shared),
feedback_cell_(feedback_cell) {}
} // namespace internal
} // namespace v8
......
......@@ -41,29 +41,16 @@ class CompilationCacheShape : public BaseShape<HashTableKey*> {
class InfoCellPair {
public:
InfoCellPair() : feedback_cell_(nullptr) {}
inline InfoCellPair(SharedFunctionInfo shared, FeedbackCell* feedback_cell);
InfoCellPair(SharedFunctionInfo shared, FeedbackCell* feedback_cell)
: shared_(shared), feedback_cell_(feedback_cell) {}
FeedbackCell* feedback_cell() const {
DCHECK(is_compiled_scope_.is_compiled());
return feedback_cell_;
}
SharedFunctionInfo shared() const {
DCHECK(is_compiled_scope_.is_compiled());
return shared_;
}
FeedbackCell* feedback_cell() const { return feedback_cell_; }
SharedFunctionInfo shared() const { return shared_; }
bool has_feedback_cell() const {
return feedback_cell_ != nullptr && is_compiled_scope_.is_compiled();
}
bool has_shared() const {
// Only return true if SFI is compiled - the bytecode could have been
// flushed while it's in the compilation cache, and not yet have been
// removed form the compilation cache.
return !shared_.is_null() && is_compiled_scope_.is_compiled();
}
bool has_feedback_cell() const { return feedback_cell_ != nullptr; }
bool has_shared() const { return !shared_.is_null(); }
private:
IsCompiledScope is_compiled_scope_;
SharedFunctionInfo shared_;
FeedbackCell* feedback_cell_;
};
......
......@@ -368,19 +368,6 @@ bool SharedFunctionInfo::is_compiled() const {
!data->IsUncompiledData();
}
IsCompiledScope SharedFunctionInfo::is_compiled_scope() const {
return IsCompiledScope(*this, GetIsolate());
}
IsCompiledScope::IsCompiledScope(const SharedFunctionInfo shared,
Isolate* isolate)
: retain_bytecode_(shared->HasBytecodeArray()
? handle(shared->GetBytecodeArray(), isolate)
: MaybeHandle<BytecodeArray>()),
is_compiled_(shared->is_compiled()) {
DCHECK_IMPLIES(!retain_bytecode_.is_null(), is_compiled());
}
uint16_t SharedFunctionInfo::GetLength() const {
DCHECK(is_compiled());
DCHECK(HasLength());
......
......@@ -21,7 +21,6 @@ class AsmWasmData;
class BytecodeArray;
class CoverageInfo;
class DebugInfo;
class IsCompiledScope;
class WasmExportedFunctionData;
// Data collected by the pre-parser storing information about scopes and inner
......@@ -247,17 +246,9 @@ class SharedFunctionInfo : public HeapObjectPtr {
inline bool HasFeedbackMetadata() const;
DECL_ACCESSORS(feedback_metadata, FeedbackMetadata)
// Returns if this function has been compiled yet. Note: with bytecode
// flushing, any GC after this call is made could cause the function
// to become uncompiled. If you need to ensure the function remains compiled
// for some period of time, use IsCompiledScope instead.
// Returns if this function has been compiled to native code yet.
inline bool is_compiled() const;
// Returns an IsCompiledScope which reports whether the function is compiled,
// and if compiled, will avoid the function becoming uncompiled while it is
// held.
inline IsCompiledScope is_compiled_scope() const;
// [length]: The function length - usually the number of declared parameters.
// Use up to 2^16-2 parameters (16 bits of values, where one is reserved for
// kDontAdaptArgumentsSentinel). The value is only reliable when the function
......@@ -700,21 +691,6 @@ struct SourceCodeOf {
int max_length;
};
// IsCompiledScope enables a caller to check if a function is compiled, and
// ensure it remains compiled (i.e., doesn't have it's bytecode flushed) while
// the scope is retained.
class IsCompiledScope {
public:
inline IsCompiledScope(const SharedFunctionInfo shared, Isolate* isolate);
inline IsCompiledScope() : retain_bytecode_(), is_compiled_(false) {}
inline bool is_compiled() const { return is_compiled_; }
private:
MaybeHandle<BytecodeArray> retain_bytecode_;
bool is_compiled_;
};
std::ostream& operator<<(std::ostream& os, const SourceCodeOf& v);
} // namespace internal
......
......@@ -36,9 +36,7 @@ RUNTIME_FUNCTION(Runtime_CompileLazy) {
if (check.JsHasOverflowed(kStackSpaceRequiredForCompilation * KB)) {
return isolate->StackOverflow();
}
IsCompiledScope is_compiled_scope;
if (!Compiler::Compile(function, Compiler::KEEP_EXCEPTION,
&is_compiled_scope)) {
if (!Compiler::Compile(function, Compiler::KEEP_EXCEPTION)) {
return ReadOnlyRoots(isolate).exception();
}
DCHECK(function->is_compiled());
......
......@@ -225,10 +225,8 @@ RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) {
}
// If function isn't compiled, compile it now.
IsCompiledScope is_compiled_scope(function->shared()->is_compiled_scope());
if (!is_compiled_scope.is_compiled() &&
!Compiler::Compile(function, Compiler::CLEAR_EXCEPTION,
&is_compiled_scope)) {
if (!function->shared()->is_compiled() &&
!Compiler::Compile(function, Compiler::CLEAR_EXCEPTION)) {
return ReadOnlyRoots(isolate).undefined_value();
}
......@@ -717,9 +715,8 @@ RUNTIME_FUNCTION(Runtime_DisassembleFunction) {
DCHECK_EQ(1, args.length());
// Get the function and make sure it is compiled.
CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
IsCompiledScope is_compiled_scope;
if (!func->is_compiled() &&
!Compiler::Compile(func, Compiler::KEEP_EXCEPTION, &is_compiled_scope)) {
!Compiler::Compile(func, Compiler::KEEP_EXCEPTION)) {
return ReadOnlyRoots(isolate).exception();
}
StdoutStream os;
......
......@@ -142,10 +142,8 @@ Handle<JSFunction> FunctionTester::ForMachineGraph(Graph* graph,
Handle<JSFunction> FunctionTester::Compile(Handle<JSFunction> function) {
Handle<SharedFunctionInfo> shared(function->shared(), isolate);
IsCompiledScope is_compiled_scope(shared->is_compiled_scope());
CHECK(is_compiled_scope.is_compiled() ||
Compiler::Compile(function, Compiler::CLEAR_EXCEPTION,
&is_compiled_scope));
CHECK(function->is_compiled() ||
Compiler::Compile(function, Compiler::CLEAR_EXCEPTION));
Zone zone(isolate->allocator(), ZONE_NAME);
OptimizedCompilationInfo info(&zone, isolate, shared, function);
......
......@@ -73,9 +73,7 @@ TEST_F(OptimizingCompileDispatcherTest, Construct) {
TEST_F(OptimizingCompileDispatcherTest, NonBlockingFlush) {
Handle<JSFunction> fun =
RunJS<JSFunction>("function f() { function g() {}; return g;}; f();");
IsCompiledScope is_compiled_scope;
ASSERT_TRUE(
Compiler::Compile(fun, Compiler::CLEAR_EXCEPTION, &is_compiled_scope));
ASSERT_TRUE(Compiler::Compile(fun, Compiler::CLEAR_EXCEPTION));
BlockingCompilationJob* job = new BlockingCompilationJob(i_isolate(), fun);
OptimizingCompileDispatcher dispatcher(i_isolate());
......
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