Commit bb2ee046 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[isolate] Introduce SaveAndSwitchContext

The most common use of {SaveContext} is to allocate this object, then
immediately set the context of the isolate to another Context. Thus
introduce a second class called "SaveAndSwitchContext" which implements
exactly that.

R=mstarzinger@chromium.org

Bug: v8:8562
Change-Id: I2fca1eadd909a7afe035316ded934624273f2e21
Reviewed-on: https://chromium-review.googlesource.com/c/1448319Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59323}
parent 40633b4f
...@@ -5177,8 +5177,7 @@ bool Bootstrapper::InstallExtensions(Handle<Context> native_context, ...@@ -5177,8 +5177,7 @@ bool Bootstrapper::InstallExtensions(Handle<Context> native_context,
// Don't install extensions into the snapshot. // Don't install extensions into the snapshot.
if (isolate_->serializer_enabled()) return true; if (isolate_->serializer_enabled()) return true;
BootstrapperActive active(this); BootstrapperActive active(this);
SaveContext saved_context(isolate_); SaveAndSwitchContext saved_context(isolate_, *native_context);
isolate_->set_context(*native_context);
return Genesis::InstallExtensions(isolate_, native_context, extensions) && return Genesis::InstallExtensions(isolate_, native_context, extensions) &&
Genesis::InstallSpecialObjects(isolate_, native_context); Genesis::InstallSpecialObjects(isolate_, native_context);
} }
......
...@@ -2996,8 +2996,7 @@ bool ProcessMessages( ...@@ -2996,8 +2996,7 @@ bool ProcessMessages(
const std::function<platform::MessageLoopBehavior()>& behavior) { const std::function<platform::MessageLoopBehavior()>& behavior) {
while (true) { while (true) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
i::SaveContext saved_context(i_isolate); i::SaveAndSwitchContext saved_context(i_isolate, i::Context());
i_isolate->set_context(i::Context());
SealHandleScope shs(isolate); SealHandleScope shs(isolate);
while (v8::platform::PumpMessageLoop(g_default_platform, isolate, while (v8::platform::PumpMessageLoop(g_default_platform, isolate,
behavior())) { behavior())) {
......
...@@ -195,8 +195,7 @@ V8_WARN_UNUSED_RESULT MaybeHandle<Object> Invoke(Isolate* isolate, ...@@ -195,8 +195,7 @@ V8_WARN_UNUSED_RESULT MaybeHandle<Object> Invoke(Isolate* isolate,
if ((!params.is_construct || function->IsConstructor()) && if ((!params.is_construct || function->IsConstructor()) &&
function->shared()->IsApiFunction() && function->shared()->IsApiFunction() &&
!function->shared()->BreakAtEntry()) { !function->shared()->BreakAtEntry()) {
SaveContext save(isolate); SaveAndSwitchContext save(isolate, function->context());
isolate->set_context(function->context());
DCHECK(function->context()->global_object()->IsJSGlobalObject()); DCHECK(function->context()->global_object()->IsJSGlobalObject());
Handle<Object> receiver = params.is_construct Handle<Object> receiver = params.is_construct
......
...@@ -3485,8 +3485,7 @@ MaybeHandle<JSBoundFunction> Factory::NewJSBoundFunction( ...@@ -3485,8 +3485,7 @@ MaybeHandle<JSBoundFunction> Factory::NewJSBoundFunction(
isolate(), prototype, isolate(), prototype,
JSReceiver::GetPrototype(isolate(), target_function), JSBoundFunction); JSReceiver::GetPrototype(isolate(), target_function), JSBoundFunction);
SaveContext save(isolate()); SaveAndSwitchContext save(isolate(), *target_function->GetCreationContext());
isolate()->set_context(*target_function->GetCreationContext());
// Create the [[BoundArguments]] for the result. // Create the [[BoundArguments]] for the result.
Handle<FixedArray> bound_arguments; Handle<FixedArray> bound_arguments;
......
...@@ -958,8 +958,7 @@ Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode( ...@@ -958,8 +958,7 @@ Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(
#ifdef DEBUG #ifdef DEBUG
// Unoptimized compilation should be context-independent. Verify that we don't // Unoptimized compilation should be context-independent. Verify that we don't
// access the native context by nulling it out during finalization. // access the native context by nulling it out during finalization.
SaveContext save(isolate); SaveAndSwitchContext save(isolate, Context());
isolate->set_context(Context());
#endif #endif
AllocateDeferredConstants(isolate, script); AllocateDeferredConstants(isolate, script);
......
...@@ -4551,6 +4551,12 @@ bool SaveContext::IsBelowFrame(StandardFrame* frame) { ...@@ -4551,6 +4551,12 @@ bool SaveContext::IsBelowFrame(StandardFrame* frame) {
return (c_entry_fp_ == 0) || (c_entry_fp_ > frame->sp()); return (c_entry_fp_ == 0) || (c_entry_fp_ > frame->sp());
} }
SaveAndSwitchContext::SaveAndSwitchContext(Isolate* isolate,
Context new_context)
: SaveContext(isolate) {
isolate->set_context(new_context);
}
#ifdef DEBUG #ifdef DEBUG
AssertNoContextChange::AssertNoContextChange(Isolate* isolate) AssertNoContextChange::AssertNoContextChange(Isolate* isolate)
: isolate_(isolate), context_(isolate->context(), isolate) {} : isolate_(isolate), context_(isolate->context(), isolate) {}
......
...@@ -90,7 +90,6 @@ class PromiseOnStack; ...@@ -90,7 +90,6 @@ class PromiseOnStack;
class RegExpStack; class RegExpStack;
class RootVisitor; class RootVisitor;
class RuntimeProfiler; class RuntimeProfiler;
class SaveContext;
class SetupIsolateDelegate; class SetupIsolateDelegate;
class Simulator; class Simulator;
class StartupDeserializer; class StartupDeserializer;
...@@ -1943,10 +1942,12 @@ class PromiseOnStack { ...@@ -1943,10 +1942,12 @@ class PromiseOnStack {
PromiseOnStack* prev_; PromiseOnStack* prev_;
}; };
// SaveContext scopes save the current context on the Isolate on creation, and
// restore it on destruction.
class V8_EXPORT_PRIVATE SaveContext { class V8_EXPORT_PRIVATE SaveContext {
public: public:
explicit SaveContext(Isolate* isolate); explicit SaveContext(Isolate* isolate);
~SaveContext(); ~SaveContext();
Handle<Context> context() { return context_; } Handle<Context> context() { return context_; }
...@@ -1960,6 +1961,13 @@ class V8_EXPORT_PRIVATE SaveContext { ...@@ -1960,6 +1961,13 @@ class V8_EXPORT_PRIVATE SaveContext {
Address c_entry_fp_; Address c_entry_fp_;
}; };
// Like SaveContext, but also switches the Context to a new one in the
// constructor.
class V8_EXPORT_PRIVATE SaveAndSwitchContext : public SaveContext {
public:
SaveAndSwitchContext(Isolate* isolate, Context new_context);
};
class AssertNoContextChange { class AssertNoContextChange {
#ifdef DEBUG #ifdef DEBUG
public: public:
......
...@@ -1417,8 +1417,7 @@ MaybeHandle<Object> Object::GetPropertyWithAccessor(LookupIterator* it) { ...@@ -1417,8 +1417,7 @@ MaybeHandle<Object> Object::GetPropertyWithAccessor(LookupIterator* it) {
// Regular accessor. // Regular accessor.
Handle<Object> getter(AccessorPair::cast(*structure)->getter(), isolate); Handle<Object> getter(AccessorPair::cast(*structure)->getter(), isolate);
if (getter->IsFunctionTemplateInfo()) { if (getter->IsFunctionTemplateInfo()) {
SaveContext save(isolate); SaveAndSwitchContext save(isolate, *holder->GetCreationContext());
isolate->set_context(*holder->GetCreationContext());
return Builtins::InvokeApiFunction( return Builtins::InvokeApiFunction(
isolate, false, Handle<FunctionTemplateInfo>::cast(getter), receiver, 0, isolate, false, Handle<FunctionTemplateInfo>::cast(getter), receiver, 0,
nullptr, isolate->factory()->undefined_value()); nullptr, isolate->factory()->undefined_value());
...@@ -1523,8 +1522,7 @@ Maybe<bool> Object::SetPropertyWithAccessor( ...@@ -1523,8 +1522,7 @@ Maybe<bool> Object::SetPropertyWithAccessor(
// Regular accessor. // Regular accessor.
Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
if (setter->IsFunctionTemplateInfo()) { if (setter->IsFunctionTemplateInfo()) {
SaveContext save(isolate); SaveAndSwitchContext save(isolate, *holder->GetCreationContext());
isolate->set_context(*holder->GetCreationContext());
Handle<Object> argv[] = {value}; Handle<Object> argv[] = {value};
RETURN_ON_EXCEPTION_VALUE( RETURN_ON_EXCEPTION_VALUE(
isolate, Builtins::InvokeApiFunction( isolate, Builtins::InvokeApiFunction(
......
...@@ -978,8 +978,8 @@ class AsyncCompileJob::CompilationStateCallback { ...@@ -978,8 +978,8 @@ class AsyncCompileJob::CompilationStateCallback {
job->foreground_task_runner_->PostTask( job->foreground_task_runner_->PostTask(
MakeCancelableTask(job->isolate_, [job] { MakeCancelableTask(job->isolate_, [job] {
HandleScope scope(job->isolate_); HandleScope scope(job->isolate_);
SaveContext saved_context(job->isolate_); SaveAndSwitchContext saved_context(job->isolate_,
job->isolate_->set_context(*job->native_context_); *job->native_context_);
job->FinishCompile(); job->FinishCompile();
})); }));
} }
...@@ -1000,8 +1000,8 @@ class AsyncCompileJob::CompilationStateCallback { ...@@ -1000,8 +1000,8 @@ class AsyncCompileJob::CompilationStateCallback {
job->foreground_task_runner_->PostTask( job->foreground_task_runner_->PostTask(
MakeCancelableTask(job->isolate_, [job] { MakeCancelableTask(job->isolate_, [job] {
HandleScope scope(job->isolate_); HandleScope scope(job->isolate_);
SaveContext saved_context(job->isolate_); SaveAndSwitchContext saved_context(job->isolate_,
job->isolate_->set_context(*job->native_context_); *job->native_context_);
WasmError error = Impl(job->native_module_->compilation_state()) WasmError error = Impl(job->native_module_->compilation_state())
->GetCompileError(); ->GetCompileError();
return job->AsyncCompileFailed(error); return job->AsyncCompileFailed(error);
...@@ -1035,8 +1035,7 @@ class AsyncCompileJob::CompileStep { ...@@ -1035,8 +1035,7 @@ class AsyncCompileJob::CompileStep {
void Run(AsyncCompileJob* job, bool on_foreground) { void Run(AsyncCompileJob* job, bool on_foreground) {
if (on_foreground) { if (on_foreground) {
HandleScope scope(job->isolate_); HandleScope scope(job->isolate_);
SaveContext saved_context(job->isolate_); SaveAndSwitchContext saved_context(job->isolate_, *job->native_context_);
job->isolate_->set_context(*job->native_context_);
RunInForeground(job); RunInForeground(job);
} else { } else {
RunInBackground(job); RunInBackground(job);
...@@ -1419,8 +1418,7 @@ void AsyncStreamingProcessor::OnFinishedStream(OwnedVector<uint8_t> bytes) { ...@@ -1419,8 +1418,7 @@ void AsyncStreamingProcessor::OnFinishedStream(OwnedVector<uint8_t> bytes) {
// CreateNativeModule, PrepareRuntimeObjects and FinishCompile as this is a // CreateNativeModule, PrepareRuntimeObjects and FinishCompile as this is a
// callback from the embedder. // callback from the embedder.
HandleScope scope(job_->isolate_); HandleScope scope(job_->isolate_);
SaveContext saved_context(job_->isolate_); SaveAndSwitchContext saved_context(job_->isolate_, *job_->native_context_);
job_->isolate_->set_context(*job_->native_context_);
bool needs_finish = job_->DecrementAndCheckFinisherCount(); bool needs_finish = job_->DecrementAndCheckFinisherCount();
if (job_->native_module_ == nullptr) { if (job_->native_module_ == nullptr) {
...@@ -1452,8 +1450,7 @@ bool AsyncStreamingProcessor::Deserialize(Vector<const uint8_t> module_bytes, ...@@ -1452,8 +1450,7 @@ bool AsyncStreamingProcessor::Deserialize(Vector<const uint8_t> module_bytes,
// DeserializeNativeModule and FinishCompile assume that they are executed in // DeserializeNativeModule and FinishCompile assume that they are executed in
// a HandleScope, and that a context is set on the isolate. // a HandleScope, and that a context is set on the isolate.
HandleScope scope(job_->isolate_); HandleScope scope(job_->isolate_);
SaveContext saved_context(job_->isolate_); SaveAndSwitchContext saved_context(job_->isolate_, *job_->native_context_);
job_->isolate_->set_context(*job_->native_context_);
MaybeHandle<WasmModuleObject> result = MaybeHandle<WasmModuleObject> result =
DeserializeNativeModule(job_->isolate_, module_bytes, wire_bytes); DeserializeNativeModule(job_->isolate_, module_bytes, wire_bytes);
......
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