diff options
Diffstat (limited to 'deps/v8/src/runtime/runtime-test.cc')
-rw-r--r-- | deps/v8/src/runtime/runtime-test.cc | 238 |
1 files changed, 168 insertions, 70 deletions
diff --git a/deps/v8/src/runtime/runtime-test.cc b/deps/v8/src/runtime/runtime-test.cc index 19a4af50d1..b3cdf3fe67 100644 --- a/deps/v8/src/runtime/runtime-test.cc +++ b/deps/v8/src/runtime/runtime-test.cc @@ -17,9 +17,11 @@ #include "src/runtime-profiler.h" #include "src/snapshot/code-serializer.h" #include "src/snapshot/natives.h" +#include "src/trap-handler/trap-handler.h" #include "src/wasm/memory-tracing.h" #include "src/wasm/wasm-module.h" #include "src/wasm/wasm-objects-inl.h" +#include "src/wasm/wasm-serialization.h" namespace { struct WasmCompileControls { @@ -127,12 +129,6 @@ RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) { // If the function is not optimized, just return. if (!function->IsOptimized()) return isolate->heap()->undefined_value(); - // TODO(turbofan): Deoptimization from AstGraphBuilder is not supported. - if (function->code()->is_turbofanned() && - !function->shared()->HasBytecodeArray()) { - return isolate->heap()->undefined_value(); - } - Deoptimizer::DeoptimizeFunction(*function); return isolate->heap()->undefined_value(); @@ -153,12 +149,6 @@ RUNTIME_FUNCTION(Runtime_DeoptimizeNow) { // If the function is not optimized, just return. if (!function->IsOptimized()) return isolate->heap()->undefined_value(); - // TODO(turbofan): Deoptimization from AstGraphBuilder is not supported. - if (function->code()->is_turbofanned() && - !function->shared()->HasBytecodeArray()) { - return isolate->heap()->undefined_value(); - } - Deoptimizer::DeoptimizeFunction(*function); return isolate->heap()->undefined_value(); @@ -482,7 +472,7 @@ RUNTIME_FUNCTION(Runtime_CheckWasmWrapperElision) { // calls an intermediate function, and the intermediate function // calls exactly one imported function HandleScope scope(isolate); - CHECK(args.length() == 2); + CHECK_EQ(args.length(), 2); // It takes two parameters, the first one is the JSFunction, // The second one is the type CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); @@ -492,48 +482,100 @@ RUNTIME_FUNCTION(Runtime_CheckWasmWrapperElision) { CONVERT_ARG_HANDLE_CHECKED(Smi, type, 1); Handle<Code> export_code = handle(function->code()); CHECK(export_code->kind() == Code::JS_TO_WASM_FUNCTION); - int const mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET); + int const mask = + RelocInfo::ModeMask(FLAG_wasm_jit_to_native ? RelocInfo::JS_TO_WASM_CALL + : RelocInfo::CODE_TARGET); // check the type of the $export_fct - Handle<Code> export_fct; + wasm::WasmCode* export_fct = nullptr; + Handle<Code> export_fct_handle; + wasm::WasmCode* intermediate_fct = nullptr; + Handle<Code> intermediate_fct_handle; + int count = 0; for (RelocIterator it(*export_code, mask); !it.done(); it.next()) { RelocInfo* rinfo = it.rinfo(); - Address target_address = rinfo->target_address(); - Code* target = Code::GetCodeFromTargetAddress(target_address); - if (target->kind() == Code::WASM_FUNCTION) { - ++count; - export_fct = handle(target); + Address target_address = FLAG_wasm_jit_to_native + ? rinfo->js_to_wasm_address() + : rinfo->target_address(); + if (FLAG_wasm_jit_to_native) { + wasm::WasmCode* target = + isolate->wasm_code_manager()->LookupCode(target_address); + if (target->kind() == wasm::WasmCode::Function) { + ++count; + export_fct = target; + } + } else { + Code* target = Code::GetCodeFromTargetAddress(target_address); + if (target->kind() == Code::WASM_FUNCTION) { + ++count; + export_fct_handle = handle(target); + } } } - CHECK(count == 1); + CHECK_EQ(count, 1); // check the type of the intermediate_fct - Handle<Code> intermediate_fct; count = 0; - for (RelocIterator it(*export_fct, mask); !it.done(); it.next()) { - RelocInfo* rinfo = it.rinfo(); - Address target_address = rinfo->target_address(); - Code* target = Code::GetCodeFromTargetAddress(target_address); - if (target->kind() == Code::WASM_FUNCTION) { - ++count; - intermediate_fct = handle(target); + if (FLAG_wasm_jit_to_native) { + for (RelocIterator it(export_fct->instructions(), export_fct->reloc_info(), + export_fct->constant_pool(), + RelocInfo::ModeMask(RelocInfo::WASM_CALL)); + !it.done(); it.next()) { + RelocInfo* rinfo = it.rinfo(); + Address target_address = rinfo->target_address(); + wasm::WasmCode* target = + isolate->wasm_code_manager()->LookupCode(target_address); + if (target->kind() == wasm::WasmCode::Function) { + ++count; + intermediate_fct = target; + } + } + } else { + count = 0; + for (RelocIterator it(*export_fct_handle, mask); !it.done(); it.next()) { + RelocInfo* rinfo = it.rinfo(); + Address target_address = rinfo->target_address(); + Code* target = Code::GetCodeFromTargetAddress(target_address); + if (target->kind() == Code::WASM_FUNCTION) { + ++count; + intermediate_fct_handle = handle(target); + } } } - CHECK(count == 1); + CHECK_EQ(count, 1); // Check the type of the imported exported function, it should be also a wasm // function in our case. - Handle<Code> imported_fct; CHECK(type->value() == 0 || type->value() == 1); - Code::Kind target_kind = - type->value() == 0 ? Code::WASM_FUNCTION : Code::WASM_TO_JS_FUNCTION; count = 0; - for (RelocIterator it(*intermediate_fct, mask); !it.done(); it.next()) { - RelocInfo* rinfo = it.rinfo(); - Address target_address = rinfo->target_address(); - Code* target = Code::GetCodeFromTargetAddress(target_address); - if (target->kind() == target_kind) { - ++count; - imported_fct = handle(target); + if (FLAG_wasm_jit_to_native) { + wasm::WasmCode::Kind target_kind = type->value() == 0 + ? wasm::WasmCode::WasmToWasmWrapper + : wasm::WasmCode::WasmToJsWrapper; + for (RelocIterator it(intermediate_fct->instructions(), + intermediate_fct->reloc_info(), + intermediate_fct->constant_pool(), + RelocInfo::ModeMask(RelocInfo::WASM_CALL)); + !it.done(); it.next()) { + RelocInfo* rinfo = it.rinfo(); + Address target_address = rinfo->target_address(); + wasm::WasmCode* target = + isolate->wasm_code_manager()->LookupCode(target_address); + if (target->kind() == target_kind) { + ++count; + } + } + } else { + Code::Kind target_kind = type->value() == 0 ? Code::WASM_TO_WASM_FUNCTION + : Code::WASM_TO_JS_FUNCTION; + count = 0; + for (RelocIterator it(*intermediate_fct_handle, mask); !it.done(); + it.next()) { + RelocInfo* rinfo = it.rinfo(); + Address target_address = rinfo->target_address(); + Code* target = Code::GetCodeFromTargetAddress(target_address); + if (target->kind() == target_kind) { + ++count; + } } } CHECK_LE(count, 1); @@ -543,7 +585,7 @@ RUNTIME_FUNCTION(Runtime_CheckWasmWrapperElision) { RUNTIME_FUNCTION(Runtime_SetWasmCompileControls) { HandleScope scope(isolate); v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); - CHECK(args.length() == 2); + CHECK_EQ(args.length(), 2); CONVERT_ARG_HANDLE_CHECKED(Smi, block_size, 0); CONVERT_BOOLEAN_ARG_CHECKED(allow_async, 1); WasmCompileControls& ctrl = (*g_PerIsolateWasmControls.Pointer())[v8_isolate]; @@ -556,7 +598,7 @@ RUNTIME_FUNCTION(Runtime_SetWasmCompileControls) { RUNTIME_FUNCTION(Runtime_SetWasmInstantiateControls) { HandleScope scope(isolate); v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); - CHECK(args.length() == 0); + CHECK_EQ(args.length(), 0); v8_isolate->SetWasmInstanceCallback(WasmInstanceOverride); return isolate->heap()->undefined_value(); } @@ -650,12 +692,25 @@ RUNTIME_FUNCTION(Runtime_DebugTrace) { RUNTIME_FUNCTION(Runtime_DebugTrackRetainingPath) { HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); + DCHECK_LE(1, args.length()); + DCHECK_GE(2, args.length()); if (!FLAG_track_retaining_path) { PrintF("DebugTrackRetainingPath requires --track-retaining-path flag.\n"); } else { CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0); - isolate->heap()->AddRetainingPathTarget(object); + RetainingPathOption option = RetainingPathOption::kDefault; + if (args.length() == 2) { + CONVERT_ARG_HANDLE_CHECKED(String, str, 1); + const char track_ephemeral_path[] = "track-ephemeral-path"; + if (str->IsOneByteEqualTo(STATIC_CHAR_VECTOR(track_ephemeral_path))) { + option = RetainingPathOption::kTrackEphemeralPath; + } else if (str->length() != 0) { + PrintF("Unexpected second argument of DebugTrackRetainingPath.\n"); + PrintF("Expected an empty string or '%s', got '%s'.\n", + track_ephemeral_path, str->ToCString().get()); + } + } + isolate->heap()->AddRetainingPathTarget(object, option); } return isolate->heap()->undefined_value(); } @@ -802,11 +857,11 @@ RUNTIME_FUNCTION(Runtime_GetExceptionDetails) { key = factory->NewStringFromAsciiChecked("start_pos"); value = handle(Smi::FromInt(message_obj->start_position()), isolate); - JSObject::SetProperty(message, key, value, STRICT).Assert(); + JSObject::SetProperty(message, key, value, LanguageMode::kStrict).Assert(); key = factory->NewStringFromAsciiChecked("end_pos"); value = handle(Smi::FromInt(message_obj->end_position()), isolate); - JSObject::SetProperty(message, key, value, STRICT).Assert(); + JSObject::SetProperty(message, key, value, LanguageMode::kStrict).Assert(); return *message; } @@ -855,12 +910,18 @@ RUNTIME_FUNCTION(Runtime_DisallowCodegenFromStrings) { DCHECK_EQ(1, args.length()); CONVERT_BOOLEAN_ARG_CHECKED(flag, 0); v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); - if (flag) { - v8_isolate->SetAllowCodeGenerationFromStringsCallback( - DisallowCodegenFromStringsCallback); - } else { - v8_isolate->SetAllowCodeGenerationFromStringsCallback(nullptr); - } + v8_isolate->SetAllowCodeGenerationFromStringsCallback( + flag ? DisallowCodegenFromStringsCallback : nullptr); + return isolate->heap()->undefined_value(); +} + +RUNTIME_FUNCTION(Runtime_DisallowWasmCodegen) { + SealHandleScope shs(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_BOOLEAN_ARG_CHECKED(flag, 0); + v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); + v8_isolate->SetAllowWasmCodeGenerationCallback( + flag ? DisallowCodegenFromStringsCallback : nullptr); return isolate->heap()->undefined_value(); } @@ -932,13 +993,24 @@ RUNTIME_FUNCTION(Runtime_SerializeWasmModule) { CONVERT_ARG_HANDLE_CHECKED(WasmModuleObject, module_obj, 0); Handle<WasmCompiledModule> orig(module_obj->compiled_module()); - std::unique_ptr<ScriptData> data = - WasmCompiledModuleSerializer::SerializeWasmModule(isolate, orig); - void* buff = isolate->array_buffer_allocator()->Allocate(data->length()); - Handle<JSArrayBuffer> ret = isolate->factory()->NewJSArrayBuffer(); - JSArrayBuffer::Setup(ret, isolate, false, buff, data->length()); - memcpy(buff, data->data(), data->length()); - return *ret; + if (FLAG_wasm_jit_to_native) { + std::pair<std::unique_ptr<byte[]>, size_t> serialized_module = + wasm::NativeModuleSerializer::SerializeWholeModule(isolate, orig); + int data_size = static_cast<int>(serialized_module.second); + void* buff = isolate->array_buffer_allocator()->Allocate(data_size); + Handle<JSArrayBuffer> ret = isolate->factory()->NewJSArrayBuffer(); + JSArrayBuffer::Setup(ret, isolate, false, buff, data_size); + memcpy(buff, serialized_module.first.get(), data_size); + return *ret; + } else { + std::unique_ptr<ScriptData> data = + WasmCompiledModuleSerializer::SerializeWasmModule(isolate, orig); + void* buff = isolate->array_buffer_allocator()->Allocate(data->length()); + Handle<JSArrayBuffer> ret = isolate->factory()->NewJSArrayBuffer(); + JSArrayBuffer::Setup(ret, isolate, false, buff, data->length()); + memcpy(buff, data->data(), data->length()); + return *ret; + } } // Take an array buffer and attempt to reconstruct a compiled wasm module. @@ -950,22 +1022,31 @@ RUNTIME_FUNCTION(Runtime_DeserializeWasmModule) { CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, wire_bytes, 1); Address mem_start = static_cast<Address>(buffer->backing_store()); - int mem_size = static_cast<int>(buffer->byte_length()->Number()); + size_t mem_size = static_cast<size_t>(buffer->byte_length()->Number()); // DeserializeWasmModule will allocate. We assume JSArrayBuffer doesn't // get relocated. - ScriptData sc(mem_start, mem_size); bool already_external = wire_bytes->is_external(); if (!already_external) { wire_bytes->set_is_external(true); isolate->heap()->UnregisterArrayBuffer(*wire_bytes); } - MaybeHandle<FixedArray> maybe_compiled_module = - WasmCompiledModuleSerializer::DeserializeWasmModule( - isolate, &sc, - Vector<const uint8_t>( - reinterpret_cast<uint8_t*>(wire_bytes->backing_store()), - static_cast<int>(wire_bytes->byte_length()->Number()))); + MaybeHandle<FixedArray> maybe_compiled_module; + if (FLAG_wasm_jit_to_native) { + maybe_compiled_module = + wasm::NativeModuleDeserializer::DeserializeFullBuffer( + isolate, {mem_start, mem_size}, + Vector<const uint8_t>( + reinterpret_cast<uint8_t*>(wire_bytes->backing_store()), + static_cast<int>(wire_bytes->byte_length()->Number()))); + } else { + ScriptData sc(mem_start, static_cast<int>(mem_size)); + maybe_compiled_module = WasmCompiledModuleSerializer::DeserializeWasmModule( + isolate, &sc, + Vector<const uint8_t>( + reinterpret_cast<uint8_t*>(wire_bytes->backing_store()), + static_cast<int>(wire_bytes->byte_length()->Number()))); + } if (!already_external) { wire_bytes->set_is_external(false); isolate->heap()->RegisterNewArrayBuffer(*wire_bytes); @@ -1058,8 +1139,10 @@ RUNTIME_FUNCTION(Runtime_WasmTraceMemory) { uint32_t addr = (static_cast<uint32_t>(addr_low) & 0xffff) | (static_cast<uint32_t>(addr_high) << 16); - uint8_t* mem_start = reinterpret_cast<uint8_t*>( - frame->wasm_instance()->memory_buffer()->allocation_base()); + uint8_t* mem_start = reinterpret_cast<uint8_t*>(frame->wasm_instance() + ->memory_object() + ->array_buffer() + ->allocation_base()); int func_index = frame->function_index(); int pos = frame->position(); // TODO(titzer): eliminate dependency on WasmModule definition here. @@ -1071,6 +1154,22 @@ RUNTIME_FUNCTION(Runtime_WasmTraceMemory) { return isolate->heap()->undefined_value(); } +RUNTIME_FUNCTION(Runtime_IsLiftoffFunction) { + HandleScope shs(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); + CHECK(WasmExportedFunction::IsWasmExportedFunction(*function)); + WasmCodeWrapper wrapper = + WasmExportedFunction::cast(*function)->GetWasmCode(); + if (!wrapper.IsCodeObject()) { + const wasm::WasmCode* wasm_code = wrapper.GetWasmCode(); + return isolate->heap()->ToBoolean(wasm_code->is_liftoff()); + } else { + Handle<Code> wasm_code = wrapper.GetCode(); + return isolate->heap()->ToBoolean(!wasm_code->is_turbofanned()); + } +} + RUNTIME_FUNCTION(Runtime_CompleteInobjectSlackTracking) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); @@ -1081,6 +1180,5 @@ RUNTIME_FUNCTION(Runtime_CompleteInobjectSlackTracking) { return isolate->heap()->undefined_value(); } - } // namespace internal } // namespace v8 |