diff options
author | Michaël Zasso <targos@protonmail.com> | 2021-07-14 11:30:07 +0200 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2021-07-20 15:24:51 +0200 |
commit | 6cdd310275bb0f8056aa0ae6d95614e9ca5b70c7 (patch) | |
tree | 9ed37b19cd668894854b7f469010f7621e63ef81 /deps/v8/src/debug | |
parent | c0f10006c82d2d9896a552de98ed146f9542720d (diff) | |
download | node-new-6cdd310275bb0f8056aa0ae6d95614e9ca5b70c7.tar.gz |
deps: update V8 to 9.2.230.21
PR-URL: https://github.com/nodejs/node/pull/38990
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Robert Nagy <ronagy@icloud.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Diffstat (limited to 'deps/v8/src/debug')
26 files changed, 301 insertions, 893 deletions
diff --git a/deps/v8/src/debug/arm/debug-arm.cc b/deps/v8/src/debug/arm/debug-arm.cc deleted file mode 100644 index 238bc5b85d..0000000000 --- a/deps/v8/src/debug/arm/debug-arm.cc +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#if V8_TARGET_ARCH_ARM - -#include "src/debug/debug.h" - -#include "src/codegen/assembler-inl.h" -#include "src/codegen/macro-assembler.h" -#include "src/debug/liveedit.h" -#include "src/execution/frames-inl.h" -#include "src/objects/objects-inl.h" - -namespace v8 { -namespace internal { - -#define __ ACCESS_MASM(masm) - - -void DebugCodegen::GenerateHandleDebuggerStatement(MacroAssembler* masm) { - { - FrameScope scope(masm, StackFrame::INTERNAL); - __ CallRuntime(Runtime::kHandleDebuggerStatement, 0); - } - __ MaybeDropFrames(); - - // Return to caller. - __ Ret(); -} - -void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) { - // Frame is being dropped: - // - Drop to the target frame specified by r1. - // - Look up current function on the frame. - // - Leave the frame. - // - Restart the frame by calling the function. - __ mov(fp, r1); - __ ldr(r1, MemOperand(fp, StandardFrameConstants::kFunctionOffset)); - __ ldr(r0, MemOperand(fp, StandardFrameConstants::kArgCOffset)); - __ LeaveFrame(StackFrame::INTERNAL); - - // The arguments are already in the stack (including any necessary padding), - // we should not try to massage the arguments again. - __ mov(r2, Operand(kDontAdaptArgumentsSentinel)); - __ InvokeFunction(r1, r2, r0, JUMP_FUNCTION); -} - - -const bool LiveEdit::kFrameDropperSupported = true; - -#undef __ - -} // namespace internal -} // namespace v8 - -#endif // V8_TARGET_ARCH_ARM diff --git a/deps/v8/src/debug/arm64/debug-arm64.cc b/deps/v8/src/debug/arm64/debug-arm64.cc deleted file mode 100644 index b12d235983..0000000000 --- a/deps/v8/src/debug/arm64/debug-arm64.cc +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2013 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#if V8_TARGET_ARCH_ARM64 - -#include "src/debug/debug.h" - -#include "src/codegen/arm64/macro-assembler-arm64-inl.h" -#include "src/debug/liveedit.h" -#include "src/execution/frame-constants.h" -#include "src/execution/frames-inl.h" -#include "src/objects/objects-inl.h" - -namespace v8 { -namespace internal { - -#define __ ACCESS_MASM(masm) - -void DebugCodegen::GenerateHandleDebuggerStatement(MacroAssembler* masm) { - { - FrameScope scope(masm, StackFrame::INTERNAL); - __ CallRuntime(Runtime::kHandleDebuggerStatement, 0); - } - __ MaybeDropFrames(); - - // Return to caller. - __ Ret(); -} - -void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) { - // Frame is being dropped: - // - Drop to the target frame specified by x1. - // - Look up current function on the frame. - // - Leave the frame. - // - Restart the frame by calling the function. - __ Mov(fp, x1); - __ Ldr(x1, MemOperand(fp, StandardFrameConstants::kFunctionOffset)); - __ ldr(x0, MemOperand(fp, StandardFrameConstants::kArgCOffset)); - - __ Mov(sp, fp); - __ Pop<TurboAssembler::kAuthLR>(fp, lr); - - // The arguments are already in the stack (including any necessary padding), - // we should not try to massage the arguments again. - __ Mov(x3, kDontAdaptArgumentsSentinel); - __ InvokeFunctionWithNewTarget(x1, x3, x0, JUMP_FUNCTION); -} - - -const bool LiveEdit::kFrameDropperSupported = true; - -} // namespace internal -} // namespace v8 - -#undef __ - -#endif // V8_TARGET_ARCH_ARM64 diff --git a/deps/v8/src/debug/debug-coverage.cc b/deps/v8/src/debug/debug-coverage.cc index 56933602a6..7ff5809a18 100644 --- a/deps/v8/src/debug/debug-coverage.cc +++ b/deps/v8/src/debug/debug-coverage.cc @@ -61,8 +61,7 @@ bool CompareCoverageBlock(const CoverageBlock& a, const CoverageBlock& b) { return a.start < b.start; } -void SortBlockData( - std::vector<CoverageBlock>& v) { // NOLINT(runtime/references) +void SortBlockData(std::vector<CoverageBlock>& v) { // Sort according to the block nesting structure. std::sort(v.begin(), v.end(), CompareCoverageBlock); } diff --git a/deps/v8/src/debug/debug-evaluate.cc b/deps/v8/src/debug/debug-evaluate.cc index 4f317fcc89..54fac88f59 100644 --- a/deps/v8/src/debug/debug-evaluate.cc +++ b/deps/v8/src/debug/debug-evaluate.cc @@ -43,6 +43,22 @@ MaybeHandle<Object> DebugEvaluate::Global(Isolate* isolate, Handle<String> source, debug::EvaluateGlobalMode mode, REPLMode repl_mode) { + Handle<SharedFunctionInfo> shared_info; + if (!GetFunctionInfo(isolate, source, repl_mode).ToHandle(&shared_info)) { + return MaybeHandle<Object>(); + } + + Handle<NativeContext> context = isolate->native_context(); + Handle<JSFunction> fun = + Factory::JSFunctionBuilder{isolate, shared_info, context}.Build(); + + return Global(isolate, fun, mode, repl_mode); +} + +MaybeHandle<Object> DebugEvaluate::Global(Isolate* isolate, + Handle<JSFunction> function, + debug::EvaluateGlobalMode mode, + REPLMode repl_mode) { // Disable breaks in side-effect free mode. DisableBreak disable_break_scope( isolate->debug(), @@ -50,19 +66,14 @@ MaybeHandle<Object> DebugEvaluate::Global(Isolate* isolate, mode == debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect); - Handle<SharedFunctionInfo> shared_info; - if (!GetFunctionInfo(isolate, source, repl_mode).ToHandle(&shared_info)) { - return MaybeHandle<Object>(); - } + Handle<NativeContext> context = isolate->native_context(); + CHECK_EQ(function->native_context(), *context); - Handle<Context> context = isolate->native_context(); - Handle<JSFunction> fun = - Factory::JSFunctionBuilder{isolate, shared_info, context}.Build(); if (mode == debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) { isolate->debug()->StartSideEffectCheckMode(); } MaybeHandle<Object> result = Execution::Call( - isolate, fun, Handle<JSObject>(context->global_proxy(), isolate), 0, + isolate, function, Handle<JSObject>(context->global_proxy(), isolate), 0, nullptr); if (mode == debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) { isolate->debug()->StopSideEffectCheckMode(); @@ -1108,7 +1119,7 @@ void DebugEvaluate::VerifyTransitiveBuiltins(Isolate* isolate) { } CHECK(!failed); #if defined(V8_TARGET_ARCH_PPC) || defined(V8_TARGET_ARCH_PPC64) || \ - defined(V8_TARGET_ARCH_MIPS64) || defined(V8_TARGET_ARCH_RISCV64) + defined(V8_TARGET_ARCH_MIPS64) // Isolate-independent builtin calls and jumps do not emit reloc infos // on PPC. We try to avoid using PC relative code due to performance // issue with especially older hardwares. diff --git a/deps/v8/src/debug/debug-evaluate.h b/deps/v8/src/debug/debug-evaluate.h index 03836dd6da..34a6c8d4c7 100644 --- a/deps/v8/src/debug/debug-evaluate.h +++ b/deps/v8/src/debug/debug-evaluate.h @@ -27,6 +27,10 @@ class DebugEvaluate : public AllStatic { debug::EvaluateGlobalMode mode, REPLMode repl_mode = REPLMode::kNo); + static V8_EXPORT_PRIVATE MaybeHandle<Object> Global( + Isolate* isolate, Handle<JSFunction> function, + debug::EvaluateGlobalMode mode, REPLMode repl_mode = REPLMode::kNo); + // Evaluate a piece of JavaScript in the context of a stack frame for // debugging. Things that need special attention are: // - Parameters and stack-allocated locals need to be materialized. Altered diff --git a/deps/v8/src/debug/debug-frames.cc b/deps/v8/src/debug/debug-frames.cc index 2e5c9443ca..95b6801481 100644 --- a/deps/v8/src/debug/debug-frames.cc +++ b/deps/v8/src/debug/debug-frames.cc @@ -7,6 +7,10 @@ #include "src/builtins/accessors.h" #include "src/execution/frames-inl.h" +#if V8_ENABLE_WEBASSEMBLY +#include "src/debug/debug-wasm-objects.h" +#endif // V8_ENABLE_WEBASSEMBLY + namespace v8 { namespace internal { @@ -21,7 +25,6 @@ FrameInspector::FrameInspector(CommonFrame* frame, int inlined_frame_index, is_constructor_ = summary.is_constructor(); source_position_ = summary.SourcePosition(); - function_name_ = summary.FunctionName(); script_ = Handle<Script>::cast(summary.script()); receiver_ = summary.receiver(); @@ -70,6 +73,18 @@ Handle<Object> FrameInspector::GetContext() { : handle(frame_->context(), isolate_); } +Handle<String> FrameInspector::GetFunctionName() { +#if V8_ENABLE_WEBASSEMBLY + if (IsWasm()) { + auto wasm_frame = WasmFrame::cast(frame_); + auto wasm_instance = handle(wasm_frame->wasm_instance(), isolate_); + return GetWasmFunctionDebugName(isolate_, wasm_instance, + wasm_frame->function_index()); + } +#endif // V8_ENABLE_WEBASSEMBLY + return JSFunction::GetDebugName(function_); +} + #if V8_ENABLE_WEBASSEMBLY bool FrameInspector::IsWasm() { return frame_->is_wasm(); } #endif // V8_ENABLE_WEBASSEMBLY diff --git a/deps/v8/src/debug/debug-frames.h b/deps/v8/src/debug/debug-frames.h index 03f670e499..5197f86298 100644 --- a/deps/v8/src/debug/debug-frames.h +++ b/deps/v8/src/debug/debug-frames.h @@ -36,7 +36,7 @@ class FrameInspector { Handle<Object> GetContext(); Handle<Object> GetReceiver() { return receiver_; } - Handle<String> GetFunctionName() { return function_name_; } + Handle<String> GetFunctionName(); #if V8_ENABLE_WEBASSEMBLY bool IsWasm(); @@ -58,7 +58,6 @@ class FrameInspector { Handle<Script> script_; Handle<Object> receiver_; Handle<JSFunction> function_; - Handle<String> function_name_; int source_position_ = -1; bool is_optimized_ = false; bool is_constructor_ = false; diff --git a/deps/v8/src/debug/debug-interface.cc b/deps/v8/src/debug/debug-interface.cc index bf74d379b6..bc545a95d4 100644 --- a/deps/v8/src/debug/debug-interface.cc +++ b/deps/v8/src/debug/debug-interface.cc @@ -12,7 +12,9 @@ #include "src/debug/debug.h" #include "src/execution/vm-state-inl.h" #include "src/objects/js-generator-inl.h" +#include "src/objects/stack-frame-info-inl.h" #include "src/regexp/regexp-stack.h" +#include "src/strings/string-builder-inl.h" #if V8_ENABLE_WEBASSEMBLY #include "src/debug/debug-wasm-objects-inl.h" @@ -43,6 +45,54 @@ v8_inspector::V8Inspector* GetInspector(Isolate* isolate) { return reinterpret_cast<i::Isolate*>(isolate)->inspector(); } +Local<String> GetFunctionDebugName(Local<StackFrame> frame) { +#if V8_ENABLE_WEBASSEMBLY + auto info = Utils::OpenHandle(*frame); + if (info->IsWasm()) { + auto isolate = info->GetIsolate(); + auto instance = handle(info->GetWasmInstance(), isolate); + auto func_index = info->GetWasmFunctionIndex(); + return Utils::ToLocal( + i::GetWasmFunctionDebugName(isolate, instance, func_index)); + } +#endif // V8_ENABLE_WEBASSEMBLY + return frame->GetFunctionName(); +} + +Local<String> GetFunctionDescription(Local<Function> function) { + auto receiver = Utils::OpenHandle(*function); + if (receiver->IsJSBoundFunction()) { + return Utils::ToLocal(i::JSBoundFunction::ToString( + i::Handle<i::JSBoundFunction>::cast(receiver))); + } + if (receiver->IsJSFunction()) { + auto function = i::Handle<i::JSFunction>::cast(receiver); +#if V8_ENABLE_WEBASSEMBLY + if (function->shared().HasWasmExportedFunctionData()) { + auto isolate = function->GetIsolate(); + auto func_index = + function->shared().wasm_exported_function_data().function_index(); + auto instance = i::handle( + function->shared().wasm_exported_function_data().instance(), isolate); + if (instance->module()->origin == i::wasm::kWasmOrigin) { + // For asm.js functions, we can still print the source + // code (hopefully), so don't bother with them here. + auto debug_name = + i::GetWasmFunctionDebugName(isolate, instance, func_index); + i::IncrementalStringBuilder builder(isolate); + builder.AppendCString("function "); + builder.AppendString(debug_name); + builder.AppendCString("() { [native code] }"); + return Utils::ToLocal(builder.Finish().ToHandleChecked()); + } + } +#endif // V8_ENABLE_WEBASSEMBLY + return Utils::ToLocal(i::JSFunction::ToString(function)); + } + return Utils::ToLocal( + receiver->GetIsolate()->factory()->function_native_code_string()); +} + void SetBreakOnNextFunctionCall(Isolate* isolate) { reinterpret_cast<i::Isolate*>(isolate)->debug()->SetBreakOnNextFunctionCall(); } @@ -901,6 +951,21 @@ MaybeLocal<v8::Value> EvaluateGlobal(v8::Isolate* isolate, RETURN_ESCAPED(result); } +v8::MaybeLocal<v8::Value> EvaluateGlobalForTesting( + v8::Isolate* isolate, v8::Local<v8::Script> function, + v8::debug::EvaluateGlobalMode mode, bool repl) { + i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); + PREPARE_FOR_DEBUG_INTERFACE_EXECUTION_WITH_ISOLATE(internal_isolate, Value); + i::REPLMode repl_mode = repl ? i::REPLMode::kYes : i::REPLMode::kNo; + Local<Value> result; + has_pending_exception = !ToLocal<Value>( + i::DebugEvaluate::Global(internal_isolate, Utils::OpenHandle(*function), + mode, repl_mode), + &result); + RETURN_ON_FAILED_EXECUTION(Value); + RETURN_ESCAPED(result); +} + void QueryObjects(v8::Local<v8::Context> v8_context, QueryObjectPredicate* predicate, PersistentValueVector<v8::Object>* objects) { @@ -944,10 +1009,12 @@ int64_t GetNextRandomInt64(v8::Isolate* v8_isolate) { void EnumerateRuntimeCallCounters(v8::Isolate* v8_isolate, RuntimeCallCounterCallback callback) { +#ifdef V8_RUNTIME_CALL_STATS i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); if (isolate->counters()) { isolate->counters()->runtime_call_stats()->EnumerateCounters(callback); } +#endif // V8_RUNTIME_CALL_STATS } int GetDebuggingId(v8::Local<v8::Function> function) { diff --git a/deps/v8/src/debug/debug-interface.h b/deps/v8/src/debug/debug-interface.h index 66c7f3997e..6c7ff9cbdd 100644 --- a/deps/v8/src/debug/debug-interface.h +++ b/deps/v8/src/debug/debug-interface.h @@ -7,7 +7,6 @@ #include <memory> -#include "include/v8-inspector.h" #include "include/v8-util.h" #include "include/v8.h" #include "src/base/platform/time.h" @@ -15,6 +14,10 @@ #include "src/debug/interface-types.h" #include "src/utils/vector.h" +namespace v8_inspector { +class V8Inspector; +} // namespace v8_inspector + namespace v8 { namespace internal { @@ -38,6 +41,16 @@ int GetContextId(Local<Context> context); void SetInspector(Isolate* isolate, v8_inspector::V8Inspector*); v8_inspector::V8Inspector* GetInspector(Isolate* isolate); +// Returns the debug name for the function, which is supposed to be used +// by the debugger and the developer tools. This can thus be different from +// the name returned by the StackFrame::GetFunctionName() method. For example, +// in case of WebAssembly, the debug name is WAT-compatible and thus always +// preceeded by a dollar ('$'). +Local<String> GetFunctionDebugName(Local<StackFrame> frame); + +// Returns a debug string representation of the function. +Local<String> GetFunctionDescription(Local<Function> function); + // Schedule a debugger break to happen when function is called inside given // isolate. V8_EXPORT_PRIVATE void SetBreakOnNextFunctionCall(Isolate* isolate); @@ -119,11 +132,7 @@ struct LiveEditResult { OK, COMPILE_ERROR, BLOCKED_BY_RUNNING_GENERATOR, - BLOCKED_BY_FUNCTION_ABOVE_BREAK_FRAME, - BLOCKED_BY_FUNCTION_BELOW_NON_DROPPABLE_FRAME, - BLOCKED_BY_ACTIVE_FUNCTION, - BLOCKED_BY_NEW_TARGET_IN_RESTART_FRAME, - FRAME_RESTART_IS_NOT_SUPPORTED + BLOCKED_BY_ACTIVE_FUNCTION }; Status status = OK; bool stack_changed = false; @@ -195,9 +204,8 @@ class WasmScript : public Script { }; #endif // V8_ENABLE_WEBASSEMBLY -V8_EXPORT_PRIVATE void GetLoadedScripts( - Isolate* isolate, - PersistentValueVector<Script>& scripts); // NOLINT(runtime/references) +V8_EXPORT_PRIVATE void GetLoadedScripts(Isolate* isolate, + PersistentValueVector<Script>& scripts); MaybeLocal<UnboundScript> CompileInspectorScript(Isolate* isolate, Local<String> source); @@ -480,7 +488,6 @@ class V8_EXPORT_PRIVATE StackTraceIterator { virtual v8::Local<v8::Function> GetFunction() const = 0; virtual std::unique_ptr<ScopeIterator> GetScopeIterator() const = 0; - virtual bool Restart() = 0; virtual v8::MaybeLocal<v8::Value> Evaluate(v8::Local<v8::String> source, bool throw_on_side_effect) = 0; }; @@ -523,6 +530,10 @@ V8_EXPORT_PRIVATE v8::MaybeLocal<v8::Value> EvaluateGlobal( v8::Isolate* isolate, v8::Local<v8::String> source, EvaluateGlobalMode mode, bool repl_mode = false); +V8_EXPORT_PRIVATE v8::MaybeLocal<v8::Value> EvaluateGlobalForTesting( + v8::Isolate* isolate, v8::Local<v8::Script> function, + v8::debug::EvaluateGlobalMode mode, bool repl); + int GetDebuggingId(v8::Local<v8::Function> function); bool SetFunctionBreakpoint(v8::Local<v8::Function> function, diff --git a/deps/v8/src/debug/debug-scopes.cc b/deps/v8/src/debug/debug-scopes.cc index 03d49fac5c..5f136d91d3 100644 --- a/deps/v8/src/debug/debug-scopes.cc +++ b/deps/v8/src/debug/debug-scopes.cc @@ -192,7 +192,13 @@ class ScopeChainRetriever { // functions that have the same end position. const bool position_fits_end = closure_scope_ ? position_ < end : position_ <= end; - return start < position_ && position_fits_end; + // While we're evaluating a class, the calling function will have a class + // context on the stack with a range that starts at Token::CLASS, and the + // source position will also point to Token::CLASS. To identify the + // matching scope we include start in the accepted range for class scopes. + const bool position_fits_start = + scope->is_class_scope() ? start <= position_ : start < position_; + return position_fits_start && position_fits_end; } }; diff --git a/deps/v8/src/debug/debug-stack-trace-iterator.cc b/deps/v8/src/debug/debug-stack-trace-iterator.cc index 9904f781f9..93722d0f16 100644 --- a/deps/v8/src/debug/debug-stack-trace-iterator.cc +++ b/deps/v8/src/debug/debug-stack-trace-iterator.cc @@ -172,14 +172,6 @@ DebugStackTraceIterator::GetScopeIterator() const { return std::make_unique<DebugScopeIterator>(isolate_, frame_inspector_.get()); } -bool DebugStackTraceIterator::Restart() { - DCHECK(!Done()); -#if V8_ENABLE_WEBASSEMBLY - if (iterator_.is_wasm()) return false; -#endif // V8_ENABLE_WEBASSEMBLY - return LiveEdit::RestartFrame(iterator_.javascript_frame()); -} - v8::MaybeLocal<v8::Value> DebugStackTraceIterator::Evaluate( v8::Local<v8::String> source, bool throw_on_side_effect) { DCHECK(!Done()); diff --git a/deps/v8/src/debug/debug-stack-trace-iterator.h b/deps/v8/src/debug/debug-stack-trace-iterator.h index 3319bc15f5..2d059e0ec5 100644 --- a/deps/v8/src/debug/debug-stack-trace-iterator.h +++ b/deps/v8/src/debug/debug-stack-trace-iterator.h @@ -31,7 +31,6 @@ class DebugStackTraceIterator final : public debug::StackTraceIterator { v8::Local<v8::Function> GetFunction() const override; std::unique_ptr<v8::debug::ScopeIterator> GetScopeIterator() const override; - bool Restart() override; v8::MaybeLocal<v8::Value> Evaluate(v8::Local<v8::String> source, bool throw_on_side_effect) override; diff --git a/deps/v8/src/debug/debug-wasm-objects.cc b/deps/v8/src/debug/debug-wasm-objects.cc index 070221f433..39286ed027 100644 --- a/deps/v8/src/debug/debug-wasm-objects.cc +++ b/deps/v8/src/debug/debug-wasm-objects.cc @@ -323,15 +323,7 @@ struct FunctionsProxy : NamedDebugProxy<FunctionsProxy, kFunctionsProxy> { static Handle<String> GetName(Isolate* isolate, Handle<WasmInstanceObject> instance, uint32_t index) { - Handle<WasmModuleObject> module_object(instance->module_object(), isolate); - MaybeHandle<String> name = - WasmModuleObject::GetFunctionNameOrNull(isolate, module_object, index); - if (name.is_null()) { - name = GetNameFromImportsAndExportsOrNull( - isolate, instance, wasm::ImportExportKindCode::kExternalFunction, - index); - } - return GetNameOrDefault(isolate, name, "$func", index); + return GetWasmFunctionDebugName(isolate, instance, index); } }; @@ -1050,78 +1042,75 @@ std::unique_ptr<debug::ScopeIterator> GetWasmScopeIterator(WasmFrame* frame) { return std::make_unique<DebugWasmScopeIterator>(frame); } -Handle<JSArray> GetWasmInstanceObjectInternalProperties( - Handle<WasmInstanceObject> instance) { - Isolate* isolate = instance->GetIsolate(); - Handle<FixedArray> result = isolate->factory()->NewFixedArray(2 * 5); - int length = 0; +Handle<String> GetWasmFunctionDebugName(Isolate* isolate, + Handle<WasmInstanceObject> instance, + uint32_t func_index) { + Handle<WasmModuleObject> module_object(instance->module_object(), isolate); + MaybeHandle<String> maybe_name = WasmModuleObject::GetFunctionNameOrNull( + isolate, module_object, func_index); + if (module_object->is_asm_js()) { + // In case of asm.js, we use the names from the function declarations. + return maybe_name.ToHandleChecked(); + } + if (maybe_name.is_null()) { + maybe_name = GetNameFromImportsAndExportsOrNull( + isolate, instance, wasm::ImportExportKindCode::kExternalFunction, + func_index); + } + return GetNameOrDefault(isolate, maybe_name, "$func", func_index); +} - Handle<String> module_str = - isolate->factory()->NewStringFromAsciiChecked("[[Module]]"); - Handle<Object> module_obj = handle(instance->module_object(), isolate); - result->set(length++, *module_str); - result->set(length++, *module_obj); +Handle<ArrayList> AddWasmInstanceObjectInternalProperties( + Isolate* isolate, Handle<ArrayList> result, + Handle<WasmInstanceObject> instance) { + result = ArrayList::Add( + isolate, result, + isolate->factory()->NewStringFromAsciiChecked("[[Module]]"), + handle(instance->module_object(), isolate)); if (FunctionsProxy::Count(isolate, instance) != 0) { - Handle<String> functions_str = - isolate->factory()->NewStringFromAsciiChecked("[[Functions]]"); - Handle<Object> functions_obj = - GetOrCreateInstanceProxy<FunctionsProxy>(isolate, instance); - result->set(length++, *functions_str); - result->set(length++, *functions_obj); + result = ArrayList::Add( + isolate, result, + isolate->factory()->NewStringFromAsciiChecked("[[Functions]]"), + GetOrCreateInstanceProxy<FunctionsProxy>(isolate, instance)); } if (GlobalsProxy::Count(isolate, instance) != 0) { - Handle<String> globals_str = - isolate->factory()->NewStringFromAsciiChecked("[[Globals]]"); - Handle<Object> globals_obj = - GetOrCreateInstanceProxy<GlobalsProxy>(isolate, instance); - result->set(length++, *globals_str); - result->set(length++, *globals_obj); + result = ArrayList::Add( + isolate, result, + isolate->factory()->NewStringFromAsciiChecked("[[Globals]]"), + GetOrCreateInstanceProxy<GlobalsProxy>(isolate, instance)); } if (MemoriesProxy::Count(isolate, instance) != 0) { - Handle<String> memories_str = - isolate->factory()->NewStringFromAsciiChecked("[[Memories]]"); - Handle<Object> memories_obj = - GetOrCreateInstanceProxy<MemoriesProxy>(isolate, instance); - result->set(length++, *memories_str); - result->set(length++, *memories_obj); + result = ArrayList::Add( + isolate, result, + isolate->factory()->NewStringFromAsciiChecked("[[Memories]]"), + GetOrCreateInstanceProxy<MemoriesProxy>(isolate, instance)); } if (TablesProxy::Count(isolate, instance) != 0) { - Handle<String> tables_str = - isolate->factory()->NewStringFromAsciiChecked("[[Tables]]"); - Handle<Object> tables_obj = - GetOrCreateInstanceProxy<TablesProxy>(isolate, instance); - result->set(length++, *tables_str); - result->set(length++, *tables_obj); + result = ArrayList::Add( + isolate, result, + isolate->factory()->NewStringFromAsciiChecked("[[Tables]]"), + GetOrCreateInstanceProxy<TablesProxy>(isolate, instance)); } - return isolate->factory()->NewJSArrayWithElements(result, PACKED_ELEMENTS, - length); + return result; } -Handle<JSArray> GetWasmModuleObjectInternalProperties( +Handle<ArrayList> AddWasmModuleObjectInternalProperties( + Isolate* isolate, Handle<ArrayList> result, Handle<WasmModuleObject> module_object) { - Isolate* isolate = module_object->GetIsolate(); - Handle<FixedArray> result = isolate->factory()->NewFixedArray(2 * 2); - int length = 0; - - Handle<String> exports_str = - isolate->factory()->NewStringFromStaticChars("[[Exports]]"); - Handle<JSArray> exports_obj = wasm::GetExports(isolate, module_object); - result->set(length++, *exports_str); - result->set(length++, *exports_obj); - - Handle<String> imports_str = - isolate->factory()->NewStringFromStaticChars("[[Imports]]"); - Handle<JSArray> imports_obj = wasm::GetImports(isolate, module_object); - result->set(length++, *imports_str); - result->set(length++, *imports_obj); - - return isolate->factory()->NewJSArrayWithElements(result, PACKED_ELEMENTS, - length); + result = ArrayList::Add( + isolate, result, + isolate->factory()->NewStringFromStaticChars("[[Exports]]"), + wasm::GetExports(isolate, module_object)); + result = ArrayList::Add( + isolate, result, + isolate->factory()->NewStringFromStaticChars("[[Imports]]"), + wasm::GetImports(isolate, module_object)); + return result; } } // namespace internal diff --git a/deps/v8/src/debug/debug-wasm-objects.h b/deps/v8/src/debug/debug-wasm-objects.h index 6eb075b9b6..62e437b727 100644 --- a/deps/v8/src/debug/debug-wasm-objects.h +++ b/deps/v8/src/debug/debug-wasm-objects.h @@ -28,6 +28,7 @@ class WasmValue; #include "torque-generated/src/debug/debug-wasm-objects-tq.inc" +class ArrayList; class WasmFrame; class WasmInstanceObject; class WasmModuleObject; @@ -68,9 +69,15 @@ Handle<JSObject> GetWasmDebugProxy(WasmFrame* frame); std::unique_ptr<debug::ScopeIterator> GetWasmScopeIterator(WasmFrame* frame); -Handle<JSArray> GetWasmInstanceObjectInternalProperties( +Handle<String> GetWasmFunctionDebugName(Isolate* isolate, + Handle<WasmInstanceObject> instance, + uint32_t func_index); + +Handle<ArrayList> AddWasmInstanceObjectInternalProperties( + Isolate* isolate, Handle<ArrayList> result, Handle<WasmInstanceObject> instance); -Handle<JSArray> GetWasmModuleObjectInternalProperties( +Handle<ArrayList> AddWasmModuleObjectInternalProperties( + Isolate* isolate, Handle<ArrayList> result, Handle<WasmModuleObject> module_object); } // namespace internal diff --git a/deps/v8/src/debug/debug.cc b/deps/v8/src/debug/debug.cc index 0b873f7c8c..42b800ef75 100644 --- a/deps/v8/src/debug/debug.cc +++ b/deps/v8/src/debug/debug.cc @@ -352,7 +352,6 @@ void Debug::ThreadInit() { thread_local_.return_value_ = Smi::zero(); thread_local_.last_breakpoint_id_ = 0; clear_suspended_generator(); - thread_local_.restart_fp_ = kNullAddress; base::Relaxed_Store(&thread_local_.current_debug_scope_, static_cast<base::AtomicWord>(0)); thread_local_.break_on_next_function_call_ = false; @@ -439,9 +438,6 @@ void Debug::Unload() { } void Debug::Break(JavaScriptFrame* frame, Handle<JSFunction> break_target) { - // Initialize LiveEdit. - LiveEdit::InitializeThreadLocal(this); - // Just continue if breaks are disabled or debugger cannot be loaded. if (break_disabled()) return; @@ -1245,7 +1241,7 @@ class DiscardBaselineCodeVisitor : public ThreadVisitor { BaselineFrame* frame = BaselineFrame::cast(it.frame()); int bytecode_offset = frame->GetBytecodeOffset(); Address* pc_addr = frame->pc_address(); - Address advance = BUILTIN_CODE(isolate, InterpreterEnterBytecodeAdvance) + Address advance = BUILTIN_CODE(isolate, InterpreterEnterAtNextBytecode) ->InstructionStart(); PointerAuthentication::ReplacePC(pc_addr, advance, kSystemPointerSize); InterpretedFrame::cast(it.Reframe()) @@ -1264,8 +1260,8 @@ class DiscardBaselineCodeVisitor : public ThreadVisitor { Address* pc_addr = frame->pc_address(); Builtins::Name advance = builtin_index == Builtins::kBaselineEnterAtBytecode - ? Builtins::kInterpreterEnterBytecodeDispatch - : Builtins::kInterpreterEnterBytecodeAdvance; + ? Builtins::kInterpreterEnterAtBytecode + : Builtins::kInterpreterEnterAtNextBytecode; Address advance_pc = isolate->builtins()->builtin(advance).InstructionStart(); PointerAuthentication::ReplacePC(pc_addr, advance_pc, @@ -1353,7 +1349,8 @@ void Debug::PrepareFunctionForDebugExecution( DCHECK(shared->is_compiled()); DCHECK(shared->HasDebugInfo()); Handle<DebugInfo> debug_info = GetOrCreateDebugInfo(shared); - if (debug_info->flags() & DebugInfo::kPreparedForDebugExecution) return; + if (debug_info->flags(kRelaxedLoad) & DebugInfo::kPreparedForDebugExecution) + return; if (shared->HasBytecodeArray()) { SharedFunctionInfo::InstallDebugBytecode(shared, isolate_); @@ -1372,8 +1369,9 @@ void Debug::PrepareFunctionForDebugExecution( redirect_visitor.VisitThread(isolate_, isolate_->thread_local_top()); isolate_->thread_manager()->IterateArchivedThreads(&redirect_visitor); } - debug_info->set_flags(debug_info->flags() | - DebugInfo::kPreparedForDebugExecution); + debug_info->set_flags( + debug_info->flags(kRelaxedLoad) | DebugInfo::kPreparedForDebugExecution, + kRelaxedStore); } void Debug::InstallDebugBreakTrampoline() { @@ -1630,7 +1628,9 @@ bool Debug::FindSharedFunctionInfosIntersectingRange( } if (!triedTopLevelCompile && !candidateSubsumesRange && - script->shared_function_infos().length() > 0) { + script->shared_function_info_count() > 0) { + DCHECK_LE(script->shared_function_info_count(), + script->shared_function_infos().length()); MaybeObject maybeToplevel = script->shared_function_infos().Get(0); HeapObject heap_object; const bool topLevelInfoExists = @@ -1751,10 +1751,10 @@ void Debug::CreateBreakInfo(Handle<SharedFunctionInfo> shared) { Handle<FixedArray> break_points( factory->NewFixedArray(DebugInfo::kEstimatedNofBreakPointsInFunction)); - int flags = debug_info->flags(); + int flags = debug_info->flags(kRelaxedLoad); flags |= DebugInfo::kHasBreakInfo; if (CanBreakAtEntry(shared)) flags |= DebugInfo::kCanBreakAtEntry; - debug_info->set_flags(flags); + debug_info->set_flags(flags, kRelaxedStore); debug_info->set_break_points(*break_points); SharedFunctionInfo::EnsureSourcePositionsAvailable(isolate_, shared); @@ -1781,7 +1781,9 @@ void Debug::InstallCoverageInfo(Handle<SharedFunctionInfo> shared, DCHECK(!debug_info->HasCoverageInfo()); - debug_info->set_flags(debug_info->flags() | DebugInfo::kHasCoverageInfo); + debug_info->set_flags( + debug_info->flags(kRelaxedLoad) | DebugInfo::kHasCoverageInfo, + kRelaxedStore); debug_info->set_coverage_info(*coverage_info); } @@ -1871,27 +1873,6 @@ bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) { return location.IsReturn(); } -void Debug::ScheduleFrameRestart(StackFrame* frame) { - // Set a target FP for the FrameDropperTrampoline builtin to drop to once - // we return from the debugger. - DCHECK(frame->is_java_script()); - // Only reschedule to a frame further below a frame we already scheduled for. - if (frame->fp() <= thread_local_.restart_fp_) return; - // If the frame is optimized, trigger a deopt and jump into the - // FrameDropperTrampoline in the deoptimizer. - thread_local_.restart_fp_ = frame->fp(); - - // Reset break frame ID to the frame below the restarted frame. - StackTraceFrameIterator it(isolate_); - thread_local_.break_frame_id_ = StackFrameId::NO_ID; - for (StackTraceFrameIterator it(isolate_); !it.done(); it.Advance()) { - if (it.frame()->fp() > thread_local_.restart_fp_) { - thread_local_.break_frame_id_ = it.frame()->id(); - return; - } - } -} - Handle<FixedArray> Debug::GetLoadedScripts() { isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags, GarbageCollectionReason::kDebugger); @@ -2243,8 +2224,6 @@ void Debug::UpdateHookOnFunctionCall() { } void Debug::HandleDebugBreak(IgnoreBreakMode ignore_break_mode) { - // Initialize LiveEdit. - LiveEdit::InitializeThreadLocal(this); // Ignore debug break during bootstrapping. if (isolate_->bootstrapper()->IsActive()) return; // Just continue if breaks are disabled. @@ -2291,12 +2270,14 @@ void Debug::PrintBreakLocation() { StackTraceFrameIterator iterator(isolate_); if (iterator.done()) return; CommonFrame* frame = iterator.frame(); - FrameSummary summary = FrameSummary::GetTop(frame); - summary.EnsureSourcePositionsAvailable(); - int source_position = summary.SourcePosition(); - Handle<Object> script_obj = summary.script(); + std::vector<FrameSummary> frames; + frame->Summarize(&frames); + int inlined_frame_index = static_cast<int>(frames.size() - 1); + FrameInspector inspector(frame, inlined_frame_index, isolate_); + int source_position = inspector.GetSourcePosition(); + Handle<Object> script_obj = inspector.GetScript(); PrintF("[debug] break in function '"); - summary.FunctionName()->PrintOn(stdout); + inspector.GetFunctionName()->PrintOn(stdout); PrintF("'.\n"); if (script_obj->IsScript()) { Handle<Script> script = Handle<Script>::cast(script_obj); diff --git a/deps/v8/src/debug/debug.h b/deps/v8/src/debug/debug.h index 86c067c035..28c6942c42 100644 --- a/deps/v8/src/debug/debug.h +++ b/deps/v8/src/debug/debug.h @@ -311,9 +311,6 @@ class V8_EXPORT_PRIVATE Debug { // Check whether this frame is just about to return. bool IsBreakAtReturn(JavaScriptFrame* frame); - // Support for LiveEdit - void ScheduleFrameRestart(StackFrame* frame); - bool AllFramesOnStackAreBlackboxed(); // Set new script source, throw an exception if error occurred. When preview @@ -380,13 +377,6 @@ class V8_EXPORT_PRIVATE Debug { return reinterpret_cast<Address>(&thread_local_.suspended_generator_); } - Address restart_fp_address() { - return reinterpret_cast<Address>(&thread_local_.restart_fp_); - } - bool will_restart() const { - return thread_local_.restart_fp_ != kNullAddress; - } - StepAction last_step_action() { return thread_local_.last_step_action_; } bool break_on_next_function_call() const { return thread_local_.break_on_next_function_call_; @@ -548,9 +538,6 @@ class V8_EXPORT_PRIVATE Debug { // The suspended generator object to track when stepping. Object suspended_generator_; - // The new frame pointer to drop to when restarting a frame. - Address restart_fp_; - // Last used inspector breakpoint id. int last_breakpoint_id_; @@ -669,25 +656,6 @@ class SuppressDebug { bool old_state_; }; -// Code generator routines. -class DebugCodegen : public AllStatic { - public: - enum DebugBreakCallHelperMode { - SAVE_RESULT_REGISTER, - IGNORE_RESULT_REGISTER - }; - - // Builtin to drop frames to restart function. - static void GenerateFrameDropperTrampoline(MacroAssembler* masm); - - // Builtin to atomically (wrt deopts) handle debugger statement and - // drop frames to restart function if necessary. - static void GenerateHandleDebuggerStatement(MacroAssembler* masm); - - // Builtin to trigger a debug break before entering the function. - static void GenerateDebugBreakTrampoline(MacroAssembler* masm); -}; - } // namespace internal } // namespace v8 diff --git a/deps/v8/src/debug/ia32/debug-ia32.cc b/deps/v8/src/debug/ia32/debug-ia32.cc deleted file mode 100644 index 72d4ac37df..0000000000 --- a/deps/v8/src/debug/ia32/debug-ia32.cc +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#if V8_TARGET_ARCH_IA32 - -#include "src/debug/debug.h" - -#include "src/codegen/macro-assembler.h" -#include "src/debug/liveedit.h" -#include "src/execution/frames-inl.h" - -namespace v8 { -namespace internal { - -#define __ ACCESS_MASM(masm) - -void DebugCodegen::GenerateHandleDebuggerStatement(MacroAssembler* masm) { - { - FrameScope scope(masm, StackFrame::INTERNAL); - __ CallRuntime(Runtime::kHandleDebuggerStatement, 0); - } - __ MaybeDropFrames(); - - // Return to caller. - __ ret(0); -} - -void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) { - // Frame is being dropped: - // - Drop to the target frame specified by eax. - // - Look up current function on the frame. - // - Leave the frame. - // - Restart the frame by calling the function. - __ mov(ebp, eax); - __ mov(edi, Operand(ebp, StandardFrameConstants::kFunctionOffset)); - __ mov(eax, Operand(ebp, StandardFrameConstants::kArgCOffset)); - __ leave(); - - // The arguments are already in the stack (including any necessary padding), - // we should not try to massage the arguments again. - __ mov(ecx, Immediate(kDontAdaptArgumentsSentinel)); - __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); - __ InvokeFunctionCode(edi, no_reg, ecx, eax, JUMP_FUNCTION); -} - -const bool LiveEdit::kFrameDropperSupported = true; - -#undef __ - -} // namespace internal -} // namespace v8 - -#endif // V8_TARGET_ARCH_IA32 diff --git a/deps/v8/src/debug/liveedit.cc b/deps/v8/src/debug/liveedit.cc index 294f0e1f7b..a3065bb49f 100644 --- a/deps/v8/src/debug/liveedit.cc +++ b/deps/v8/src/debug/liveedit.cc @@ -66,31 +66,35 @@ class Differencer { public: explicit Differencer(Comparator::Input* input) : input_(input), len1_(input->GetLength1()), len2_(input->GetLength2()) { - buffer_ = NewArray<int>(len1_ * len2_); - } - ~Differencer() { - DeleteArray(buffer_); } void Initialize() { - int array_size = len1_ * len2_; - for (int i = 0; i < array_size; i++) { - buffer_[i] = kEmptyCellValue; - } } // Makes sure that result for the full problem is calculated and stored // in the table together with flags showing a path through subproblems. void FillTable() { - CompareUpToTail(0, 0); + // Determine common prefix to skip. + int minLen = std::min(len1_, len2_); + while (prefixLen_ < minLen && input_->Equals(prefixLen_, prefixLen_)) { + ++prefixLen_; + } + + // Pre-fill common suffix in the table. + for (int pos1 = len1_, pos2 = len2_; pos1 > prefixLen_ && + pos2 > prefixLen_ && + input_->Equals(--pos1, --pos2);) { + set_value4_and_dir(pos1, pos2, 0, EQ); + } + + CompareUpToTail(prefixLen_, prefixLen_); } void SaveResult(Comparator::Output* chunk_writer) { ResultWriter writer(chunk_writer); - int pos1 = 0; - int pos2 = 0; - while (true) { + if (prefixLen_) writer.eq(prefixLen_); + for (int pos1 = prefixLen_, pos2 = prefixLen_; true;) { if (pos1 < len1_) { if (pos2 < len2_) { Direction dir = get_direction(pos1, pos2); @@ -128,9 +132,10 @@ class Differencer { private: Comparator::Input* input_; - int* buffer_; + std::map<std::pair<int, int>, int> buffer_; int len1_; int len2_; + int prefixLen_ = 0; enum Direction { EQ = 0, @@ -144,51 +149,51 @@ class Differencer { // Computes result for a subtask and optionally caches it in the buffer table. // All results values are shifted to make space for flags in the lower bits. int CompareUpToTail(int pos1, int pos2) { - if (pos1 < len1_) { - if (pos2 < len2_) { - int cached_res = get_value4(pos1, pos2); - if (cached_res == kEmptyCellValue) { - Direction dir; - int res; - if (input_->Equals(pos1, pos2)) { - res = CompareUpToTail(pos1 + 1, pos2 + 1); - dir = EQ; - } else { - int res1 = CompareUpToTail(pos1 + 1, pos2) + - (1 << kDirectionSizeBits); - int res2 = CompareUpToTail(pos1, pos2 + 1) + - (1 << kDirectionSizeBits); - if (res1 == res2) { - res = res1; - dir = SKIP_ANY; - } else if (res1 < res2) { - res = res1; - dir = SKIP1; - } else { - res = res2; - dir = SKIP2; - } - } - set_value4_and_dir(pos1, pos2, res, dir); - cached_res = res; - } - return cached_res; + if (pos1 == len1_) { + return (len2_ - pos2) << kDirectionSizeBits; + } + if (pos2 == len2_) { + return (len1_ - pos1) << kDirectionSizeBits; + } + int res = get_value4(pos1, pos2); + if (res != kEmptyCellValue) { + return res; + } + Direction dir; + if (input_->Equals(pos1, pos2)) { + res = CompareUpToTail(pos1 + 1, pos2 + 1); + dir = EQ; + } else { + int res1 = CompareUpToTail(pos1 + 1, pos2) + (1 << kDirectionSizeBits); + int res2 = CompareUpToTail(pos1, pos2 + 1) + (1 << kDirectionSizeBits); + if (res1 == res2) { + res = res1; + dir = SKIP_ANY; + } else if (res1 < res2) { + res = res1; + dir = SKIP1; } else { - return (len1_ - pos1) << kDirectionSizeBits; + res = res2; + dir = SKIP2; } - } else { - return (len2_ - pos2) << kDirectionSizeBits; } + set_value4_and_dir(pos1, pos2, res, dir); + return res; } - inline int& get_cell(int i1, int i2) { - return buffer_[i1 + i2 * len1_]; + inline int get_cell(int i1, int i2) { + auto it = buffer_.find(std::make_pair(i1, i2)); + return it == buffer_.end() ? kEmptyCellValue : it->second; + } + + inline void set_cell(int i1, int i2, int value) { + buffer_.insert(std::make_pair(std::make_pair(i1, i2), value)); } // Each cell keeps a value plus direction. Value is multiplied by 4. void set_value4_and_dir(int i1, int i2, int value4, Direction dir) { DCHECK_EQ(0, value4 & kDirectionMask); - get_cell(i1, i2) = value4 | dir; + set_cell(i1, i2, value4 | dir); } int get_value4(int i1, int i2) { @@ -214,10 +219,10 @@ class Differencer { : chunk_writer_(chunk_writer), pos1_(0), pos2_(0), pos1_begin_(-1), pos2_begin_(-1), has_open_chunk_(false) { } - void eq() { + void eq(int len = 1) { FlushChunk(); - pos1_++; - pos2_++; + pos1_ += len; + pos2_ += len; } void skip1(int len1) { StartChunk(); @@ -782,10 +787,8 @@ bool ParseScript(Isolate* isolate, Handle<Script> script, ParseInfo* parse_info, } struct FunctionData { - FunctionData(FunctionLiteral* literal, bool should_restart) - : literal(literal), - stack_position(NOT_ON_STACK), - should_restart(should_restart) {} + explicit FunctionData(FunctionLiteral* literal) + : literal(literal), stack_position(NOT_ON_STACK) {} FunctionLiteral* literal; MaybeHandle<SharedFunctionInfo> shared; @@ -794,23 +797,14 @@ struct FunctionData { // In case of multiple functions with different stack position, the latest // one (in the order below) is used, since it is the most restrictive. // This is important only for functions to be restarted. - enum StackPosition { - NOT_ON_STACK, - ABOVE_BREAK_FRAME, - PATCHABLE, - BELOW_NON_DROPPABLE_FRAME, - ARCHIVED_THREAD, - }; + enum StackPosition { NOT_ON_STACK, ON_STACK }; StackPosition stack_position; - bool should_restart; }; class FunctionDataMap : public ThreadVisitor { public: - void AddInterestingLiteral(int script_id, FunctionLiteral* literal, - bool should_restart) { - map_.emplace(GetFuncId(script_id, literal), - FunctionData{literal, should_restart}); + void AddInterestingLiteral(int script_id, FunctionLiteral* literal) { + map_.emplace(GetFuncId(script_id, literal), FunctionData{literal}); } bool Lookup(SharedFunctionInfo sfi, FunctionData** data) { @@ -827,7 +821,7 @@ class FunctionDataMap : public ThreadVisitor { return Lookup(GetFuncId(script->id(), literal), data); } - void Fill(Isolate* isolate, Address* restart_frame_fp) { + void Fill(Isolate* isolate) { { HeapObjectIterator iterator(isolate->heap(), HeapObjectIterator::kFilterUnreachable); @@ -854,38 +848,11 @@ class FunctionDataMap : public ThreadVisitor { } } } - FunctionData::StackPosition stack_position = - isolate->debug()->break_frame_id() == StackFrameId::NO_ID - ? FunctionData::PATCHABLE - : FunctionData::ABOVE_BREAK_FRAME; - for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { - StackFrame* frame = it.frame(); - if (stack_position == FunctionData::ABOVE_BREAK_FRAME) { - if (frame->id() == isolate->debug()->break_frame_id()) { - stack_position = FunctionData::PATCHABLE; - } - } - if (stack_position == FunctionData::PATCHABLE && - (frame->is_exit() || frame->is_builtin_exit())) { - stack_position = FunctionData::BELOW_NON_DROPPABLE_FRAME; - continue; - } - if (!frame->is_java_script()) continue; - std::vector<Handle<SharedFunctionInfo>> sfis; - JavaScriptFrame::cast(frame)->GetFunctions(&sfis); - for (auto& sfi : sfis) { - if (stack_position == FunctionData::PATCHABLE && - IsResumableFunction(sfi->kind())) { - stack_position = FunctionData::BELOW_NON_DROPPABLE_FRAME; - } - FunctionData* data = nullptr; - if (!Lookup(*sfi, &data)) continue; - if (!data->should_restart) continue; - data->stack_position = stack_position; - *restart_frame_fp = frame->fp(); - } - } + // Visit the current thread stack. + VisitThread(isolate, isolate->thread_local_top()); + + // Visit the stacks of all archived threads. isolate->thread_manager()->IterateArchivedThreads(this); } @@ -932,7 +899,7 @@ class FunctionDataMap : public ThreadVisitor { for (auto& sfi : sfis) { FunctionData* data = nullptr; if (!Lookup(*sfi, &data)) continue; - data->stack_position = FunctionData::ARCHIVED_THREAD; + data->stack_position = FunctionData::ON_STACK; } } } @@ -940,11 +907,10 @@ class FunctionDataMap : public ThreadVisitor { std::map<FuncId, FunctionData> map_; }; -bool CanPatchScript( - const LiteralMap& changed, Handle<Script> script, Handle<Script> new_script, - FunctionDataMap& function_data_map, // NOLINT(runtime/references) - debug::LiveEditResult* result) { - debug::LiveEditResult::Status status = debug::LiveEditResult::OK; +bool CanPatchScript(const LiteralMap& changed, Handle<Script> script, + Handle<Script> new_script, + FunctionDataMap& function_data_map, + debug::LiveEditResult* result) { for (const auto& mapping : changed) { FunctionData* data = nullptr; function_data_map.Lookup(script, mapping.first, &data); @@ -953,55 +919,11 @@ bool CanPatchScript( Handle<SharedFunctionInfo> sfi; if (!data->shared.ToHandle(&sfi)) { continue; - } else if (!data->should_restart) { - UNREACHABLE(); - } else if (data->stack_position == FunctionData::ABOVE_BREAK_FRAME) { - status = debug::LiveEditResult::BLOCKED_BY_FUNCTION_ABOVE_BREAK_FRAME; - } else if (data->stack_position == - FunctionData::BELOW_NON_DROPPABLE_FRAME) { - status = - debug::LiveEditResult::BLOCKED_BY_FUNCTION_BELOW_NON_DROPPABLE_FRAME; - } else if (!data->running_generators.empty()) { - status = debug::LiveEditResult::BLOCKED_BY_RUNNING_GENERATOR; - } else if (data->stack_position == FunctionData::ARCHIVED_THREAD) { - status = debug::LiveEditResult::BLOCKED_BY_ACTIVE_FUNCTION; - } - if (status != debug::LiveEditResult::OK) { - result->status = status; + } else if (data->stack_position == FunctionData::ON_STACK) { + result->status = debug::LiveEditResult::BLOCKED_BY_ACTIVE_FUNCTION; return false; - } - } - return true; -} - -bool CanRestartFrame( - Isolate* isolate, Address fp, - FunctionDataMap& function_data_map, // NOLINT(runtime/references) - const LiteralMap& changed, debug::LiveEditResult* result) { - DCHECK_GT(fp, 0); - StackFrame* restart_frame = nullptr; - StackFrameIterator it(isolate); - for (; !it.done(); it.Advance()) { - if (it.frame()->fp() == fp) { - restart_frame = it.frame(); - break; - } - } - DCHECK(restart_frame && restart_frame->is_java_script()); - if (!LiveEdit::kFrameDropperSupported) { - result->status = debug::LiveEditResult::FRAME_RESTART_IS_NOT_SUPPORTED; - return false; - } - std::vector<Handle<SharedFunctionInfo>> sfis; - JavaScriptFrame::cast(restart_frame)->GetFunctions(&sfis); - for (auto& sfi : sfis) { - FunctionData* data = nullptr; - if (!function_data_map.Lookup(*sfi, &data)) continue; - auto new_literal_it = changed.find(data->literal); - if (new_literal_it == changed.end()) continue; - if (new_literal_it->second->scope()->new_target_var()) { - result->status = - debug::LiveEditResult::BLOCKED_BY_NEW_TARGET_IN_RESTART_FRAME; + } else if (!data->running_generators.empty()) { + result->status = debug::LiveEditResult::BLOCKED_BY_RUNNING_GENERATOR; return false; } } @@ -1092,24 +1014,17 @@ void LiveEdit::PatchScript(Isolate* isolate, Handle<Script> script, FunctionDataMap function_data_map; for (const auto& mapping : changed) { - function_data_map.AddInterestingLiteral(script->id(), mapping.first, true); - function_data_map.AddInterestingLiteral(new_script->id(), mapping.second, - false); + function_data_map.AddInterestingLiteral(script->id(), mapping.first); + function_data_map.AddInterestingLiteral(new_script->id(), mapping.second); } for (const auto& mapping : unchanged) { - function_data_map.AddInterestingLiteral(script->id(), mapping.first, false); + function_data_map.AddInterestingLiteral(script->id(), mapping.first); } - Address restart_frame_fp = 0; - function_data_map.Fill(isolate, &restart_frame_fp); + function_data_map.Fill(isolate); if (!CanPatchScript(changed, script, new_script, function_data_map, result)) { return; } - if (restart_frame_fp && - !CanRestartFrame(isolate, restart_frame_fp, function_data_map, changed, - result)) { - return; - } if (preview) { result->status = debug::LiveEditResult::OK; @@ -1273,16 +1188,6 @@ void LiveEdit::PatchScript(Isolate* isolate, Handle<Script> script, } #endif - if (restart_frame_fp) { - for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { - if (it.frame()->fp() == restart_frame_fp) { - isolate->debug()->ScheduleFrameRestart(it.frame()); - result->stack_changed = true; - break; - } - } - } - int script_id = script->id(); script->set_id(new_script->id()); new_script->set_id(script_id); @@ -1290,42 +1195,6 @@ void LiveEdit::PatchScript(Isolate* isolate, Handle<Script> script, result->script = ToApiHandle<v8::debug::Script>(new_script); } -void LiveEdit::InitializeThreadLocal(Debug* debug) { - debug->thread_local_.restart_fp_ = 0; -} - -bool LiveEdit::RestartFrame(JavaScriptFrame* frame) { - if (!LiveEdit::kFrameDropperSupported) return false; - Isolate* isolate = frame->isolate(); - StackFrameId break_frame_id = isolate->debug()->break_frame_id(); - bool break_frame_found = break_frame_id == StackFrameId::NO_ID; - for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { - StackFrame* current = it.frame(); - break_frame_found = break_frame_found || break_frame_id == current->id(); - if (current->fp() == frame->fp()) { - if (break_frame_found) { - isolate->debug()->ScheduleFrameRestart(current); - return true; - } else { - return false; - } - } - if (!break_frame_found) continue; - if (current->is_exit() || current->is_builtin_exit()) { - return false; - } - if (!current->is_java_script()) continue; - std::vector<Handle<SharedFunctionInfo>> shareds; - JavaScriptFrame::cast(current)->GetFunctions(&shareds); - for (auto& shared : shareds) { - if (IsResumableFunction(shared->kind())) { - return false; - } - } - } - return false; -} - void LiveEdit::CompareStrings(Isolate* isolate, Handle<String> s1, Handle<String> s2, std::vector<SourceChangeRange>* diffs) { diff --git a/deps/v8/src/debug/liveedit.h b/deps/v8/src/debug/liveedit.h index 4291efb2d0..5e06d3f2a3 100644 --- a/deps/v8/src/debug/liveedit.h +++ b/deps/v8/src/debug/liveedit.h @@ -56,11 +56,6 @@ struct SourceChangeRange { class V8_EXPORT_PRIVATE LiveEdit : AllStatic { public: - static void InitializeThreadLocal(Debug* debug); - - // Restarts the call frame and completely drops all frames above it. - static bool RestartFrame(JavaScriptFrame* frame); - static void CompareStrings(Isolate* isolate, Handle<String> a, Handle<String> b, std::vector<SourceChangeRange>* diffs); @@ -69,8 +64,6 @@ class V8_EXPORT_PRIVATE LiveEdit : AllStatic { static void PatchScript(Isolate* isolate, Handle<Script> script, Handle<String> source, bool preview, debug::LiveEditResult* result); - // Architecture-specific constant. - static const bool kFrameDropperSupported; }; } // namespace internal } // namespace v8 diff --git a/deps/v8/src/debug/mips/debug-mips.cc b/deps/v8/src/debug/mips/debug-mips.cc deleted file mode 100644 index d1ab6ec545..0000000000 --- a/deps/v8/src/debug/mips/debug-mips.cc +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#if V8_TARGET_ARCH_MIPS - -#include "src/debug/debug.h" - -#include "src/codegen/macro-assembler.h" -#include "src/debug/liveedit.h" -#include "src/execution/frames-inl.h" - -namespace v8 { -namespace internal { - -#define __ ACCESS_MASM(masm) - -void DebugCodegen::GenerateHandleDebuggerStatement(MacroAssembler* masm) { - { - FrameScope scope(masm, StackFrame::INTERNAL); - __ CallRuntime(Runtime::kHandleDebuggerStatement, 0); - } - __ MaybeDropFrames(); - - // Return to caller. - __ Ret(); -} - -void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) { - // Frame is being dropped: - // - Drop to the target frame specified by a1. - // - Look up current function on the frame. - // - Leave the frame. - // - Restart the frame by calling the function. - __ mov(fp, a1); - __ lw(a1, MemOperand(fp, StandardFrameConstants::kFunctionOffset)); - __ lw(a0, MemOperand(fp, StandardFrameConstants::kArgCOffset)); - - // Pop return address and frame. - __ LeaveFrame(StackFrame::INTERNAL); - - __ li(a2, Operand(kDontAdaptArgumentsSentinel)); - - __ InvokeFunction(a1, a2, a0, JUMP_FUNCTION); -} - - -const bool LiveEdit::kFrameDropperSupported = true; - -#undef __ - -} // namespace internal -} // namespace v8 - -#endif // V8_TARGET_ARCH_MIPS diff --git a/deps/v8/src/debug/mips64/debug-mips64.cc b/deps/v8/src/debug/mips64/debug-mips64.cc deleted file mode 100644 index 7b8e9e9744..0000000000 --- a/deps/v8/src/debug/mips64/debug-mips64.cc +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#if V8_TARGET_ARCH_MIPS64 - -#include "src/debug/debug.h" - -#include "src/codegen/macro-assembler.h" -#include "src/debug/liveedit.h" -#include "src/execution/frames-inl.h" - -namespace v8 { -namespace internal { - -#define __ ACCESS_MASM(masm) - -void DebugCodegen::GenerateHandleDebuggerStatement(MacroAssembler* masm) { - { - FrameScope scope(masm, StackFrame::INTERNAL); - __ CallRuntime(Runtime::kHandleDebuggerStatement, 0); - } - __ MaybeDropFrames(); - - // Return to caller. - __ Ret(); -} - -void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) { - // Frame is being dropped: - // - Drop to the target frame specified by a1. - // - Look up current function on the frame. - // - Leave the frame. - // - Restart the frame by calling the function. - __ mov(fp, a1); - __ Ld(a1, MemOperand(fp, StandardFrameConstants::kFunctionOffset)); - __ Ld(a0, MemOperand(fp, StandardFrameConstants::kArgCOffset)); - - // Pop return address and frame. - __ LeaveFrame(StackFrame::INTERNAL); - - __ li(a2, Operand(kDontAdaptArgumentsSentinel)); - - __ InvokeFunction(a1, a2, a0, JUMP_FUNCTION); -} - - -const bool LiveEdit::kFrameDropperSupported = true; - -#undef __ - -} // namespace internal -} // namespace v8 - -#endif // V8_TARGET_ARCH_MIPS64 diff --git a/deps/v8/src/debug/ppc/OWNERS b/deps/v8/src/debug/ppc/OWNERS deleted file mode 100644 index 02c2cd757c..0000000000 --- a/deps/v8/src/debug/ppc/OWNERS +++ /dev/null @@ -1,5 +0,0 @@ -junyan@redhat.com -joransiu@ca.ibm.com -midawson@redhat.com -mfarazma@redhat.com -vasili.skurydzin@ibm.com diff --git a/deps/v8/src/debug/ppc/debug-ppc.cc b/deps/v8/src/debug/ppc/debug-ppc.cc deleted file mode 100644 index c083708d3a..0000000000 --- a/deps/v8/src/debug/ppc/debug-ppc.cc +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2014 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#if V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64 - -#include "src/debug/debug.h" - -#include "src/codegen/macro-assembler.h" -#include "src/debug/liveedit.h" -#include "src/execution/frames-inl.h" - -namespace v8 { -namespace internal { - -#define __ ACCESS_MASM(masm) - -void DebugCodegen::GenerateHandleDebuggerStatement(MacroAssembler* masm) { - { - FrameScope scope(masm, StackFrame::INTERNAL); - __ CallRuntime(Runtime::kHandleDebuggerStatement, 0); - } - __ MaybeDropFrames(); - - // Return to caller. - __ Ret(); -} - -void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) { - // Frame is being dropped: - // - Drop to the target frame specified by r4. - // - Look up current function on the frame. - // - Leave the frame. - // - Restart the frame by calling the function. - - __ mr(fp, r4); - __ LoadP(r4, MemOperand(fp, StandardFrameConstants::kFunctionOffset)); - __ LoadP(r3, MemOperand(fp, StandardFrameConstants::kArgCOffset)); - __ LeaveFrame(StackFrame::INTERNAL); - - // The arguments are already in the stack (including any necessary padding), - // we should not try to massage the arguments again. - __ mov(r5, Operand(kDontAdaptArgumentsSentinel)); - __ InvokeFunction(r4, r5, r3, JUMP_FUNCTION); -} - -const bool LiveEdit::kFrameDropperSupported = true; - -#undef __ -} // namespace internal -} // namespace v8 - -#endif // V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64 diff --git a/deps/v8/src/debug/riscv64/debug-riscv64.cc b/deps/v8/src/debug/riscv64/debug-riscv64.cc deleted file mode 100644 index b292300150..0000000000 --- a/deps/v8/src/debug/riscv64/debug-riscv64.cc +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2021 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#if V8_TARGET_ARCH_RISCV64 - -#include "src/codegen/macro-assembler.h" -#include "src/debug/debug.h" -#include "src/debug/liveedit.h" -#include "src/execution/frames-inl.h" - -namespace v8 { -namespace internal { - -#define __ ACCESS_MASM(masm) - -void DebugCodegen::GenerateHandleDebuggerStatement(MacroAssembler* masm) { - { - FrameScope scope(masm, StackFrame::INTERNAL); - __ CallRuntime(Runtime::kHandleDebuggerStatement, 0); - } - __ MaybeDropFrames(); - - // Return to caller. - __ Ret(); -} - -void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) { - // Frame is being dropped: - // - Drop to the target frame specified by a1. - // - Look up current function on the frame. - // - Leave the frame. - // - Restart the frame by calling the function. - __ mv(fp, a1); - __ Ld(a1, MemOperand(fp, StandardFrameConstants::kFunctionOffset)); - - // Pop return address and frame. - __ LeaveFrame(StackFrame::INTERNAL); - - __ Ld(a0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); - __ Lhu(a0, - FieldMemOperand(a0, SharedFunctionInfo::kFormalParameterCountOffset)); - __ mv(a2, a0); - - __ InvokeFunction(a1, a2, a0, JUMP_FUNCTION); -} - -const bool LiveEdit::kFrameDropperSupported = true; - -#undef __ - -} // namespace internal -} // namespace v8 - -#endif // V8_TARGET_ARCH_RISCV64 diff --git a/deps/v8/src/debug/s390/debug-s390.cc b/deps/v8/src/debug/s390/debug-s390.cc deleted file mode 100644 index b58e70b851..0000000000 --- a/deps/v8/src/debug/s390/debug-s390.cc +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2015 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "src/init/v8.h" - -#if V8_TARGET_ARCH_S390 - -#include "src/debug/debug.h" - -#include "src/codegen/macro-assembler.h" -#include "src/debug/liveedit.h" -#include "src/execution/frames-inl.h" - -namespace v8 { -namespace internal { - -#define __ ACCESS_MASM(masm) - -void DebugCodegen::GenerateHandleDebuggerStatement(MacroAssembler* masm) { - { - FrameScope scope(masm, StackFrame::INTERNAL); - __ CallRuntime(Runtime::kHandleDebuggerStatement, 0); - } - __ MaybeDropFrames(); - - // Return to caller. - __ Ret(); -} - -void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) { - // Frame is being dropped: - // - Drop to the target frame specified by r3. - // - Look up current function on the frame. - // - Leave the frame. - // - Restart the frame by calling the function. - - __ mov(fp, r3); - __ LoadU64(r3, MemOperand(fp, StandardFrameConstants::kFunctionOffset)); - __ LoadU64(r2, MemOperand(fp, StandardFrameConstants::kArgCOffset)); - __ LeaveFrame(StackFrame::INTERNAL); - - // The arguments are already in the stack (including any necessary padding), - // we should not try to massage the arguments again. - __ mov(r4, Operand(kDontAdaptArgumentsSentinel)); - __ InvokeFunction(r3, r4, r2, JUMP_FUNCTION); -} - -const bool LiveEdit::kFrameDropperSupported = true; - -#undef __ -} // namespace internal -} // namespace v8 - -#endif // V8_TARGET_ARCH_S390 diff --git a/deps/v8/src/debug/x64/debug-x64.cc b/deps/v8/src/debug/x64/debug-x64.cc deleted file mode 100644 index 2209213831..0000000000 --- a/deps/v8/src/debug/x64/debug-x64.cc +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#if V8_TARGET_ARCH_X64 - -#include "src/debug/debug.h" - -#include "src/codegen/assembler.h" -#include "src/codegen/macro-assembler.h" -#include "src/debug/liveedit.h" -#include "src/execution/frames-inl.h" -#include "src/objects/objects-inl.h" - -namespace v8 { -namespace internal { - -#define __ ACCESS_MASM(masm) - -void DebugCodegen::GenerateHandleDebuggerStatement(MacroAssembler* masm) { - { - FrameScope scope(masm, StackFrame::INTERNAL); - __ CallRuntime(Runtime::kHandleDebuggerStatement, 0); - } - __ MaybeDropFrames(); - - // Return to caller. - __ ret(0); -} - -void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) { - // Frame is being dropped: - // - Drop to the target frame specified by rbx. - // - Look up current function on the frame. - // - Leave the frame. - // - Restart the frame by calling the function. - __ movq(rbp, rbx); - __ movq(rdi, Operand(rbp, StandardFrameConstants::kFunctionOffset)); - __ movq(rax, Operand(rbp, StandardFrameConstants::kArgCOffset)); - __ leave(); - - // The arguments are already in the stack (including any necessary padding), - // we should not try to massage the arguments again. - __ movq(rbx, Immediate(kDontAdaptArgumentsSentinel)); - __ InvokeFunction(rdi, no_reg, rbx, rax, JUMP_FUNCTION); -} - -const bool LiveEdit::kFrameDropperSupported = true; - -#undef __ - -} // namespace internal -} // namespace v8 - -#endif // V8_TARGET_ARCH_X64 |