diff options
Diffstat (limited to 'deps/v8/src/runtime/runtime-test.cc')
-rw-r--r-- | deps/v8/src/runtime/runtime-test.cc | 154 |
1 files changed, 91 insertions, 63 deletions
diff --git a/deps/v8/src/runtime/runtime-test.cc b/deps/v8/src/runtime/runtime-test.cc index bcc36e9d87..40ca5de401 100644 --- a/deps/v8/src/runtime/runtime-test.cc +++ b/deps/v8/src/runtime/runtime-test.cc @@ -13,9 +13,13 @@ #include "src/base/platform/mutex.h" #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h" #include "src/compiler.h" +#include "src/counters.h" #include "src/deoptimizer.h" #include "src/frames-inl.h" #include "src/isolate-inl.h" +#include "src/objects/heap-object-inl.h" +#include "src/objects/smi.h" +#include "src/ostreams.h" #include "src/runtime-profiler.h" #include "src/snapshot/natives.h" #include "src/trap-handler/trap-handler.h" @@ -34,20 +38,20 @@ struct WasmCompileControls { uint32_t MaxWasmBufferSize = std::numeric_limits<uint32_t>::max(); bool AllowAnySizeForAsync = true; }; +using WasmCompileControlsMap = std::map<v8::Isolate*, WasmCompileControls>; // We need per-isolate controls, because we sometimes run tests in multiple // isolates concurrently. Methods need to hold the accompanying mutex on access. // To avoid upsetting the static initializer count, we lazy initialize this. -base::LazyInstance<std::map<v8::Isolate*, WasmCompileControls>>::type - g_PerIsolateWasmControls = LAZY_INSTANCE_INITIALIZER; -base::LazyInstance<base::Mutex>::type g_PerIsolateWasmControlsMutex = - LAZY_INSTANCE_INITIALIZER; +DEFINE_LAZY_LEAKY_OBJECT_GETTER(WasmCompileControlsMap, + GetPerIsolateWasmControls); +base::LazyMutex g_PerIsolateWasmControlsMutex = LAZY_MUTEX_INITIALIZER; bool IsWasmCompileAllowed(v8::Isolate* isolate, v8::Local<v8::Value> value, bool is_async) { - base::LockGuard<base::Mutex> guard(g_PerIsolateWasmControlsMutex.Pointer()); - DCHECK_GT(g_PerIsolateWasmControls.Get().count(isolate), 0); - const WasmCompileControls& ctrls = g_PerIsolateWasmControls.Get().at(isolate); + base::MutexGuard guard(g_PerIsolateWasmControlsMutex.Pointer()); + DCHECK_GT(GetPerIsolateWasmControls()->count(isolate), 0); + const WasmCompileControls& ctrls = GetPerIsolateWasmControls()->at(isolate); return (is_async && ctrls.AllowAnySizeForAsync) || (value->IsArrayBuffer() && v8::Local<v8::ArrayBuffer>::Cast(value)->ByteLength() <= @@ -58,16 +62,17 @@ bool IsWasmCompileAllowed(v8::Isolate* isolate, v8::Local<v8::Value> value, bool IsWasmInstantiateAllowed(v8::Isolate* isolate, v8::Local<v8::Value> module_or_bytes, bool is_async) { - base::LockGuard<base::Mutex> guard(g_PerIsolateWasmControlsMutex.Pointer()); - DCHECK_GT(g_PerIsolateWasmControls.Get().count(isolate), 0); - const WasmCompileControls& ctrls = g_PerIsolateWasmControls.Get().at(isolate); + base::MutexGuard guard(g_PerIsolateWasmControlsMutex.Pointer()); + DCHECK_GT(GetPerIsolateWasmControls()->count(isolate), 0); + const WasmCompileControls& ctrls = GetPerIsolateWasmControls()->at(isolate); if (is_async && ctrls.AllowAnySizeForAsync) return true; if (!module_or_bytes->IsWebAssemblyCompiledModule()) { return IsWasmCompileAllowed(isolate, module_or_bytes, is_async); } - v8::Local<v8::WasmCompiledModule> module = - v8::Local<v8::WasmCompiledModule>::Cast(module_or_bytes); - return static_cast<uint32_t>(module->GetWasmWireBytesRef().size) <= + v8::Local<v8::WasmModuleObject> module = + v8::Local<v8::WasmModuleObject>::Cast(module_or_bytes); + return static_cast<uint32_t>( + module->GetCompiledModule().GetWireBytesRef().size()) <= ctrls.MaxWasmBufferSize; } @@ -156,7 +161,6 @@ RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) { return ReadOnlyRoots(isolate).undefined_value(); } - RUNTIME_FUNCTION(Runtime_DeoptimizeNow) { HandleScope scope(isolate); DCHECK_EQ(0, args.length()); @@ -176,7 +180,6 @@ RUNTIME_FUNCTION(Runtime_DeoptimizeNow) { return ReadOnlyRoots(isolate).undefined_value(); } - RUNTIME_FUNCTION(Runtime_RunningInSimulator) { SealHandleScope shs(isolate); DCHECK_EQ(0, args.length()); @@ -187,6 +190,11 @@ RUNTIME_FUNCTION(Runtime_RunningInSimulator) { #endif } +RUNTIME_FUNCTION(Runtime_ICsAreEnabled) { + SealHandleScope shs(isolate); + DCHECK_EQ(0, args.length()); + return isolate->heap()->ToBoolean(FLAG_use_ic); +} RUNTIME_FUNCTION(Runtime_IsConcurrentRecompilationSupported) { SealHandleScope shs(isolate); @@ -219,8 +227,16 @@ RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) { } // If function isn't compiled, compile it now. - if (!function->shared()->is_compiled() && - !Compiler::Compile(function, Compiler::CLEAR_EXCEPTION)) { + IsCompiledScope is_compiled_scope(function->shared()->is_compiled_scope()); + if (!is_compiled_scope.is_compiled() && + !Compiler::Compile(function, Compiler::CLEAR_EXCEPTION, + &is_compiled_scope)) { + return ReadOnlyRoots(isolate).undefined_value(); + } + + if (function->shared()->optimization_disabled() && + function->shared()->disable_optimization_reason() == + BailoutReason::kNeverOptimize) { return ReadOnlyRoots(isolate).undefined_value(); } @@ -237,8 +253,13 @@ RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) { ConcurrencyMode concurrency_mode = ConcurrencyMode::kNotConcurrent; if (args.length() == 2) { - CONVERT_ARG_HANDLE_CHECKED(String, type, 1); - if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("concurrent")) && + // Ignore invalid inputs produced by fuzzers. + CONVERT_ARG_HANDLE_CHECKED(Object, type, 1); + if (!type->IsString()) { + return ReadOnlyRoots(isolate).undefined_value(); + } + if (Handle<String>::cast(type)->IsOneByteEqualTo( + StaticCharVector("concurrent")) && isolate->concurrent_recompilation_enabled()) { concurrency_mode = ConcurrencyMode::kConcurrent; } @@ -282,6 +303,12 @@ RUNTIME_FUNCTION(Runtime_OptimizeOsr) { // If the function is already optimized, just return. if (function->IsOptimized()) return ReadOnlyRoots(isolate).undefined_value(); + if (function->shared()->optimization_disabled() && + function->shared()->disable_optimization_reason() == + BailoutReason::kNeverOptimize) { + return ReadOnlyRoots(isolate).undefined_value(); + } + // Ensure that the function is marked for non-concurrent optimization, so that // subsequent runs don't also optimize. if (!function->HasOptimizedCode()) { @@ -296,7 +323,8 @@ RUNTIME_FUNCTION(Runtime_OptimizeOsr) { // Make the profiler arm all back edges in unoptimized code. if (it.frame()->type() == StackFrame::INTERPRETED) { isolate->runtime_profiler()->AttemptOnStackReplacement( - it.frame(), AbstractCode::kMaxLoopNestingMarker); + InterpretedFrame::cast(it.frame()), + AbstractCode::kMaxLoopNestingMarker); } return ReadOnlyRoots(isolate).undefined_value(); @@ -313,8 +341,7 @@ RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) { return ReadOnlyRoots(isolate).undefined_value(); } Handle<JSFunction> function = Handle<JSFunction>::cast(function_object); - function->shared()->DisableOptimization( - BailoutReason::kOptimizationDisabledForTest); + function->shared()->DisableOptimization(BailoutReason::kNeverOptimize); return ReadOnlyRoots(isolate).undefined_value(); } @@ -322,6 +349,9 @@ RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) { HandleScope scope(isolate); DCHECK(args.length() == 1 || args.length() == 2); int status = 0; + if (FLAG_lite_mode) { + status |= static_cast<int>(OptimizationStatus::kLiteMode); + } if (!isolate->use_optimizer()) { status |= static_cast<int>(OptimizationStatus::kNeverOptimize); } @@ -347,7 +377,7 @@ RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) { if (!sync_object->IsString()) return ReadOnlyRoots(isolate).undefined_value(); Handle<String> sync = Handle<String>::cast(sync_object); - if (sync->IsOneByteEqualTo(STATIC_CHAR_VECTOR("no sync"))) { + if (sync->IsOneByteEqualTo(StaticCharVector("no sync"))) { sync_with_compiler_thread = false; } } @@ -433,7 +463,7 @@ RUNTIME_FUNCTION(Runtime_GetUndetectable) { desc->SetCallAsFunctionHandler(ReturnThis); Local<v8::Object> obj; if (!desc->NewInstance(v8_isolate->GetCurrentContext()).ToLocal(&obj)) { - return nullptr; + return Object(); } return *Utils::OpenHandle(*obj); } @@ -481,8 +511,8 @@ RUNTIME_FUNCTION(Runtime_SetWasmCompileControls) { CHECK_EQ(args.length(), 2); CONVERT_ARG_HANDLE_CHECKED(Smi, block_size, 0); CONVERT_BOOLEAN_ARG_CHECKED(allow_async, 1); - base::LockGuard<base::Mutex> guard(g_PerIsolateWasmControlsMutex.Pointer()); - WasmCompileControls& ctrl = (*g_PerIsolateWasmControls.Pointer())[v8_isolate]; + base::MutexGuard guard(g_PerIsolateWasmControlsMutex.Pointer()); + WasmCompileControls& ctrl = (*GetPerIsolateWasmControls())[v8_isolate]; ctrl.AllowAnySizeForAsync = allow_async; ctrl.MaxWasmBufferSize = static_cast<uint32_t>(block_size->value()); v8_isolate->SetWasmModuleCallback(WasmModuleOverride); @@ -533,27 +563,17 @@ RUNTIME_FUNCTION(Runtime_DebugPrint) { SealHandleScope shs(isolate); DCHECK_EQ(1, args.length()); - // Hack: The argument is passed as Object* but here it's really a - // MaybeObject*. - MaybeObject* maybe_object = reinterpret_cast<MaybeObject*>(args[0]); + MaybeObject maybe_object(*args.address_of_arg_at(0)); StdoutStream os; if (maybe_object->IsCleared()) { os << "[weak cleared]"; } else { - Object* object; - HeapObject* heap_object; - bool weak = false; - if (maybe_object->GetHeapObjectIfWeak(&heap_object)) { - weak = true; - object = heap_object; - } else { - // Strong reference or SMI. - object = maybe_object->cast<Object>(); - } + Object object = maybe_object.GetHeapObjectOrSmi(); + bool weak = maybe_object.IsWeak(); #ifdef DEBUG - if (object->IsString() && isolate->context() != nullptr) { + if (object->IsString() && !isolate->context().is_null()) { DCHECK(!weak); // If we have a string, assume it's a code "marker" // and print some interesting cpu debugging info. @@ -625,7 +645,7 @@ RUNTIME_FUNCTION(Runtime_DebugTrackRetainingPath) { if (args.length() == 2) { CONVERT_ARG_HANDLE_CHECKED(String, str, 1); const char track_ephemeron_path[] = "track-ephemeron-path"; - if (str->IsOneByteEqualTo(STATIC_CHAR_VECTOR(track_ephemeron_path))) { + if (str->IsOneByteEqualTo(StaticCharVector(track_ephemeron_path))) { option = RetainingPathOption::kTrackEphemeronPath; } else if (str->length() != 0) { PrintF("Unexpected second argument of DebugTrackRetainingPath.\n"); @@ -695,7 +715,7 @@ RUNTIME_FUNCTION(Runtime_AbortJS) { CONVERT_ARG_HANDLE_CHECKED(String, message, 0); if (FLAG_disable_abortjs) { base::OS::PrintError("[disabled] abort: %s\n", message->ToCString().get()); - return nullptr; + return Object(); } base::OS::PrintError("abort: %s\n", message->ToCString().get()); isolate->PrintStack(stderr); @@ -710,8 +730,9 @@ RUNTIME_FUNCTION(Runtime_DisassembleFunction) { DCHECK_EQ(1, args.length()); // Get the function and make sure it is compiled. CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0); + IsCompiledScope is_compiled_scope; if (!func->is_compiled() && - !Compiler::Compile(func, Compiler::KEEP_EXCEPTION)) { + !Compiler::Compile(func, Compiler::KEEP_EXCEPTION, &is_compiled_scope)) { return ReadOnlyRoots(isolate).exception(); } StdoutStream os; @@ -835,6 +856,12 @@ RUNTIME_FUNCTION(Runtime_IsWasmTrapHandlerEnabled) { return isolate->heap()->ToBoolean(trap_handler::IsTrapHandlerEnabled()); } +RUNTIME_FUNCTION(Runtime_IsThreadInWasm) { + DisallowHeapAllocation no_gc; + DCHECK_EQ(0, args.length()); + return isolate->heap()->ToBoolean(trap_handler::IsThreadInWasm()); +} + RUNTIME_FUNCTION(Runtime_GetWasmRecoveredTrapCount) { HandleScope scope(isolate); DCHECK_EQ(0, args.length()); @@ -863,10 +890,13 @@ RUNTIME_FUNCTION(Runtime_GetWasmExceptionValues) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSReceiver, exception, 0); - RETURN_RESULT_OR_FAILURE( - isolate, JSReceiver::GetProperty( - isolate, exception, - isolate->factory()->wasm_exception_values_symbol())); + Handle<Object> values_obj; + CHECK(JSReceiver::GetProperty( + isolate, exception, + isolate->factory()->wasm_exception_values_symbol()) + .ToHandle(&values_obj)); + Handle<FixedArray> values = Handle<FixedArray>::cast(values_obj); + return *isolate->factory()->NewJSArrayWithElements(values); } namespace { @@ -921,18 +951,16 @@ RUNTIME_FUNCTION(Runtime_ArraySpeciesProtector) { return isolate->heap()->ToBoolean(isolate->IsArraySpeciesLookupChainIntact()); } -RUNTIME_FUNCTION(Runtime_TypedArraySpeciesProtector) { +RUNTIME_FUNCTION(Runtime_MapIteratorProtector) { SealHandleScope shs(isolate); DCHECK_EQ(0, args.length()); - return isolate->heap()->ToBoolean( - isolate->IsTypedArraySpeciesLookupChainIntact()); + return isolate->heap()->ToBoolean(isolate->IsMapIteratorLookupChainIntact()); } -RUNTIME_FUNCTION(Runtime_PromiseSpeciesProtector) { +RUNTIME_FUNCTION(Runtime_SetIteratorProtector) { SealHandleScope shs(isolate); DCHECK_EQ(0, args.length()); - return isolate->heap()->ToBoolean( - isolate->IsPromiseSpeciesLookupChainIntact()); + return isolate->heap()->ToBoolean(isolate->IsSetIteratorLookupChainIntact()); } RUNTIME_FUNCTION(Runtime_StringIteratorProtector) { @@ -950,10 +978,11 @@ RUNTIME_FUNCTION(Runtime_SerializeWasmModule) { CONVERT_ARG_HANDLE_CHECKED(WasmModuleObject, module_obj, 0); wasm::NativeModule* native_module = module_obj->native_module(); - wasm::WasmSerializer wasm_serializer(isolate, native_module); + wasm::WasmSerializer wasm_serializer(native_module); size_t compiled_size = wasm_serializer.GetSerializedNativeModuleSize(); void* array_data = isolate->array_buffer_allocator()->Allocate(compiled_size); - Handle<JSArrayBuffer> array_buffer = isolate->factory()->NewJSArrayBuffer(); + Handle<JSArrayBuffer> array_buffer = + isolate->factory()->NewJSArrayBuffer(SharedFlag::kNotShared); JSArrayBuffer::Setup(array_buffer, isolate, false, array_data, compiled_size); if (!array_data || !wasm_serializer.SerializeNativeModule( @@ -1009,7 +1038,7 @@ RUNTIME_FUNCTION(Runtime_WasmGetNumberOfInstances) { DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(WasmModuleObject, module_obj, 0); int instance_count = 0; - WeakArrayList* weak_instance_list = module_obj->weak_instance_list(); + WeakArrayList weak_instance_list = module_obj->weak_instance_list(); for (int i = 0; i < weak_instance_list->length(); ++i) { if (weak_instance_list->Get(i)->IsWeak()) instance_count++; } @@ -1020,7 +1049,7 @@ RUNTIME_FUNCTION(Runtime_WasmNumInterpretedCalls) { DCHECK_EQ(1, args.length()); HandleScope scope(isolate); CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0); - if (!instance->has_debug_info()) return nullptr; + if (!instance->has_debug_info()) return Object(); uint64_t num = instance->debug_info()->NumInterpretedCalls(); return *isolate->factory()->NewNumberFromSize(static_cast<size_t>(num)); } @@ -1043,7 +1072,7 @@ RUNTIME_FUNCTION(Runtime_WasmTraceMemory) { CONVERT_ARG_CHECKED(Smi, info_addr, 0); wasm::MemoryTracingInfo* info = - reinterpret_cast<wasm::MemoryTracingInfo*>(info_addr); + reinterpret_cast<wasm::MemoryTracingInfo*>(info_addr.ptr()); // Find the caller wasm frame. StackTraceFrameIterator it(isolate); @@ -1071,11 +1100,10 @@ RUNTIME_FUNCTION(Runtime_WasmTierUpFunction) { DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0); CONVERT_SMI_ARG_CHECKED(function_index, 1); - if (!isolate->wasm_engine()->CompileFunction( - isolate, instance->module_object()->native_module(), function_index, - wasm::ExecutionTier::kOptimized)) { - return ReadOnlyRoots(isolate).exception(); - } + auto* native_module = instance->module_object()->native_module(); + isolate->wasm_engine()->CompileFunction( + isolate, native_module, function_index, wasm::ExecutionTier::kOptimized); + CHECK(!native_module->compilation_state()->failed()); return ReadOnlyRoots(isolate).undefined_value(); } |