diff options
Diffstat (limited to 'deps/v8/src/api.cc')
-rw-r--r-- | deps/v8/src/api.cc | 920 |
1 files changed, 315 insertions, 605 deletions
diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc index 6155cbb3257..d141496c574 100644 --- a/deps/v8/src/api.cc +++ b/deps/v8/src/api.cc @@ -8,6 +8,9 @@ #include <cmath> // For isnan. #include <limits> #include <vector> + +#include "src/api-inl.h" + #include "include/v8-profiler.h" #include "include/v8-testing.h" #include "include/v8-util.h" @@ -48,7 +51,9 @@ #include "src/messages.h" #include "src/objects-inl.h" #include "src/objects/api-callbacks.h" +#include "src/objects/js-array-inl.h" #include "src/objects/js-collection-inl.h" +#include "src/objects/js-generator-inl.h" #include "src/objects/js-promise-inl.h" #include "src/objects/js-regexp-inl.h" #include "src/objects/module-inl.h" @@ -207,17 +212,6 @@ namespace v8 { #define RETURN_ESCAPED(value) return handle_scope.Escape(value); -// TODO(v8:7786): Remove this when HeapObject::GetIsolate is removed. -#ifdef DEPRECATE_GET_ISOLATE -#define DISABLE_DEPRECATED_WARNINGS \ - _Pragma("clang diagnostic push") \ - _Pragma("clang diagnostic ignored \"-Wdeprecated\"") -#define RESET_DEPRECATED_WARNINGS _Pragma("clang diagnostic pop") -#else -#define DISABLE_DEPRECATED_WARNINGS -#define RESET_DEPRECATED_WARNINGS -#endif - namespace { Local<Context> ContextFromNeverReadOnlySpaceObject( @@ -225,19 +219,6 @@ Local<Context> ContextFromNeverReadOnlySpaceObject( return reinterpret_cast<v8::Isolate*>(obj->GetIsolate())->GetCurrentContext(); } -// This is unsafe because obj could be in RO_SPACE which would not be tied to a -// particular isolate. -#ifdef DEPRECATE_GET_ISOLATE -[[deprecated("Pass Context explicitly or use a NeverReadOnlySpaceObject")]] -#endif - Local<Context> - UnsafeContextFromHeapObject(i::Handle<i::Object> obj) { - DISABLE_DEPRECATED_WARNINGS - return reinterpret_cast<v8::Isolate*>(i::HeapObject::cast(*obj)->GetIsolate()) - ->GetCurrentContext(); - RESET_DEPRECATED_WARNINGS -} - class InternalEscapableScope : public v8::EscapableHandleScope { public: explicit inline InternalEscapableScope(i::Isolate* isolate) @@ -534,34 +515,6 @@ class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { void Free(void* data, size_t) override { free(data); } }; -bool RunExtraCode(Isolate* isolate, Local<Context> context, - const char* utf8_source, const char* name) { - base::ElapsedTimer timer; - timer.Start(); - Context::Scope context_scope(context); - TryCatch try_catch(isolate); - Local<String> source_string; - if (!String::NewFromUtf8(isolate, utf8_source, NewStringType::kNormal) - .ToLocal(&source_string)) { - return false; - } - Local<String> resource_name = - String::NewFromUtf8(isolate, name, NewStringType::kNormal) - .ToLocalChecked(); - ScriptOrigin origin(resource_name); - ScriptCompiler::Source source(source_string, origin); - Local<Script> script; - if (!ScriptCompiler::Compile(context, &source).ToLocal(&script)) return false; - if (script->Run(context).IsEmpty()) return false; - if (i::FLAG_profile_deserialization) { - i::PrintF("Executing custom snapshot script %s took %0.3f ms\n", name, - timer.Elapsed().InMillisecondsF()); - } - timer.Stop(); - CHECK(!try_catch.HasCaught()); - return true; -} - struct SnapshotCreatorData { explicit SnapshotCreatorData(Isolate* isolate) : isolate_(isolate), @@ -763,7 +716,7 @@ StartupData SnapshotCreator::CreateBlob( i::GarbageCollectionReason::kSnapshotCreator); { i::HandleScope scope(isolate); - isolate->heap()->CompactFixedArraysOfWeakCells(); + isolate->heap()->CompactWeakArrayLists(internal::TENURED); } isolate->heap()->read_only_space()->ClearStringPaddingIfNeeded(); @@ -884,77 +837,6 @@ StartupData SnapshotCreator::CreateBlob( return result; } -StartupData V8::CreateSnapshotDataBlob(const char* embedded_source) { - // Create a new isolate and a new context from scratch, optionally run - // a script to embed, and serialize to create a snapshot blob. - StartupData result = {nullptr, 0}; - base::ElapsedTimer timer; - timer.Start(); - { - SnapshotCreator snapshot_creator; - Isolate* isolate = snapshot_creator.GetIsolate(); - { - HandleScope scope(isolate); - Local<Context> context = Context::New(isolate); - if (embedded_source != nullptr && - !RunExtraCode(isolate, context, embedded_source, "<embedded>")) { - return result; - } - snapshot_creator.SetDefaultContext(context); - } - result = snapshot_creator.CreateBlob( - SnapshotCreator::FunctionCodeHandling::kClear); - } - - if (i::FLAG_profile_deserialization) { - i::PrintF("Creating snapshot took %0.3f ms\n", - timer.Elapsed().InMillisecondsF()); - } - timer.Stop(); - return result; -} - -StartupData V8::WarmUpSnapshotDataBlob(StartupData cold_snapshot_blob, - const char* warmup_source) { - CHECK(cold_snapshot_blob.raw_size > 0 && cold_snapshot_blob.data != nullptr); - CHECK_NOT_NULL(warmup_source); - // Use following steps to create a warmed up snapshot blob from a cold one: - // - Create a new isolate from the cold snapshot. - // - Create a new context to run the warmup script. This will trigger - // compilation of executed functions. - // - Create a new context. This context will be unpolluted. - // - Serialize the isolate and the second context into a new snapshot blob. - StartupData result = {nullptr, 0}; - base::ElapsedTimer timer; - timer.Start(); - { - SnapshotCreator snapshot_creator(nullptr, &cold_snapshot_blob); - Isolate* isolate = snapshot_creator.GetIsolate(); - { - HandleScope scope(isolate); - Local<Context> context = Context::New(isolate); - if (!RunExtraCode(isolate, context, warmup_source, "<warm-up>")) { - return result; - } - } - { - HandleScope handle_scope(isolate); - isolate->ContextDisposedNotification(false); - Local<Context> context = Context::New(isolate); - snapshot_creator.SetDefaultContext(context); - } - result = snapshot_creator.CreateBlob( - SnapshotCreator::FunctionCodeHandling::kKeep); - } - - if (i::FLAG_profile_deserialization) { - i::PrintF("Warming up snapshot took %0.3f ms\n", - timer.Elapsed().InMillisecondsF()); - } - timer.Stop(); - return result; -} - void V8::SetDcheckErrorHandler(DcheckErrorCallback that) { v8::base::SetDcheckFunction(that); } @@ -1953,16 +1835,6 @@ static void ObjectTemplateSetNamedPropertyHandler( cons->set_named_property_handler(*obj); } -// TODO(cbruni) deprecate. -void ObjectTemplate::SetNamedPropertyHandler( - NamedPropertyGetterCallback getter, NamedPropertySetterCallback setter, - NamedPropertyQueryCallback query, NamedPropertyDeleterCallback remover, - NamedPropertyEnumeratorCallback enumerator, Local<Value> data) { - ObjectTemplateSetNamedPropertyHandler( - this, getter, setter, query, nullptr, remover, enumerator, nullptr, data, - PropertyHandlerFlags::kOnlyInterceptStrings); -} - void ObjectTemplate::SetHandler( const NamedPropertyHandlerConfiguration& config) { ObjectTemplateSetNamedPropertyHandler( @@ -2247,15 +2119,6 @@ MaybeLocal<Value> Script::Run(Local<Context> context) { } -Local<Value> Script::Run() { - auto self = Utils::OpenHandle(this, true); - // If execution is terminating, Compile(..)->Run() requires this - // check. - if (self.is_null()) return Local<Value>(); - auto context = ContextFromNeverReadOnlySpaceObject(self); - RETURN_TO_LOCAL_UNCHECKED(Run(context), Value); -} - Local<Value> ScriptOrModule::GetResourceName() { i::Handle<i::Script> obj = Utils::OpenHandle(this); i::Isolate* isolate = obj->GetIsolate(); @@ -2307,14 +2170,6 @@ void PrimitiveArray::Set(Isolate* v8_isolate, int index, array->set(index, *i_item); } -void PrimitiveArray::Set(int index, Local<Primitive> item) { - i::Handle<i::FixedArray> array = Utils::OpenHandle(this); - DISABLE_DEPRECATED_WARNINGS - i::Isolate* isolate = array->GetIsolate(); - RESET_DEPRECATED_WARNINGS - Set(reinterpret_cast<Isolate*>(isolate), index, item); -} - Local<Primitive> PrimitiveArray::Get(Isolate* v8_isolate, int index) { i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); i::Handle<i::FixedArray> array = Utils::OpenHandle(this); @@ -2327,14 +2182,6 @@ Local<Primitive> PrimitiveArray::Get(Isolate* v8_isolate, int index) { return ToApiHandle<Primitive>(i_item); } -Local<Primitive> PrimitiveArray::Get(int index) { - i::Handle<i::FixedArray> array = Utils::OpenHandle(this); - DISABLE_DEPRECATED_WARNINGS - i::Isolate* isolate = array->GetIsolate(); - RESET_DEPRECATED_WARNINGS - return Get(reinterpret_cast<Isolate*>(isolate), index); -} - Module::Status Module::GetStatus() const { i::Handle<i::Module> self = Utils::OpenHandle(this); switch (self->status()) { @@ -2513,8 +2360,8 @@ MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal( source->host_defined_options); i::MaybeHandle<i::SharedFunctionInfo> maybe_function_info = i::Compiler::GetSharedFunctionInfoForScript( - str, script_details, source->resource_options, nullptr, script_data, - options, no_cache_reason, i::NOT_NATIVES_CODE); + isolate, str, script_details, source->resource_options, nullptr, + script_data, options, no_cache_reason, i::NOT_NATIVES_CODE); if (options == kConsumeCodeCache) { source->cached_data->rejected = script_data->rejected(); } @@ -2680,17 +2527,6 @@ MaybeLocal<Function> ScriptCompiler::CompileFunctionInContext( } -Local<Function> ScriptCompiler::CompileFunctionInContext( - Isolate* v8_isolate, Source* source, Local<Context> v8_context, - size_t arguments_count, Local<String> arguments[], - size_t context_extension_count, Local<Object> context_extensions[]) { - RETURN_TO_LOCAL_UNCHECKED( - CompileFunctionInContext(v8_context, source, arguments_count, arguments, - context_extension_count, context_extensions), - Function); -} - - ScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreamingScript( Isolate* v8_isolate, StreamedSource* source, CompileOptions options) { if (!i::FLAG_script_streaming) { @@ -2722,7 +2558,7 @@ MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context, i::MaybeHandle<i::SharedFunctionInfo> maybe_function_info = i::Compiler::GetSharedFunctionInfoForStreamedScript( - str, script_details, origin.Options(), streaming_data); + isolate, str, script_details, origin.Options(), streaming_data); i::Handle<i::SharedFunctionInfo> result; has_pending_exception = !maybe_function_info.ToHandle(&result); @@ -2744,11 +2580,6 @@ uint32_t ScriptCompiler::CachedDataVersionTag() { } ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCache( - Local<UnboundScript> unbound_script, Local<String> source) { - return CreateCodeCache(unbound_script); -} - -ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCache( Local<UnboundScript> unbound_script) { i::Handle<i::SharedFunctionInfo> shared = i::Handle<i::SharedFunctionInfo>::cast( @@ -2768,11 +2599,6 @@ ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCache( } ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCacheForFunction( - Local<Function> function, Local<String> source) { - return CreateCodeCacheForFunction(function); -} - -ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCacheForFunction( Local<Function> function) { auto js_function = i::Handle<i::JSFunction>::cast(Utils::OpenHandle(*function)); @@ -2793,27 +2619,6 @@ MaybeLocal<Script> Script::Compile(Local<Context> context, Local<String> source, } -Local<Script> Script::Compile(v8::Local<String> source, - v8::ScriptOrigin* origin) { - auto str = Utils::OpenHandle(*source); - DISABLE_DEPRECATED_WARNINGS - auto context = UnsafeContextFromHeapObject(str); - RESET_DEPRECATED_WARNINGS - RETURN_TO_LOCAL_UNCHECKED(Compile(context, source, origin), Script); -} - - -Local<Script> Script::Compile(v8::Local<String> source, - v8::Local<String> file_name) { - auto str = Utils::OpenHandle(*source); - DISABLE_DEPRECATED_WARNINGS - auto context = UnsafeContextFromHeapObject(str); - RESET_DEPRECATED_WARNINGS - ScriptOrigin origin(file_name); - return Compile(context, source, &origin).FromMaybe(Local<Script>()); -} - - // --- E x c e p t i o n s --- v8::TryCatch::TryCatch(v8::Isolate* isolate) @@ -2919,12 +2724,6 @@ MaybeLocal<Value> v8::TryCatch::StackTrace(Local<Context> context) const { } -v8::Local<Value> v8::TryCatch::StackTrace() const { - auto context = reinterpret_cast<v8::Isolate*>(isolate_)->GetCurrentContext(); - RETURN_TO_LOCAL_UNCHECKED(StackTrace(context), Value); -} - - v8::Local<v8::Message> v8::TryCatch::Message() const { i::Object* message = reinterpret_cast<i::Object*>(message_obj_); DCHECK(message->IsJSMessageObject() || message->IsTheHole(isolate_)); @@ -2978,6 +2777,10 @@ Local<String> Message::Get() const { return scope.Escape(result); } +v8::Isolate* Message::GetIsolate() const { + i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); + return reinterpret_cast<Isolate*>(isolate); +} ScriptOrigin Message::GetScriptOrigin() const { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); @@ -3015,12 +2818,6 @@ Maybe<int> Message::GetLineNumber(Local<Context> context) const { } -int Message::GetLineNumber() const { - auto context = ContextFromNeverReadOnlySpaceObject(Utils::OpenHandle(this)); - return GetLineNumber(context).FromMaybe(0); -} - - int Message::GetStartPosition() const { auto self = Utils::OpenHandle(this); return self->start_position(); @@ -3094,12 +2891,6 @@ MaybeLocal<String> Message::GetSourceLine(Local<Context> context) const { } -Local<String> Message::GetSourceLine() const { - auto context = ContextFromNeverReadOnlySpaceObject(Utils::OpenHandle(this)); - RETURN_TO_LOCAL_UNCHECKED(GetSourceLine(context), String) -} - - void Message::PrintCurrentStackTrace(Isolate* isolate, FILE* out) { i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); @@ -3119,13 +2910,6 @@ Local<StackFrame> StackTrace::GetFrame(Isolate* v8_isolate, return scope.Escape(Utils::StackFrameToLocal(info)); } -Local<StackFrame> StackTrace::GetFrame(uint32_t index) const { - DISABLE_DEPRECATED_WARNINGS - i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); - RESET_DEPRECATED_WARNINGS - return GetFrame(reinterpret_cast<Isolate*>(isolate), index); -} - int StackTrace::GetFrameCount() const { return Utils::OpenHandle(this)->length(); } @@ -3244,9 +3028,8 @@ MaybeLocal<String> JSON::Stringify(Local<Context> context, ? isolate->factory()->empty_string() : Utils::OpenHandle(*gap); i::Handle<i::Object> maybe; - has_pending_exception = !i::JsonStringifier(isolate) - .Stringify(object, replacer, gap_string) - .ToHandle(&maybe); + has_pending_exception = + !i::JsonStringify(isolate, object, replacer, gap_string).ToHandle(&maybe); RETURN_ON_FAILED_EXECUTION(String); Local<String> result; has_pending_exception = @@ -3580,15 +3363,13 @@ bool Value::IsTypedArray() const { return Utils::OpenHandle(this)->IsJSTypedArray(); } - -#define VALUE_IS_TYPED_ARRAY(Type, typeName, TYPE, ctype, size) \ +#define VALUE_IS_TYPED_ARRAY(Type, typeName, TYPE, ctype) \ bool Value::Is##Type##Array() const { \ i::Handle<i::Object> obj = Utils::OpenHandle(this); \ return obj->IsJSTypedArray() && \ i::JSTypedArray::cast(*obj)->type() == i::kExternal##Type##Array; \ } - TYPED_ARRAYS(VALUE_IS_TYPED_ARRAY) #undef VALUE_IS_TYPED_ARRAY @@ -3616,14 +3397,6 @@ bool Value::IsBigInt() const { return Utils::OpenHandle(this)->IsBigInt(); } bool Value::IsProxy() const { return Utils::OpenHandle(this)->IsJSProxy(); } -bool Value::IsWebAssemblyCompiledModule() const { - i::Handle<i::Object> obj = Utils::OpenHandle(this); - if (!obj->IsJSObject()) return false; - i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj); - return js_obj->GetIsolate()->native_context()->wasm_module_constructor() == - js_obj->map()->GetConstructor(); -} - #define VALUE_IS_SPECIFIC_TYPE(Type, Check) \ bool Value::Is##Type() const { \ i::Handle<i::Object> obj = Utils::OpenHandle(this); \ @@ -3641,6 +3414,7 @@ VALUE_IS_SPECIFIC_TYPE(Map, JSMap) VALUE_IS_SPECIFIC_TYPE(Set, JSSet) VALUE_IS_SPECIFIC_TYPE(WeakMap, JSWeakMap) VALUE_IS_SPECIFIC_TYPE(WeakSet, JSWeakSet) +VALUE_IS_SPECIFIC_TYPE(WebAssemblyCompiledModule, WasmModuleObject) #undef VALUE_IS_SPECIFIC_TYPE @@ -4023,8 +3797,7 @@ void v8::TypedArray::CheckCast(Value* that) { "Could not convert to TypedArray"); } - -#define CHECK_TYPED_ARRAY_CAST(Type, typeName, TYPE, ctype, size) \ +#define CHECK_TYPED_ARRAY_CAST(Type, typeName, TYPE, ctype) \ void v8::Type##Array::CheckCast(Value* that) { \ i::Handle<i::Object> obj = Utils::OpenHandle(that); \ Utils::ApiCheck( \ @@ -4033,7 +3806,6 @@ void v8::TypedArray::CheckCast(Value* that) { "v8::" #Type "Array::Cast()", "Could not convert to " #Type "Array"); \ } - TYPED_ARRAYS(CHECK_TYPED_ARRAY_CAST) #undef CHECK_TYPED_ARRAY_CAST @@ -4110,17 +3882,6 @@ Maybe<bool> Value::BooleanValue(Local<Context> context) const { } -bool Value::BooleanValue() const { - auto obj = Utils::OpenHandle(this); - if (obj->IsSmi()) return *obj != i::Smi::kZero; - DCHECK(obj->IsHeapObject()); - DISABLE_DEPRECATED_WARNINGS - i::Isolate* isolate = i::Handle<i::HeapObject>::cast(obj)->GetIsolate(); - RESET_DEPRECATED_WARNINGS - return obj->BooleanValue(isolate); -} - - Maybe<double> Value::NumberValue(Local<Context> context) const { auto obj = Utils::OpenHandle(this); if (obj->IsNumber()) return Just(obj->Number()); @@ -4134,16 +3895,6 @@ Maybe<double> Value::NumberValue(Local<Context> context) const { } -double Value::NumberValue() const { - auto obj = Utils::OpenHandle(this); - if (obj->IsNumber()) return obj->Number(); - DISABLE_DEPRECATED_WARNINGS - return NumberValue(UnsafeContextFromHeapObject(obj)) - .FromMaybe(std::numeric_limits<double>::quiet_NaN()); - RESET_DEPRECATED_WARNINGS -} - - Maybe<int64_t> Value::IntegerValue(Local<Context> context) const { auto obj = Utils::OpenHandle(this); if (obj->IsNumber()) { @@ -4159,21 +3910,6 @@ Maybe<int64_t> Value::IntegerValue(Local<Context> context) const { } -int64_t Value::IntegerValue() const { - auto obj = Utils::OpenHandle(this); - if (obj->IsNumber()) { - if (obj->IsSmi()) { - return i::Smi::ToInt(*obj); - } else { - return static_cast<int64_t>(obj->Number()); - } - } - DISABLE_DEPRECATED_WARNINGS - return IntegerValue(UnsafeContextFromHeapObject(obj)).FromMaybe(0); - RESET_DEPRECATED_WARNINGS -} - - Maybe<int32_t> Value::Int32Value(Local<Context> context) const { auto obj = Utils::OpenHandle(this); if (obj->IsNumber()) return Just(NumberToInt32(*obj)); @@ -4188,15 +3924,6 @@ Maybe<int32_t> Value::Int32Value(Local<Context> context) const { } -int32_t Value::Int32Value() const { - auto obj = Utils::OpenHandle(this); - if (obj->IsNumber()) return NumberToInt32(*obj); - DISABLE_DEPRECATED_WARNINGS - return Int32Value(UnsafeContextFromHeapObject(obj)).FromMaybe(0); - RESET_DEPRECATED_WARNINGS -} - - Maybe<uint32_t> Value::Uint32Value(Local<Context> context) const { auto obj = Utils::OpenHandle(this); if (obj->IsNumber()) return Just(NumberToUint32(*obj)); @@ -4211,15 +3938,6 @@ Maybe<uint32_t> Value::Uint32Value(Local<Context> context) const { } -uint32_t Value::Uint32Value() const { - auto obj = Utils::OpenHandle(this); - if (obj->IsNumber()) return NumberToUint32(*obj); - DISABLE_DEPRECATED_WARNINGS - return Uint32Value(UnsafeContextFromHeapObject(obj)).FromMaybe(0); - RESET_DEPRECATED_WARNINGS -} - - MaybeLocal<Uint32> Value::ToArrayIndex(Local<Context> context) const { auto self = Utils::OpenHandle(this); if (self->IsSmi()) { @@ -4254,23 +3972,6 @@ Maybe<bool> Value::Equals(Local<Context> context, Local<Value> that) const { } -bool Value::Equals(Local<Value> that) const { - auto self = Utils::OpenHandle(this); - auto other = Utils::OpenHandle(*that); - if (self->IsSmi() && other->IsSmi()) { - return self->Number() == other->Number(); - } - if (self->IsJSObject() && other->IsJSObject()) { - return *self == *other; - } - auto heap_object = self->IsSmi() ? other : self; - DISABLE_DEPRECATED_WARNINGS - auto context = UnsafeContextFromHeapObject(heap_object); - RESET_DEPRECATED_WARNINGS - return Equals(context, that).FromMaybe(false); -} - - bool Value::StrictEquals(Local<Value> that) const { auto self = Utils::OpenHandle(this); auto other = Utils::OpenHandle(*that); @@ -4357,10 +4058,8 @@ Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context, i::Handle<i::Name> key_obj = Utils::OpenHandle(*key); i::Handle<i::Object> value_obj = Utils::OpenHandle(*value); - i::LookupIterator it = i::LookupIterator::PropertyOrElement( - isolate, self, key_obj, self, i::LookupIterator::OWN); - Maybe<bool> result = - i::JSReceiver::CreateDataProperty(&it, value_obj, i::kDontThrow); + Maybe<bool> result = i::JSReceiver::CreateDataProperty( + isolate, self, key_obj, value_obj, i::kDontThrow); has_pending_exception = result.IsNothing(); RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); return result; @@ -5596,11 +5295,6 @@ bool String::ContainsOnlyOneByte() const { return helper.Check(*str); } -int String::Utf8Length() const { - i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); - return Utf8Length(reinterpret_cast<Isolate*>(isolate)); -} - int String::Utf8Length(Isolate* isolate) const { i::Handle<i::String> str = Utils::OpenHandle(this); str = i::String::Flatten(reinterpret_cast<i::Isolate*>(isolate), str); @@ -5843,11 +5537,12 @@ int String::WriteUtf8(Isolate* v8_isolate, char* buffer, int capacity, if (success) return writer.CompleteWrite(write_null, nchars_ref); } else if (capacity >= string_length) { // First check that the buffer is large enough. - int utf8_bytes = Utf8Length(reinterpret_cast<Isolate*>(isolate)); + int utf8_bytes = Utf8Length(v8_isolate); if (utf8_bytes <= capacity) { // one-byte fast path. if (utf8_bytes == string_length) { - WriteOneByte(reinterpret_cast<uint8_t*>(buffer), 0, capacity, options); + WriteOneByte(v8_isolate, reinterpret_cast<uint8_t*>(buffer), 0, + capacity, options); if (nchars_ref != nullptr) *nchars_ref = string_length; if (write_null && (utf8_bytes+1 <= capacity)) { return string_length + 1; @@ -5860,7 +5555,7 @@ int String::WriteUtf8(Isolate* v8_isolate, char* buffer, int capacity, // Recurse once without a capacity limit. // This will get into the first branch above. // TODO(dcarney) Check max left rec. in Utf8Length and fall through. - return WriteUtf8(buffer, -1, nchars_ref, options); + return WriteUtf8(v8_isolate, buffer, -1, nchars_ref, options); } } Utf8WriterVisitor writer(buffer, capacity, false, replace_invalid_utf8); @@ -5868,16 +5563,6 @@ int String::WriteUtf8(Isolate* v8_isolate, char* buffer, int capacity, return writer.CompleteWrite(write_null, nchars_ref); } -int String::WriteUtf8(char* buffer, int capacity, int* nchars_ref, - int options) const { - i::Handle<i::String> str = Utils::OpenHandle(this); - DISABLE_DEPRECATED_WARNINGS - i::Isolate* isolate = str->GetIsolate(); - RESET_DEPRECATED_WARNINGS - return WriteUtf8(reinterpret_cast<Isolate*>(isolate), buffer, capacity, - nchars_ref, options); -} - template <typename CharType> static inline int WriteHelper(i::Isolate* isolate, const String* string, CharType* buffer, int start, int length, @@ -5900,16 +5585,6 @@ static inline int WriteHelper(i::Isolate* isolate, const String* string, } -int String::WriteOneByte(uint8_t* buffer, - int start, - int length, - int options) const { - DISABLE_DEPRECATED_WARNINGS - i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); - RESET_DEPRECATED_WARNINGS - return WriteHelper(isolate, this, buffer, start, length, options); -} - int String::WriteOneByte(Isolate* isolate, uint8_t* buffer, int start, int length, int options) const { return WriteHelper(reinterpret_cast<i::Isolate*>(isolate), this, buffer, @@ -5917,16 +5592,6 @@ int String::WriteOneByte(Isolate* isolate, uint8_t* buffer, int start, } -int String::Write(uint16_t* buffer, - int start, - int length, - int options) const { - DISABLE_DEPRECATED_WARNINGS - i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); - RESET_DEPRECATED_WARNINGS - return WriteHelper(isolate, this, buffer, start, length, options); -} - int String::Write(Isolate* isolate, uint16_t* buffer, int start, int length, int options) const { return WriteHelper(reinterpret_cast<i::Isolate*>(isolate), this, buffer, @@ -5948,11 +5613,16 @@ bool v8::String::IsExternalOneByte() const { void v8::String::VerifyExternalStringResource( v8::String::ExternalStringResource* value) const { - i::Handle<i::String> str = Utils::OpenHandle(this); + i::DisallowHeapAllocation no_allocation; + i::String* str = *Utils::OpenHandle(this); const v8::String::ExternalStringResource* expected; - if (i::StringShape(*str).IsExternalTwoByte()) { - const void* resource = - i::Handle<i::ExternalTwoByteString>::cast(str)->resource(); + + if (str->IsThinString()) { + str = i::ThinString::cast(str)->actual(); + } + + if (i::StringShape(str).IsExternalTwoByte()) { + const void* resource = i::ExternalTwoByteString::cast(str)->resource(); expected = reinterpret_cast<const ExternalStringResource*>(resource); } else { expected = nullptr; @@ -5962,17 +5632,21 @@ void v8::String::VerifyExternalStringResource( void v8::String::VerifyExternalStringResourceBase( v8::String::ExternalStringResourceBase* value, Encoding encoding) const { - i::Handle<i::String> str = Utils::OpenHandle(this); + i::DisallowHeapAllocation no_allocation; + i::String* str = *Utils::OpenHandle(this); const v8::String::ExternalStringResourceBase* expected; Encoding expectedEncoding; - if (i::StringShape(*str).IsExternalOneByte()) { - const void* resource = - i::Handle<i::ExternalOneByteString>::cast(str)->resource(); + + if (str->IsThinString()) { + str = i::ThinString::cast(str)->actual(); + } + + if (i::StringShape(str).IsExternalOneByte()) { + const void* resource = i::ExternalOneByteString::cast(str)->resource(); expected = reinterpret_cast<const ExternalStringResourceBase*>(resource); expectedEncoding = ONE_BYTE_ENCODING; - } else if (i::StringShape(*str).IsExternalTwoByte()) { - const void* resource = - i::Handle<i::ExternalTwoByteString>::cast(str)->resource(); + } else if (i::StringShape(str).IsExternalTwoByte()) { + const void* resource = i::ExternalTwoByteString::cast(str)->resource(); expected = reinterpret_cast<const ExternalStringResourceBase*>(resource); expectedEncoding = TWO_BYTE_ENCODING; } else { @@ -5984,15 +5658,69 @@ void v8::String::VerifyExternalStringResourceBase( CHECK_EQ(expectedEncoding, encoding); } +String::ExternalStringResource* String::GetExternalStringResourceSlow() const { + i::DisallowHeapAllocation no_allocation; + typedef internal::Internals I; + ExternalStringResource* result = nullptr; + i::String* str = *Utils::OpenHandle(this); + + if (str->IsThinString()) { + str = i::ThinString::cast(str)->actual(); + } + + if (i::StringShape(str).IsExternalTwoByte()) { + void* value = I::ReadField<void*>(str, I::kStringResourceOffset); + result = reinterpret_cast<String::ExternalStringResource*>(value); + } + return result; +} + +String::ExternalStringResourceBase* String::GetExternalStringResourceBaseSlow( + String::Encoding* encoding_out) const { + i::DisallowHeapAllocation no_allocation; + typedef internal::Internals I; + ExternalStringResourceBase* resource = nullptr; + i::String* str = *Utils::OpenHandle(this); + + if (str->IsThinString()) { + str = i::ThinString::cast(str)->actual(); + } + + int type = I::GetInstanceType(str) & I::kFullStringRepresentationMask; + *encoding_out = static_cast<Encoding>(type & I::kStringEncodingMask); + if (i::StringShape(str).IsExternalOneByte() || + i::StringShape(str).IsExternalTwoByte()) { + void* value = I::ReadField<void*>(str, I::kStringResourceOffset); + resource = static_cast<ExternalStringResourceBase*>(value); + } + return resource; +} + +const String::ExternalOneByteStringResource* +String::GetExternalOneByteStringResourceSlow() const { + i::DisallowHeapAllocation no_allocation; + i::String* str = *Utils::OpenHandle(this); + + if (str->IsThinString()) { + str = i::ThinString::cast(str)->actual(); + } + + if (i::StringShape(str).IsExternalOneByte()) { + const void* resource = i::ExternalOneByteString::cast(str)->resource(); + return reinterpret_cast<const ExternalOneByteStringResource*>(resource); + } + return nullptr; +} + const v8::String::ExternalOneByteStringResource* v8::String::GetExternalOneByteStringResource() const { - i::Handle<i::String> str = Utils::OpenHandle(this); - if (i::StringShape(*str).IsExternalOneByte()) { - const void* resource = - i::Handle<i::ExternalOneByteString>::cast(str)->resource(); + i::DisallowHeapAllocation no_allocation; + i::String* str = *Utils::OpenHandle(this); + if (i::StringShape(str).IsExternalOneByte()) { + const void* resource = i::ExternalOneByteString::cast(str)->resource(); return reinterpret_cast<const ExternalOneByteStringResource*>(resource); } else { - return nullptr; + return GetExternalOneByteStringResourceSlow(); } } @@ -6000,17 +5728,18 @@ v8::String::GetExternalOneByteStringResource() const { Local<Value> Symbol::Name() const { i::Handle<i::Symbol> sym = Utils::OpenHandle(this); - i::MemoryChunk* chunk = i::MemoryChunk::FromHeapObject(*sym); - // If the Symbol is in RO_SPACE, then its name must be too. Since RO_SPACE - // objects are immovable we can use the Handle(T**) constructor with the - // address of the name field in the Symbol object without needing an isolate. - if (chunk->owner()->identity() == i::RO_SPACE) { + i::Isolate* isolate; + if (!i::Isolate::FromWritableHeapObject(*sym, &isolate)) { + // If the Symbol is in RO_SPACE, then its name must be too. Since RO_SPACE + // objects are immovable we can use the Handle(T**) constructor with the + // address of the name field in the Symbol object without needing an + // isolate. i::Handle<i::HeapObject> ro_name(reinterpret_cast<i::HeapObject**>( sym->GetFieldAddress(i::Symbol::kNameOffset))); return Utils::ToLocal(ro_name); } - i::Handle<i::Object> name(sym->name(), chunk->heap()->isolate()); + i::Handle<i::Object> name(sym->name(), isolate); return Utils::ToLocal(name); } @@ -6207,6 +5936,7 @@ HeapStatistics::HeapStatistics() used_heap_size_(0), heap_size_limit_(0), malloced_memory_(0), + external_memory_(0), peak_malloced_memory_(0), does_zap_garbage_(0), number_of_native_contexts_(0), @@ -6819,14 +6549,6 @@ Local<String> v8::String::Concat(Isolate* v8_isolate, Local<String> left, return Utils::ToLocal(result); } -Local<String> v8::String::Concat(Local<String> left, Local<String> right) { - i::Handle<i::String> left_string = Utils::OpenHandle(*left); - DISABLE_DEPRECATED_WARNINGS - i::Isolate* isolate = left_string->GetIsolate(); - RESET_DEPRECATED_WARNINGS - return Concat(reinterpret_cast<Isolate*>(isolate), left, right); -} - MaybeLocal<String> v8::String::NewExternalTwoByte( Isolate* isolate, v8::String::ExternalStringResource* resource) { CHECK(resource && resource->data()); @@ -6880,73 +6602,83 @@ Local<String> v8::String::NewExternal( bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) { - i::Handle<i::String> obj = Utils::OpenHandle(this); - // RO_SPACE strings cannot be externalized. - i::MemoryChunk* chunk = i::MemoryChunk::FromHeapObject(*obj); - if (chunk->owner()->identity() == i::RO_SPACE) { - return false; - } + i::DisallowHeapAllocation no_allocation; - i::Isolate* isolate = chunk->heap()->isolate(); - if (i::StringShape(*obj).IsExternal()) { - return false; // Already an external string. + i::String* obj = *Utils::OpenHandle(this); + + if (obj->IsThinString()) { + obj = i::ThinString::cast(obj)->actual(); } - ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); - if (isolate->heap()->IsInGCPostProcessing()) { + + if (!obj->SupportsExternalization()) { return false; } + + // It is safe to call FromWritable because SupportsExternalization already + // checked that the object is writable. + i::Isolate* isolate; + i::Isolate::FromWritableHeapObject(obj, &isolate); + ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); + CHECK(resource && resource->data()); bool result = obj->MakeExternal(resource); - // Assert that if CanMakeExternal(), then externalizing actually succeeds. - DCHECK(!CanMakeExternal() || result); - if (result) { - DCHECK(obj->IsExternalString()); - } + DCHECK(result); + DCHECK(obj->IsExternalString()); return result; } bool v8::String::MakeExternal( v8::String::ExternalOneByteStringResource* resource) { - i::Handle<i::String> obj = Utils::OpenHandle(this); + i::DisallowHeapAllocation no_allocation; - // RO_SPACE strings cannot be externalized. - i::MemoryChunk* chunk = i::MemoryChunk::FromHeapObject(*obj); - if (chunk->owner()->identity() == i::RO_SPACE) { - return false; - } + i::String* obj = *Utils::OpenHandle(this); - i::Isolate* isolate = chunk->heap()->isolate(); - if (i::StringShape(*obj).IsExternal()) { - return false; // Already an external string. + if (obj->IsThinString()) { + obj = i::ThinString::cast(obj)->actual(); } - ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); - if (isolate->heap()->IsInGCPostProcessing()) { + + if (!obj->SupportsExternalization()) { return false; } + + // It is safe to call FromWritable because SupportsExternalization already + // checked that the object is writable. + i::Isolate* isolate; + i::Isolate::FromWritableHeapObject(obj, &isolate); + ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); + CHECK(resource && resource->data()); bool result = obj->MakeExternal(resource); - // Assert that if CanMakeExternal(), then externalizing actually succeeds. - DCHECK(!CanMakeExternal() || result); - if (result) { - DCHECK(obj->IsExternalString()); - } + DCHECK(result); + DCHECK(obj->IsExternalString()); return result; } bool v8::String::CanMakeExternal() { - i::Handle<i::String> obj = Utils::OpenHandle(this); - if (obj->IsExternalString()) return false; + i::DisallowHeapAllocation no_allocation; + i::String* obj = *Utils::OpenHandle(this); + + if (obj->IsThinString()) { + obj = i::ThinString::cast(obj)->actual(); + } + + if (!obj->SupportsExternalization()) { + return false; + } // Only old space strings should be externalized. - i::MemoryChunk* chunk = i::MemoryChunk::FromHeapObject(*obj); - i::AllocationSpace space = chunk->owner()->identity(); - return space != i::NEW_SPACE && space != i::RO_SPACE; + return !i::Heap::InNewSpace(obj); } +bool v8::String::StringEquals(Local<String> that) { + auto self = Utils::OpenHandle(this); + auto other = Utils::OpenHandle(*that); + return self->Equals(*other); +} Isolate* v8::Object::GetIsolate() { i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate(); @@ -7026,14 +6758,6 @@ bool v8::BooleanObject::ValueOf() const { } -Local<v8::Value> v8::StringObject::New(Local<String> value) { - i::Handle<i::String> string = Utils::OpenHandle(*value); - DISABLE_DEPRECATED_WARNINGS - i::Isolate* isolate = string->GetIsolate(); - RESET_DEPRECATED_WARNINGS - return New(reinterpret_cast<Isolate*>(isolate), value); -} - Local<v8::Value> v8::StringObject::New(Isolate* v8_isolate, Local<String> value) { i::Handle<i::String> string = Utils::OpenHandle(*value); @@ -7138,14 +6862,6 @@ MaybeLocal<v8::RegExp> v8::RegExp::New(Local<Context> context, } -Local<v8::RegExp> v8::RegExp::New(Local<String> pattern, Flags flags) { - auto isolate = - reinterpret_cast<Isolate*>(Utils::OpenHandle(*pattern)->GetIsolate()); - auto context = isolate->GetCurrentContext(); - RETURN_TO_LOCAL_UNCHECKED(New(context, pattern, flags), RegExp); -} - - Local<v8::String> v8::RegExp::GetSource() const { i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this); return Utils::ToLocal( @@ -7436,12 +7152,6 @@ MaybeLocal<Promise::Resolver> Promise::Resolver::New(Local<Context> context) { } -Local<Promise::Resolver> Promise::Resolver::New(Isolate* isolate) { - RETURN_TO_LOCAL_UNCHECKED(New(isolate->GetCurrentContext()), - Promise::Resolver); -} - - Local<Promise> Promise::Resolver::GetPromise() { i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this); return Local<Promise>::Cast(Utils::ToLocal(promise)); @@ -7467,12 +7177,6 @@ Maybe<bool> Promise::Resolver::Resolve(Local<Context> context, } -void Promise::Resolver::Resolve(Local<Value> value) { - auto context = ContextFromNeverReadOnlySpaceObject(Utils::OpenHandle(this)); - USE(Resolve(context, value)); -} - - Maybe<bool> Promise::Resolver::Reject(Local<Context> context, Local<Value> value) { auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate()); @@ -7492,12 +7196,6 @@ Maybe<bool> Promise::Resolver::Reject(Local<Context> context, } -void Promise::Resolver::Reject(Local<Value> value) { - auto context = ContextFromNeverReadOnlySpaceObject(Utils::OpenHandle(this)); - USE(Reject(context, value)); -} - - MaybeLocal<Promise> Promise::Catch(Local<Context> context, Local<Function> handler) { PREPARE_FOR_EXECUTION(context, Promise, Catch, Promise); @@ -7610,42 +7308,47 @@ Local<String> WasmCompiledModule::GetWasmWireBytes() { .ToLocalChecked(); } -// Currently, wasm modules are bound, both to Isolate and to -// the Context they were created in. The currently-supported means to -// decontextualize and then re-contextualize a module is via -// serialization/deserialization. WasmCompiledModule::TransferrableModule WasmCompiledModule::GetTransferrableModule() { - i::DisallowHeapAllocation no_gc; - WasmCompiledModule::SerializedModule compiled_part = Serialize(); - - BufferReference wire_bytes_ref = GetWasmWireBytesRef(); - size_t wire_size = wire_bytes_ref.size; - std::unique_ptr<uint8_t[]> wire_bytes_copy(new uint8_t[wire_size]); - memcpy(wire_bytes_copy.get(), wire_bytes_ref.start, wire_size); - - return TransferrableModule(std::move(compiled_part), - {std::move(wire_bytes_copy), wire_size}); + if (i::FLAG_wasm_shared_code) { + i::Handle<i::WasmModuleObject> obj = + i::Handle<i::WasmModuleObject>::cast(Utils::OpenHandle(this)); + return TransferrableModule(obj->managed_native_module()->get()); + } else { + WasmCompiledModule::SerializedModule serialized_module = Serialize(); + BufferReference wire_bytes_ref = GetWasmWireBytesRef(); + size_t wire_size = wire_bytes_ref.size; + std::unique_ptr<uint8_t[]> wire_bytes_copy(new uint8_t[wire_size]); + memcpy(wire_bytes_copy.get(), wire_bytes_ref.start, wire_size); + return TransferrableModule(std::move(serialized_module), + {std::move(wire_bytes_copy), wire_size}); + } } MaybeLocal<WasmCompiledModule> WasmCompiledModule::FromTransferrableModule( Isolate* isolate, const WasmCompiledModule::TransferrableModule& transferrable_module) { - MaybeLocal<WasmCompiledModule> ret = - Deserialize(isolate, AsReference(transferrable_module.compiled_code), - AsReference(transferrable_module.wire_bytes)); - return ret; + if (i::FLAG_wasm_shared_code) { + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); + i::Handle<i::WasmModuleObject> module_object = + i_isolate->wasm_engine()->ImportNativeModule( + i_isolate, transferrable_module.shared_module_); + return Local<WasmCompiledModule>::Cast( + Utils::ToLocal(i::Handle<i::JSObject>::cast(module_object))); + } else { + return Deserialize(isolate, AsReference(transferrable_module.serialized_), + AsReference(transferrable_module.wire_bytes_)); + } } WasmCompiledModule::SerializedModule WasmCompiledModule::Serialize() { i::Handle<i::WasmModuleObject> obj = i::Handle<i::WasmModuleObject>::cast(Utils::OpenHandle(this)); i::wasm::NativeModule* native_module = obj->native_module(); - size_t buffer_size = - i::wasm::GetSerializedNativeModuleSize(obj->GetIsolate(), native_module); + i::wasm::WasmSerializer wasm_serializer(obj->GetIsolate(), native_module); + size_t buffer_size = wasm_serializer.GetSerializedNativeModuleSize(); std::unique_ptr<uint8_t[]> buffer(new uint8_t[buffer_size]); - if (i::wasm::SerializeNativeModule(obj->GetIsolate(), native_module, - {buffer.get(), buffer_size})) + if (wasm_serializer.SerializeNativeModule({buffer.get(), buffer_size})) return {std::move(buffer), buffer_size}; return {}; } @@ -7685,9 +7388,11 @@ MaybeLocal<WasmCompiledModule> WasmCompiledModule::Compile(Isolate* isolate, if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) { return MaybeLocal<WasmCompiledModule>(); } + auto enabled_features = i::wasm::WasmFeaturesFromIsolate(i_isolate); i::MaybeHandle<i::JSObject> maybe_compiled = i_isolate->wasm_engine()->SyncCompile( - i_isolate, &thrower, i::wasm::ModuleWireBytes(start, start + length)); + i_isolate, enabled_features, &thrower, + i::wasm::ModuleWireBytes(start, start + length)); if (maybe_compiled.is_null()) return MaybeLocal<WasmCompiledModule>(); return Local<WasmCompiledModule>::Cast( Utils::ToLocal(maybe_compiled.ToHandleChecked())); @@ -7698,7 +7403,7 @@ MaybeLocal<WasmCompiledModule> WasmCompiledModule::Compile(Isolate* isolate, // move to wasm-js.cc. class AsyncCompilationResolver : public i::wasm::CompilationResultResolver { public: - AsyncCompilationResolver(Isolate* isolate, Handle<Promise> promise) + AsyncCompilationResolver(Isolate* isolate, Local<Promise> promise) : promise_( reinterpret_cast<i::Isolate*>(isolate)->global_handles()->Create( *Utils::OpenHandle(*promise))) {} @@ -7726,55 +7431,23 @@ class AsyncCompilationResolver : public i::wasm::CompilationResultResolver { }; WasmModuleObjectBuilderStreaming::WasmModuleObjectBuilderStreaming( - Isolate* isolate) - : isolate_(isolate) { - MaybeLocal<Promise::Resolver> maybe_resolver = - Promise::Resolver::New(isolate->GetCurrentContext()); - Local<Promise::Resolver> resolver = maybe_resolver.ToLocalChecked(); - promise_.Reset(isolate, resolver->GetPromise()); - - i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); - streaming_decoder_ = i_isolate->wasm_engine()->StartStreamingCompilation( - i_isolate, handle(i_isolate->context(), i_isolate), - base::make_unique<AsyncCompilationResolver>(isolate, GetPromise())); + Isolate* isolate) { + USE(isolate_); } -Local<Promise> WasmModuleObjectBuilderStreaming::GetPromise() { - return promise_.Get(isolate_); -} +Local<Promise> WasmModuleObjectBuilderStreaming::GetPromise() { return {}; } void WasmModuleObjectBuilderStreaming::OnBytesReceived(const uint8_t* bytes, size_t size) { - streaming_decoder_->OnBytesReceived(i::Vector<const uint8_t>(bytes, size)); } void WasmModuleObjectBuilderStreaming::Finish() { - streaming_decoder_->Finish(); } void WasmModuleObjectBuilderStreaming::Abort(MaybeLocal<Value> exception) { - Local<Promise> promise = GetPromise(); - // The promise has already been resolved, e.g. because of a compilation - // error. - if (promise->State() != v8::Promise::kPending) return; - streaming_decoder_->Abort(); - - // If no exception value is provided, we do not reject the promise. This can - // happen when streaming compilation gets aborted when no script execution is - // allowed anymore, e.g. when a browser tab gets refreshed. - if (exception.IsEmpty()) return; - - Local<Promise::Resolver> resolver = promise.As<Promise::Resolver>(); - i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate_); - i::HandleScope scope(i_isolate); - Local<Context> context = - Utils::ToLocal(handle(i_isolate->context(), i_isolate)); - auto maybe = resolver->Reject(context, exception.ToLocalChecked()); - CHECK_IMPLIES(!maybe.FromMaybe(false), i_isolate->has_scheduled_exception()); } WasmModuleObjectBuilderStreaming::~WasmModuleObjectBuilderStreaming() { - promise_.Reset(); } // static @@ -7799,35 +7472,53 @@ v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() { "ArrayBuffer already externalized"); self->set_is_external(true); - // We need to capture the contents before releasing the allocation from the - // Wasm tracker, because otherwise we will not correctly capture the - // allocation data. const v8::ArrayBuffer::Contents contents = GetContents(); - if (self->is_wasm_memory()) { - // Since this is being externalized, the Wasm Allocation Tracker can no - // longer track it. - // - // TODO(eholk): Find a way to track this across externalization - self->StopTrackingWasmMemory(isolate); - } isolate->heap()->UnregisterArrayBuffer(*self); // A regular copy is good enough. No move semantics needed. return contents; } +v8::ArrayBuffer::Contents::Contents(void* data, size_t byte_length, + void* allocation_base, + size_t allocation_length, + Allocator::AllocationMode allocation_mode, + DeleterCallback deleter, void* deleter_data) + : data_(data), + byte_length_(byte_length), + allocation_base_(allocation_base), + allocation_length_(allocation_length), + allocation_mode_(allocation_mode), + deleter_(deleter), + deleter_data_(deleter_data) { + DCHECK_LE(allocation_base_, data_); + DCHECK_LE(byte_length_, allocation_length_); +} + +void WasmMemoryDeleter(void* buffer, size_t lenght, void* info) { + internal::wasm::WasmEngine* engine = + reinterpret_cast<internal::wasm::WasmEngine*>(info); + CHECK(engine->memory_tracker()->FreeMemoryIfIsWasmMemory(nullptr, buffer)); +} + +void ArrayBufferDeleter(void* buffer, size_t length, void* info) { + v8::ArrayBuffer::Allocator* allocator = + reinterpret_cast<v8::ArrayBuffer::Allocator*>(info); + allocator->Free(buffer, length); +} v8::ArrayBuffer::Contents v8::ArrayBuffer::GetContents() { i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this); size_t byte_length = static_cast<size_t>(self->byte_length()->Number()); - Contents contents; - contents.allocation_base_ = self->allocation_base(); - contents.allocation_length_ = self->allocation_length(); - contents.allocation_mode_ = self->is_wasm_memory() - ? Allocator::AllocationMode::kReservation - : Allocator::AllocationMode::kNormal; - contents.data_ = self->backing_store(); - contents.byte_length_ = byte_length; + Contents contents( + self->backing_store(), byte_length, self->allocation_base(), + self->allocation_length(), + self->is_wasm_memory() ? Allocator::AllocationMode::kReservation + : Allocator::AllocationMode::kNormal, + self->is_wasm_memory() ? WasmMemoryDeleter : ArrayBufferDeleter, + self->is_wasm_memory() + ? static_cast<void*>(self->GetIsolate()->wasm_engine()) + : static_cast<void*>(self->GetIsolate()->array_buffer_allocator())); return contents; } @@ -7948,13 +7639,13 @@ size_t v8::ArrayBufferView::ByteLength() { size_t v8::TypedArray::Length() { i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this); - return static_cast<size_t>(obj->length_value()); + return obj->length_value(); } static_assert(v8::TypedArray::kMaxLength == i::Smi::kMaxValue, "v8::TypedArray::kMaxLength must match i::Smi::kMaxValue"); -#define TYPED_ARRAY_NEW(Type, type, TYPE, ctype, size) \ +#define TYPED_ARRAY_NEW(Type, type, TYPE, ctype) \ Local<Type##Array> Type##Array::New(Local<ArrayBuffer> array_buffer, \ size_t byte_offset, size_t length) { \ i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate(); \ @@ -8025,7 +7716,6 @@ bool v8::SharedArrayBuffer::IsExternal() const { return Utils::OpenHandle(this)->is_external(); } - v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::Externalize() { i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this); i::Isolate* isolate = self->GetIsolate(); @@ -8033,46 +7723,51 @@ v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::Externalize() { "SharedArrayBuffer already externalized"); self->set_is_external(true); - // We need to capture the contents before releasing the allocation from the - // Wasm tracker, because otherwise we will not correctly capture the - // allocation data. const v8::SharedArrayBuffer::Contents contents = GetContents(); - if (self->is_wasm_memory()) { - // Since this is being externalized, the Wasm Allocation Tracker can no - // longer track it. - // - // TODO(eholk): Find a way to track this across externalization - self->StopTrackingWasmMemory(isolate); - } isolate->heap()->UnregisterArrayBuffer(*self); // A regular copy is good enough. No move semantics needed. return contents; } +v8::SharedArrayBuffer::Contents::Contents( + void* data, size_t byte_length, void* allocation_base, + size_t allocation_length, Allocator::AllocationMode allocation_mode, + DeleterCallback deleter, void* deleter_data) + : data_(data), + byte_length_(byte_length), + allocation_base_(allocation_base), + allocation_length_(allocation_length), + allocation_mode_(allocation_mode), + deleter_(deleter), + deleter_data_(deleter_data) { + DCHECK_LE(allocation_base_, data_); + DCHECK_LE(byte_length_, allocation_length_); +} v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::GetContents() { i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this); size_t byte_length = static_cast<size_t>(self->byte_length()->Number()); - Contents contents; - contents.allocation_base_ = self->allocation_base(); - contents.allocation_length_ = self->allocation_length(); - contents.allocation_mode_ = + Contents contents( + self->backing_store(), byte_length, self->allocation_base(), + self->allocation_length(), + self->is_wasm_memory() + ? ArrayBuffer::Allocator::AllocationMode::kReservation + : ArrayBuffer::Allocator::AllocationMode::kNormal, + self->is_wasm_memory() + ? reinterpret_cast<Contents::DeleterCallback>(WasmMemoryDeleter) + : reinterpret_cast<Contents::DeleterCallback>(ArrayBufferDeleter), self->is_wasm_memory() - ? ArrayBufferAllocator::Allocator::AllocationMode::kReservation - : ArrayBufferAllocator::Allocator::AllocationMode::kNormal; - contents.data_ = self->backing_store(); - contents.byte_length_ = byte_length; + ? static_cast<void*>(self->GetIsolate()->wasm_engine()) + : static_cast<void*>(self->GetIsolate()->array_buffer_allocator())); return contents; } - size_t v8::SharedArrayBuffer::ByteLength() const { i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this); return static_cast<size_t>(obj->byte_length()->Number()); } - Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(Isolate* isolate, size_t byte_length) { CHECK(i::FLAG_harmony_sharedarraybuffer); @@ -8102,9 +7797,11 @@ Local<SharedArrayBuffer> v8::SharedArrayBuffer::New( ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); i::Handle<i::JSArrayBuffer> obj = i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kShared); + bool is_wasm_memory = + i_isolate->wasm_engine()->memory_tracker()->IsWasmMemory(data); i::JSArrayBuffer::Setup(obj, i_isolate, mode == ArrayBufferCreationMode::kExternalized, data, - byte_length, i::SharedFlag::kShared); + byte_length, i::SharedFlag::kShared, is_wasm_memory); return Utils::ToLocalShared(obj); } @@ -8302,14 +7999,6 @@ v8::Local<v8::Context> Isolate::GetCurrentContext() { } -v8::Local<v8::Context> Isolate::GetCallingContext() { - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); - i::Handle<i::Object> calling = isolate->GetCallingNativeContext(); - if (calling.is_null()) return Local<Context>(); - return Utils::ToLocal(i::Handle<i::Context>::cast(calling)); -} - - v8::Local<v8::Context> Isolate::GetEnteredContext() { i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); i::Handle<i::Object> last = @@ -8670,6 +8359,7 @@ void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) { heap_statistics->malloced_memory_ = isolate->allocator()->GetCurrentMemoryUsage() + isolate->wasm_engine()->allocator()->GetCurrentMemoryUsage(); + heap_statistics->external_memory_ = isolate->heap()->external_memory(); heap_statistics->peak_malloced_memory_ = isolate->allocator()->GetMaxMemoryUsage() + isolate->wasm_engine()->allocator()->GetMaxMemoryUsage(); @@ -8806,18 +8496,6 @@ void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) { isolate->RemoveCallCompletedCallback(callback); } -void Isolate::AddCallCompletedCallback( - DeprecatedCallCompletedCallback callback) { - AddCallCompletedCallback(reinterpret_cast<CallCompletedCallback>(callback)); -} - - -void Isolate::RemoveCallCompletedCallback( - DeprecatedCallCompletedCallback callback) { - RemoveCallCompletedCallback( - reinterpret_cast<CallCompletedCallback>(callback)); -} - void Isolate::AtomicsWaitWakeHandle::Wake() { reinterpret_cast<i::AtomicsWaitWakeHandle*>(this)->Wake(); } @@ -8861,17 +8539,6 @@ void Isolate::EnqueueMicrotask(MicrotaskCallback callback, void* data) { } -void Isolate::SetAutorunMicrotasks(bool autorun) { - SetMicrotasksPolicy( - autorun ? MicrotasksPolicy::kAuto : MicrotasksPolicy::kExplicit); -} - - -bool Isolate::WillAutorunMicrotasks() const { - return GetMicrotasksPolicy() == MicrotasksPolicy::kAuto; -} - - void Isolate::SetMicrotasksPolicy(MicrotasksPolicy policy) { i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); isolate->handle_scope_implementer()->set_microtasks_policy(policy); @@ -8959,7 +8626,7 @@ int Isolate::ContextDisposedNotification(bool dependant_context) { if (!dependant_context) { // We left the current context, we can abort all WebAssembly compilations on // that isolate. - isolate->wasm_engine()->AbortCompileJobsOnIsolate(isolate); + isolate->wasm_engine()->DeleteCompileJobsOnIsolate(isolate); } // TODO(ahaas): move other non-heap activity out of the heap call. return isolate->heap()->NotifyContextDisposed(dependant_context); @@ -9065,6 +8732,9 @@ CALLBACK_SETTER(WasmCompileStreamingCallback, ApiImplementationCallback, CALLBACK_SETTER(WasmStreamingCallback, WasmStreamingCallback, wasm_streaming_callback) +CALLBACK_SETTER(WasmThreadsEnabledCallback, WasmThreadsEnabledCallback, + wasm_threads_enabled_callback) + void Isolate::AddNearHeapLimitCallback(v8::NearHeapLimitCallback callback, void* data) { i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); @@ -9235,12 +8905,9 @@ String::Utf8Value::Utf8Value(v8::Isolate* isolate, v8::Local<v8::Value> obj) if (!obj->ToString(context).ToLocal(&str)) return; length_ = str->Utf8Length(isolate); str_ = i::NewArray<char>(length_ + 1); - str->WriteUtf8(str_); + str->WriteUtf8(isolate, str_); } -String::Utf8Value::Utf8Value(v8::Local<v8::Value> obj) - : String::Utf8Value::Utf8Value(Isolate::GetCurrent(), obj) {} - String::Utf8Value::~Utf8Value() { i::DeleteArray(str_); } @@ -9257,12 +8924,9 @@ String::Value::Value(v8::Isolate* isolate, v8::Local<v8::Value> obj) if (!obj->ToString(context).ToLocal(&str)) return; length_ = str->Length(); str_ = i::NewArray<uint16_t>(length_ + 1); - str->Write(str_); + str->Write(isolate, str_); } -String::Value::Value(v8::Local<v8::Value> obj) - : String::Value::Value(v8::Isolate::GetCurrent(), obj) {} - String::Value::~Value() { i::DeleteArray(str_); } @@ -9757,7 +9421,7 @@ MaybeLocal<UnboundScript> debug::CompileInspectorScript(Isolate* v8_isolate, i::ScriptData* script_data = nullptr; i::MaybeHandle<i::SharedFunctionInfo> maybe_function_info = i::Compiler::GetSharedFunctionInfoForScript( - str, i::Compiler::ScriptDetails(), origin_options, nullptr, + isolate, str, i::Compiler::ScriptDetails(), origin_options, nullptr, script_data, ScriptCompiler::kNoCompileOptions, ScriptCompiler::kNoCacheBecauseInspector, i::FLAG_expose_inspector_scripts ? i::NOT_NATIVES_CODE @@ -9990,7 +9654,6 @@ void debug::GlobalLexicalScopeNames( void debug::SetReturnValue(v8::Isolate* v8_isolate, v8::Local<v8::Value> value) { i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); - if (!isolate->debug()->break_id()) return; isolate->debug()->set_return_value(*Utils::OpenHandle(*value)); } @@ -10773,6 +10436,55 @@ void EmbedderHeapTracer::FinalizeTracing() { } } +void EmbedderHeapTracer::GarbageCollectionForTesting( + EmbedderStackState stack_state) { + CHECK(isolate_); + CHECK(i::FLAG_expose_gc); + i::Heap* const heap = reinterpret_cast<i::Isolate*>(isolate_)->heap(); + heap->SetEmbedderStackStateForNextFinalizaton(stack_state); + heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask, + i::GarbageCollectionReason::kTesting, + kGCCallbackFlagForced); +} + +bool EmbedderHeapTracer::AdvanceTracing(double deadline_in_ms) { +#if __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated" +#endif + return !this->AdvanceTracing( + deadline_in_ms, AdvanceTracingActions(std::isinf(deadline_in_ms) + ? FORCE_COMPLETION + : DO_NOT_FORCE_COMPLETION)); +#if __clang__ +#pragma clang diagnostic pop +#endif +} + +void EmbedderHeapTracer::EnterFinalPause(EmbedderStackState stack_state) { +#if __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated" +#endif + this->EnterFinalPause(); +#if __clang__ +#pragma clang diagnostic pop +#endif +} + +bool EmbedderHeapTracer::IsTracingDone() { +// TODO(mlippautz): Implement using "return true" after removing the deprecated +// call. +#if __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated" +#endif + return NumberOfWrappersToTrace() == 0; +#if __clang__ +#pragma clang diagnostic pop +#endif +} + namespace internal { void HandleScopeImplementer::FreeThreadResources() { @@ -10968,8 +10680,6 @@ void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info, #undef SET_FIELD_WRAPPED #undef NEW_STRING #undef CALLBACK_SETTER -#undef DISABLE_DEPRECATED_WARNINGS -#undef RESET_DEPRECATED_WARNINGS } // namespace internal } // namespace v8 |