summaryrefslogtreecommitdiff
path: root/deps/v8/src/execution/isolate.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/execution/isolate.cc')
-rw-r--r--deps/v8/src/execution/isolate.cc377
1 files changed, 41 insertions, 336 deletions
diff --git a/deps/v8/src/execution/isolate.cc b/deps/v8/src/execution/isolate.cc
index 3ba39562b1..2b6bb76d8a 100644
--- a/deps/v8/src/execution/isolate.cc
+++ b/deps/v8/src/execution/isolate.cc
@@ -15,7 +15,6 @@
#include "src/api/api-inl.h"
#include "src/ast/ast-value-factory.h"
#include "src/ast/scopes.h"
-#include "src/base/adapters.h"
#include "src/base/hashmap.h"
#include "src/base/platform/platform.h"
#include "src/base/sys-info.h"
@@ -36,6 +35,7 @@
#include "src/execution/isolate-inl.h"
#include "src/execution/messages.h"
#include "src/execution/microtask-queue.h"
+#include "src/execution/protectors-inl.h"
#include "src/execution/runtime-profiler.h"
#include "src/execution/simulator.h"
#include "src/execution/v8threads.h"
@@ -51,6 +51,7 @@
#include "src/logging/counters.h"
#include "src/logging/log.h"
#include "src/numbers/hash-seed-inl.h"
+#include "src/objects/backing-store.h"
#include "src/objects/elements.h"
#include "src/objects/frame-array-inl.h"
#include "src/objects/hash-table-inl.h"
@@ -320,7 +321,9 @@ Isolate::FindOrAllocatePerThreadDataForThisThread() {
base::MutexGuard lock_guard(&thread_data_table_mutex_);
per_thread = thread_data_table_.Lookup(thread_id);
if (per_thread == nullptr) {
- base::OS::AdjustSchedulingParams();
+ if (FLAG_adjust_os_scheduling_parameters) {
+ base::OS::AdjustSchedulingParams();
+ }
per_thread = new PerIsolateThreadData(this, thread_id);
thread_data_table_.Insert(per_thread);
}
@@ -1091,12 +1094,14 @@ Handle<Object> CaptureStackTrace(Isolate* isolate, Handle<Object> caller,
} else {
Handle<JSAsyncGeneratorObject> async_generator_object =
Handle<JSAsyncGeneratorObject>::cast(generator_object);
- Handle<AsyncGeneratorRequest> async_generator_request(
- AsyncGeneratorRequest::cast(async_generator_object->queue()),
- isolate);
- Handle<JSPromise> promise(
- JSPromise::cast(async_generator_request->promise()), isolate);
- CaptureAsyncStackTrace(isolate, promise, &builder);
+ Handle<Object> queue(async_generator_object->queue(), isolate);
+ if (!queue->IsUndefined(isolate)) {
+ Handle<AsyncGeneratorRequest> async_generator_request =
+ Handle<AsyncGeneratorRequest>::cast(queue);
+ Handle<JSPromise> promise(
+ JSPromise::cast(async_generator_request->promise()), isolate);
+ CaptureAsyncStackTrace(isolate, promise, &builder);
+ }
}
}
} else {
@@ -1701,22 +1706,20 @@ Object Isolate::UnwindAndFindHandler() {
// currently being executed.
wasm::WasmCodeRefScope code_ref_scope;
WasmCompiledFrame* wasm_frame = static_cast<WasmCompiledFrame*>(frame);
- int stack_slots = 0; // Will contain stack slot count of frame.
- int offset = wasm_frame->LookupExceptionHandlerInTable(&stack_slots);
+ wasm::WasmCode* wasm_code =
+ wasm_engine()->code_manager()->LookupCode(frame->pc());
+ int offset = wasm_frame->LookupExceptionHandlerInTable();
if (offset < 0) break;
// Compute the stack pointer from the frame pointer. This ensures that
// argument slots on the stack are dropped as returning would.
Address return_sp = frame->fp() +
StandardFrameConstants::kFixedFrameSizeAboveFp -
- stack_slots * kSystemPointerSize;
+ wasm_code->stack_slots() * kSystemPointerSize;
// This is going to be handled by Wasm, so we need to set the TLS flag
// again. It was cleared above assuming the frame would be unwound.
trap_handler::SetThreadInWasm();
- // Gather information from the frame.
- wasm::WasmCode* wasm_code =
- wasm_engine()->code_manager()->LookupCode(frame->pc());
return FoundHandler(Context(), wasm_code->instruction_start(), offset,
wasm_code->constant_pool(), return_sp, frame->fp());
}
@@ -1735,18 +1738,14 @@ Object Isolate::UnwindAndFindHandler() {
// For optimized frames we perform a lookup in the handler table.
if (!catchable_by_js) break;
OptimizedFrame* js_frame = static_cast<OptimizedFrame*>(frame);
- int stack_slots = 0; // Will contain stack slot count of frame.
- int offset =
- js_frame->LookupExceptionHandlerInTable(&stack_slots, nullptr);
+ Code code = frame->LookupCode();
+ int offset = js_frame->LookupExceptionHandlerInTable(nullptr, nullptr);
if (offset < 0) break;
// Compute the stack pointer from the frame pointer. This ensures
// that argument slots on the stack are dropped as returning would.
Address return_sp = frame->fp() +
StandardFrameConstants::kFixedFrameSizeAboveFp -
- stack_slots * kSystemPointerSize;
-
- // Gather information from the frame.
- Code code = frame->LookupCode();
+ code.stack_slots() * kSystemPointerSize;
// TODO(bmeurer): Turbofanned BUILTIN frames appear as OPTIMIZED,
// but do not have a code kind of OPTIMIZED_FUNCTION.
@@ -1767,31 +1766,24 @@ Object Isolate::UnwindAndFindHandler() {
// Some stubs are able to handle exceptions.
if (!catchable_by_js) break;
StubFrame* stub_frame = static_cast<StubFrame*>(frame);
+#ifdef DEBUG
wasm::WasmCodeRefScope code_ref_scope;
- wasm::WasmCode* wasm_code =
- wasm_engine()->code_manager()->LookupCode(frame->pc());
- if (wasm_code != nullptr) {
- // It is safe to skip Wasm runtime stubs as none of them contain local
- // exception handlers.
- CHECK_EQ(wasm::WasmCode::kRuntimeStub, wasm_code->kind());
- CHECK_EQ(0, wasm_code->handler_table_size());
- break;
- }
+ DCHECK_NULL(wasm_engine()->code_manager()->LookupCode(frame->pc()));
+#endif // DEBUG
Code code = stub_frame->LookupCode();
if (!code.IsCode() || code.kind() != Code::BUILTIN ||
!code.has_handler_table() || !code.is_turbofanned()) {
break;
}
- int stack_slots = 0; // Will contain stack slot count of frame.
- int offset = stub_frame->LookupExceptionHandlerInTable(&stack_slots);
+ int offset = stub_frame->LookupExceptionHandlerInTable();
if (offset < 0) break;
// Compute the stack pointer from the frame pointer. This ensures
// that argument slots on the stack are dropped as returning would.
Address return_sp = frame->fp() +
StandardFrameConstants::kFixedFrameSizeAboveFp -
- stack_slots * kSystemPointerSize;
+ code.stack_slots() * kSystemPointerSize;
return FoundHandler(Context(), code.InstructionStart(), offset,
code.constant_pool(), return_sp, frame->fp());
@@ -2063,7 +2055,7 @@ void Isolate::PrintCurrentStackTrace(FILE* out) {
for (int i = 0; i < frames->length(); ++i) {
Handle<StackTraceFrame> frame(StackTraceFrame::cast(frames->get(i)), this);
- SerializeStackTraceFrame(this, frame, builder);
+ SerializeStackTraceFrame(this, frame, &builder);
}
Handle<String> stack_trace = builder.Finish().ToHandleChecked();
@@ -2821,7 +2813,7 @@ Isolate* Isolate::New(IsolateAllocationMode mode) {
// IsolateAllocator allocates the memory for the Isolate object according to
// the given allocation mode.
std::unique_ptr<IsolateAllocator> isolate_allocator =
- base::make_unique<IsolateAllocator>(mode);
+ std::make_unique<IsolateAllocator>(mode);
// Construct Isolate object in the allocated memory.
void* isolate_ptr = isolate_allocator->isolate_memory();
Isolate* isolate = new (isolate_ptr) Isolate(std::move(isolate_allocator));
@@ -2986,7 +2978,7 @@ void Isolate::Deinit() {
optimizing_compile_dispatcher_ = nullptr;
}
- wasm_engine()->memory_tracker()->DeleteSharedMemoryObjectsOnIsolate(this);
+ BackingStore::RemoveSharedWasmMemoryObjects(this);
heap_.mark_compact_collector()->EnsureSweepingCompleted();
heap_.memory_allocator()->unmapper()->EnsureUnmappingCompleted();
@@ -3805,308 +3797,12 @@ bool Isolate::IsInAnyContext(Object object, uint32_t index) {
return false;
}
-bool Isolate::IsNoElementsProtectorIntact(Context context) {
- PropertyCell no_elements_cell = heap()->no_elements_protector();
- bool cell_reports_intact =
- no_elements_cell.value().IsSmi() &&
- Smi::ToInt(no_elements_cell.value()) == kProtectorValid;
-
-#ifdef DEBUG
- Context native_context = context.native_context();
-
- Map root_array_map =
- native_context.GetInitialJSArrayMap(GetInitialFastElementsKind());
- JSObject initial_array_proto = JSObject::cast(
- native_context.get(Context::INITIAL_ARRAY_PROTOTYPE_INDEX));
- JSObject initial_object_proto = JSObject::cast(
- native_context.get(Context::INITIAL_OBJECT_PROTOTYPE_INDEX));
- JSObject initial_string_proto = JSObject::cast(
- native_context.get(Context::INITIAL_STRING_PROTOTYPE_INDEX));
-
- if (root_array_map.is_null() || initial_array_proto == initial_object_proto) {
- // We are in the bootstrapping process, and the entire check sequence
- // shouldn't be performed.
- return cell_reports_intact;
- }
-
- // Check that the array prototype hasn't been altered WRT empty elements.
- if (root_array_map.prototype() != initial_array_proto) {
- DCHECK_EQ(false, cell_reports_intact);
- return cell_reports_intact;
- }
-
- FixedArrayBase elements = initial_array_proto.elements();
- ReadOnlyRoots roots(heap());
- if (elements != roots.empty_fixed_array() &&
- elements != roots.empty_slow_element_dictionary()) {
- DCHECK_EQ(false, cell_reports_intact);
- return cell_reports_intact;
- }
-
- // Check that the Object.prototype hasn't been altered WRT empty elements.
- elements = initial_object_proto.elements();
- if (elements != roots.empty_fixed_array() &&
- elements != roots.empty_slow_element_dictionary()) {
- DCHECK_EQ(false, cell_reports_intact);
- return cell_reports_intact;
- }
-
- // Check that the Array.prototype has the Object.prototype as its
- // [[Prototype]] and that the Object.prototype has a null [[Prototype]].
- PrototypeIterator iter(this, initial_array_proto);
- if (iter.IsAtEnd() || iter.GetCurrent() != initial_object_proto) {
- DCHECK_EQ(false, cell_reports_intact);
- DCHECK(!has_pending_exception());
- return cell_reports_intact;
- }
- iter.Advance();
- if (!iter.IsAtEnd()) {
- DCHECK_EQ(false, cell_reports_intact);
- DCHECK(!has_pending_exception());
- return cell_reports_intact;
- }
- DCHECK(!has_pending_exception());
-
- // Check that the String.prototype hasn't been altered WRT empty elements.
- elements = initial_string_proto.elements();
- if (elements != roots.empty_fixed_array() &&
- elements != roots.empty_slow_element_dictionary()) {
- DCHECK_EQ(false, cell_reports_intact);
- return cell_reports_intact;
- }
-
- // Check that the String.prototype has the Object.prototype
- // as its [[Prototype]] still.
- if (initial_string_proto.map().prototype() != initial_object_proto) {
- DCHECK_EQ(false, cell_reports_intact);
- return cell_reports_intact;
- }
-#endif
-
- return cell_reports_intact;
-}
-
-bool Isolate::IsNoElementsProtectorIntact() {
- return Isolate::IsNoElementsProtectorIntact(context());
-}
-
-bool Isolate::IsIsConcatSpreadableLookupChainIntact() {
- Cell is_concat_spreadable_cell = heap()->is_concat_spreadable_protector();
- bool is_is_concat_spreadable_set =
- Smi::ToInt(is_concat_spreadable_cell.value()) == kProtectorInvalid;
-#ifdef DEBUG
- Map root_array_map =
- raw_native_context().GetInitialJSArrayMap(GetInitialFastElementsKind());
- if (root_array_map.is_null()) {
- // Ignore the value of is_concat_spreadable during bootstrap.
- return !is_is_concat_spreadable_set;
- }
- Handle<Object> array_prototype(array_function()->prototype(), this);
- Handle<Symbol> key = factory()->is_concat_spreadable_symbol();
- Handle<Object> value;
- LookupIterator it(this, array_prototype, key);
- if (it.IsFound() && !JSReceiver::GetDataProperty(&it)->IsUndefined(this)) {
- // TODO(cbruni): Currently we do not revert if we unset the
- // @@isConcatSpreadable property on Array.prototype or Object.prototype
- // hence the reverse implication doesn't hold.
- DCHECK(is_is_concat_spreadable_set);
- return false;
- }
-#endif // DEBUG
-
- return !is_is_concat_spreadable_set;
-}
-
-bool Isolate::IsIsConcatSpreadableLookupChainIntact(JSReceiver receiver) {
- if (!IsIsConcatSpreadableLookupChainIntact()) return false;
- return !receiver.HasProxyInPrototype(this);
-}
-
-bool Isolate::IsPromiseHookProtectorIntact() {
- PropertyCell promise_hook_cell = heap()->promise_hook_protector();
- bool is_promise_hook_protector_intact =
- Smi::ToInt(promise_hook_cell.value()) == kProtectorValid;
- DCHECK_IMPLIES(is_promise_hook_protector_intact,
- !promise_hook_or_async_event_delegate_);
- DCHECK_IMPLIES(is_promise_hook_protector_intact,
- !promise_hook_or_debug_is_active_or_async_event_delegate_);
- return is_promise_hook_protector_intact;
-}
-
-bool Isolate::IsPromiseResolveLookupChainIntact() {
- Cell promise_resolve_cell = heap()->promise_resolve_protector();
- bool is_promise_resolve_protector_intact =
- Smi::ToInt(promise_resolve_cell.value()) == kProtectorValid;
- return is_promise_resolve_protector_intact;
-}
-
-bool Isolate::IsPromiseThenLookupChainIntact() {
- PropertyCell promise_then_cell = heap()->promise_then_protector();
- bool is_promise_then_protector_intact =
- Smi::ToInt(promise_then_cell.value()) == kProtectorValid;
- return is_promise_then_protector_intact;
-}
-
-bool Isolate::IsPromiseThenLookupChainIntact(Handle<JSReceiver> receiver) {
- DisallowHeapAllocation no_gc;
- if (!receiver->IsJSPromise()) return false;
- if (!IsInAnyContext(receiver->map().prototype(),
- Context::PROMISE_PROTOTYPE_INDEX)) {
- return false;
- }
- return IsPromiseThenLookupChainIntact();
-}
-
void Isolate::UpdateNoElementsProtectorOnSetElement(Handle<JSObject> object) {
DisallowHeapAllocation no_gc;
if (!object->map().is_prototype_map()) return;
- if (!IsNoElementsProtectorIntact()) return;
+ if (!Protectors::IsNoElementsIntact(this)) return;
if (!IsArrayOrObjectOrStringPrototype(*object)) return;
- PropertyCell::SetValueWithInvalidation(
- this, "no_elements_protector", factory()->no_elements_protector(),
- handle(Smi::FromInt(kProtectorInvalid), this));
-}
-
-void Isolate::TraceProtectorInvalidation(const char* protector_name) {
- static constexpr char kInvalidateProtectorTracingCategory[] =
- "V8.InvalidateProtector";
- static constexpr char kInvalidateProtectorTracingArg[] = "protector-name";
-
- DCHECK(FLAG_trace_protector_invalidation);
-
- // TODO(jgruber): Remove the PrintF once tracing can output to stdout.
- i::PrintF("Invalidating protector cell %s in isolate %p\n", protector_name,
- this);
- TRACE_EVENT_INSTANT1("v8", kInvalidateProtectorTracingCategory,
- TRACE_EVENT_SCOPE_THREAD, kInvalidateProtectorTracingArg,
- protector_name);
-}
-
-void Isolate::InvalidateIsConcatSpreadableProtector() {
- DCHECK(factory()->is_concat_spreadable_protector()->value().IsSmi());
- DCHECK(IsIsConcatSpreadableLookupChainIntact());
- if (FLAG_trace_protector_invalidation) {
- TraceProtectorInvalidation("is_concat_spreadable_protector");
- }
- factory()->is_concat_spreadable_protector()->set_value(
- Smi::FromInt(kProtectorInvalid));
- DCHECK(!IsIsConcatSpreadableLookupChainIntact());
-}
-
-void Isolate::InvalidateArrayConstructorProtector() {
- DCHECK(factory()->array_constructor_protector()->value().IsSmi());
- DCHECK(IsArrayConstructorIntact());
- if (FLAG_trace_protector_invalidation) {
- TraceProtectorInvalidation("array_constructor_protector");
- }
- factory()->array_constructor_protector()->set_value(
- Smi::FromInt(kProtectorInvalid));
- DCHECK(!IsArrayConstructorIntact());
-}
-
-void Isolate::InvalidateTypedArraySpeciesProtector() {
- DCHECK(factory()->typed_array_species_protector()->value().IsSmi());
- DCHECK(IsTypedArraySpeciesLookupChainIntact());
- PropertyCell::SetValueWithInvalidation(
- this, "typed_array_species_protector",
- factory()->typed_array_species_protector(),
- handle(Smi::FromInt(kProtectorInvalid), this));
- DCHECK(!IsTypedArraySpeciesLookupChainIntact());
-}
-
-void Isolate::InvalidatePromiseSpeciesProtector() {
- DCHECK(factory()->promise_species_protector()->value().IsSmi());
- DCHECK(IsPromiseSpeciesLookupChainIntact());
- PropertyCell::SetValueWithInvalidation(
- this, "promise_species_protector", factory()->promise_species_protector(),
- handle(Smi::FromInt(kProtectorInvalid), this));
- DCHECK(!IsPromiseSpeciesLookupChainIntact());
-}
-
-void Isolate::InvalidateStringLengthOverflowProtector() {
- DCHECK(factory()->string_length_protector()->value().IsSmi());
- DCHECK(IsStringLengthOverflowIntact());
- if (FLAG_trace_protector_invalidation) {
- TraceProtectorInvalidation("string_length_protector");
- }
- factory()->string_length_protector()->set_value(
- Smi::FromInt(kProtectorInvalid));
- DCHECK(!IsStringLengthOverflowIntact());
-}
-
-void Isolate::InvalidateArrayIteratorProtector() {
- DCHECK(factory()->array_iterator_protector()->value().IsSmi());
- DCHECK(IsArrayIteratorLookupChainIntact());
- PropertyCell::SetValueWithInvalidation(
- this, "array_iterator_protector", factory()->array_iterator_protector(),
- handle(Smi::FromInt(kProtectorInvalid), this));
- DCHECK(!IsArrayIteratorLookupChainIntact());
-}
-
-void Isolate::InvalidateMapIteratorProtector() {
- DCHECK(factory()->map_iterator_protector()->value().IsSmi());
- DCHECK(IsMapIteratorLookupChainIntact());
- PropertyCell::SetValueWithInvalidation(
- this, "map_iterator_protector", factory()->map_iterator_protector(),
- handle(Smi::FromInt(kProtectorInvalid), this));
- DCHECK(!IsMapIteratorLookupChainIntact());
-}
-
-void Isolate::InvalidateSetIteratorProtector() {
- DCHECK(factory()->set_iterator_protector()->value().IsSmi());
- DCHECK(IsSetIteratorLookupChainIntact());
- PropertyCell::SetValueWithInvalidation(
- this, "set_iterator_protector", factory()->set_iterator_protector(),
- handle(Smi::FromInt(kProtectorInvalid), this));
- DCHECK(!IsSetIteratorLookupChainIntact());
-}
-
-void Isolate::InvalidateStringIteratorProtector() {
- DCHECK(factory()->string_iterator_protector()->value().IsSmi());
- DCHECK(IsStringIteratorLookupChainIntact());
- PropertyCell::SetValueWithInvalidation(
- this, "string_iterator_protector", factory()->string_iterator_protector(),
- handle(Smi::FromInt(kProtectorInvalid), this));
- DCHECK(!IsStringIteratorLookupChainIntact());
-}
-
-void Isolate::InvalidateArrayBufferDetachingProtector() {
- DCHECK(factory()->array_buffer_detaching_protector()->value().IsSmi());
- DCHECK(IsArrayBufferDetachingIntact());
- PropertyCell::SetValueWithInvalidation(
- this, "array_buffer_detaching_protector",
- factory()->array_buffer_detaching_protector(),
- handle(Smi::FromInt(kProtectorInvalid), this));
- DCHECK(!IsArrayBufferDetachingIntact());
-}
-
-void Isolate::InvalidatePromiseHookProtector() {
- DCHECK(factory()->promise_hook_protector()->value().IsSmi());
- DCHECK(IsPromiseHookProtectorIntact());
- PropertyCell::SetValueWithInvalidation(
- this, "promise_hook_protector", factory()->promise_hook_protector(),
- handle(Smi::FromInt(kProtectorInvalid), this));
- DCHECK(!IsPromiseHookProtectorIntact());
-}
-
-void Isolate::InvalidatePromiseResolveProtector() {
- DCHECK(factory()->promise_resolve_protector()->value().IsSmi());
- DCHECK(IsPromiseResolveLookupChainIntact());
- if (FLAG_trace_protector_invalidation) {
- TraceProtectorInvalidation("promise_resolve_protector");
- }
- factory()->promise_resolve_protector()->set_value(
- Smi::FromInt(kProtectorInvalid));
- DCHECK(!IsPromiseResolveLookupChainIntact());
-}
-
-void Isolate::InvalidatePromiseThenProtector() {
- DCHECK(factory()->promise_then_protector()->value().IsSmi());
- DCHECK(IsPromiseThenLookupChainIntact());
- PropertyCell::SetValueWithInvalidation(
- this, "promise_then_protector", factory()->promise_then_protector(),
- handle(Smi::FromInt(kProtectorInvalid), this));
- DCHECK(!IsPromiseThenLookupChainIntact());
+ Protectors::InvalidateNoElements(this);
}
bool Isolate::IsAnyInitialArrayPrototype(Handle<JSArray> array) {
@@ -4256,9 +3952,9 @@ void Isolate::PromiseHookStateUpdated() {
bool promise_hook_or_debug_is_active_or_async_event_delegate =
promise_hook_or_async_event_delegate || debug()->is_active();
if (promise_hook_or_debug_is_active_or_async_event_delegate &&
- IsPromiseHookProtectorIntact()) {
+ Protectors::IsPromiseHookIntact(this)) {
HandleScope scope(this);
- InvalidatePromiseHookProtector();
+ Protectors::InvalidatePromiseHook(this);
}
promise_hook_or_async_event_delegate_ = promise_hook_or_async_event_delegate;
promise_hook_or_debug_is_active_or_async_event_delegate_ =
@@ -4584,6 +4280,15 @@ void Isolate::AddDetachedContext(Handle<Context> context) {
heap()->set_detached_contexts(*detached_contexts);
}
+void Isolate::AddSharedWasmMemory(Handle<WasmMemoryObject> memory_object) {
+ HandleScope scope(this);
+ Handle<WeakArrayList> shared_wasm_memories =
+ factory()->shared_wasm_memories();
+ shared_wasm_memories = WeakArrayList::AddToEnd(
+ this, shared_wasm_memories, MaybeObjectHandle::Weak(memory_object));
+ heap()->set_shared_wasm_memories(*shared_wasm_memories);
+}
+
void Isolate::CheckDetachedContextsAfterGC() {
HandleScope scope(this);
Handle<WeakArrayList> detached_contexts = factory()->detached_contexts();