aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/runtime/runtime-test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/runtime/runtime-test.cc')
-rw-r--r--deps/v8/src/runtime/runtime-test.cc154
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();
}