27 frame_inspector_(frame_inspector),
28 function_(frame_inspector_->GetFunction()),
29 script_(frame_inspector_->GetScript()),
31 if (!IsContext(*frame_inspector->
GetContext())) {
37#
if V8_ENABLE_WEBASSEMBLY
55 if (debug_name->length() > 0)
return debug_name;
63 context_(function->context(), isolate),
65 if (!function->shared()->IsSubjectToDebugging()) {
66 context_ = Handle<Context>();
77 function_(generator->function(), isolate),
78 context_(generator->context(), isolate),
105class ScopeChainRetriever {
131 void RetrieveScopes() {
133 RetrieveClosureScope(
scope_);
144 bool RetrieveClosureScope(Scope* scope) {
150 if (break_scope_type_ == scope->scope_type() &&
151 break_scope_start_ == scope->start_position() &&
152 break_scope_end_ == scope->end_position()) {
157 for (Scope* inner_scope = scope->inner_scope(); inner_scope !=
nullptr;
158 inner_scope = inner_scope->sibling()) {
159 if (RetrieveClosureScope(inner_scope))
return true;
164 void RetrieveStartScope(Scope* scope) {
165 const int start = scope->start_position();
166 const int end = scope->end_position();
176 for (Scope* inner_scope = scope->inner_scope(); inner_scope !=
nullptr;
177 inner_scope = inner_scope->sibling()) {
178 RetrieveStartScope(inner_scope);
182 bool ContainsPosition(Scope* scope) {
183 const int start = scope->start_position();
184 const int end = scope->end_position();
188 const bool position_fits_end =
198 const bool position_fits_start =
199 scope->is_class_scope() || scope->is_with_scope() ?
start <=
position_
201 return position_fits_start && position_fits_end;
206MaybeDirectHandle<ScopeInfo> FindEvalScope(Isolate* isolate,
210 scope->HasOuterScopeInfo()) {
211 scope = scope->OuterScopeInfo();
215 ? MaybeHandle<ScopeInfo>(scope, isolate)
225 if (IsUndefined(shared_info->script(),
isolate_)) {
232 bool ignore_nested_scopes =
false;
245 ignore_nested_scopes = location.
IsReturn();
269 flags.set_is_reparse(
true);
272 if (flags.is_toplevel() &&
283 if (FindEvalScope(
isolate_, *scope_info).ToHandle(&eval_scope)) {
284 flags.set_outer_language_mode(eval_scope->language_mode());
285 if (eval_scope->HasOuterScopeInfo()) {
293 }
else if (scope_info->scope_type() ==
EVAL_SCOPE || script->is_wrapped()) {
294 flags.set_is_eval(
true);
300 flags.set_outer_language_mode(shared_info->language_mode());
302 DCHECK(script->origin_options().IsModule());
303 DCHECK(flags.is_module());
305 DCHECK(scope_info->is_script_scope() ||
312 std::make_unique<ReusableUnoptimizedCompileState>(
isolate_);
313 info_ = std::make_unique<ParseInfo>(
isolate_, flags, &compile_state,
316 const bool parse_result =
326 ScopeChainRetriever scope_chain_retriever(literal_scope,
function_,
334 ? scope_chain_retriever.ClosureScope()
337 if (ignore_nested_scopes) {
364 if (!
context_->IsDebugEvaluateContext())
return;
368 if (IsContext(wrapped)) {
371 DCHECK(!current->previous().is_null());
372 current = current->previous();
374 }
while (current->IsDebugEvaluateContext());
407 if (IsNativeContext(*
context_))
return 0;
408 return context_->closure_context()->scope_info()->StartPosition();
413 if (IsNativeContext(*
context_))
return 0;
414 return context_->closure_context()->scope_info()->EndPosition();
423 bool declares_local =
false;
426 declares_local =
true;
430 return declares_local;
453 return needs_context;
527 if (leaving_closure) {
551 context_->IsDebugEvaluateContext());
588 context_->IsDebugEvaluateContext()) {
623 if (IsOptimizedOut(*value,
isolate_)) {
627 }
else if (IsTheHole(*value,
isolate_)) {
628 const bool is_overriden_repl_let =
631 if (!is_overriden_repl_let) {
737void ScopeIterator::DebugPrint() {
782 Print(
context_->native_context()->script_context_table(), os);
825 int module_variable_count = scope_info->ModuleVariableCount();
829 for (
int i = 0;
i < module_variable_count; ++
i) {
834 scope_info->ModuleVariable(
i, &raw_name, &index);
853 int context_index = scope_info->ContextHeaderLength() + it->index();
855 if (
v8_flags.script_context_mutable_heap_number &&
856 context->IsScriptContext()) {
858 context, it->index(), value,
isolate_),
861 if (visitor(name, value, scope_type))
return true;
886 if (function_var !=
nullptr) {
891 if (visitor(name, function, scope_type))
return true;
904 int index = var->index();
906 switch (var->location()) {
921 DCHECK_LT(index, parameters_and_registers->length());
923 }
else if (var->IsReceiver()) {
938 function_->shared()->scope_info()->ParameterCount();
940 DCHECK_LT(index, parameters_and_registers->length());
944 if (IsOptimizedOut(*value,
isolate_)) {
965 DCHECK(var->IsContextSlot());
970 if (
v8_flags.script_context_mutable_heap_number &&
987 if (visitor(var->name(), value, scope_type))
return true;
996 if (!IsJSObject(
context_->extension_receiver())) {
1009 if (
VisitLocals(visitor, mode, scope_type))
return;
1048 if (!
context_->scope_info()->SloppyEvalCanExtendVars())
return;
1049 if (
context_->extension_object().is_null())
return;
1056 for (
int i = 0;
i < keys->
length();
i++) {
1058 DCHECK(IsString(keys->get(
i)));
1062 if (visitor(
key, value, scope_type))
return;
1073 int index = var->index();
1074 switch (var->location()) {
1087 if (var->is_this())
return false;
1093 DCHECK_LT(index, parameters_and_registers->length());
1094 parameters_and_registers->set(index, *new_value);
1109 function_->shared()->scope_info()->ParameterCount();
1113 DCHECK_LT(index, parameters_and_registers->length());
1114 parameters_and_registers->set(index, *new_value);
1125 DCHECK(var->IsContextSlot());
1131 if (
context_->scope_info()->ContextSlotIndex(variable_name) !=
1135 if ((
v8_flags.script_context_mutable_heap_number ||
1147 if (!var->IsExport())
return false;
1161 if (!
context_->has_extension())
return false;
1163 DCHECK(IsJSContextExtensionObject(
context_->extension_object()));
1168 if (!maybe.
FromJust())
return false;
1176 int slot_index =
context_->scope_info()->ContextSlotIndex(variable_name);
1177 if (slot_index < 0)
return false;
1178 context_->set(slot_index, *new_value);
1189 cell_index =
context_->scope_info()->ModuleIndex(
1190 *variable_name, &mode, &init_flag, &maybe_assigned_flag);
1208 if (script_contexts->Lookup(variable_name, &lookup_result)) {
1211 if (
v8_flags.script_context_mutable_heap_number ||
1216 script_context->set(lookup_result.
slot_index, *new_value);
1244class LocalBlocklistsCollector {
1249 void CollectAndStore();
1252 void InitializeWithClosureScope();
1253 void AdvanceToNextNonHiddenScope();
1254 void CollectCurrentLocalsIntoBlocklists();
1268LocalBlocklistsCollector::LocalBlocklistsCollector(
1270 DeclarationScope* closure_scope)
1277void LocalBlocklistsCollector::InitializeWithClosureScope() {
1283void LocalBlocklistsCollector::AdvanceToNextNonHiddenScope() {
1288 }
while (
scope_->is_hidden());
1291void LocalBlocklistsCollector::CollectCurrentLocalsIntoBlocklists() {
1292 for (Variable* var : *
scope_->locals()) {
1293 if (var->location() == VariableLocation::PARAMETER ||
1294 var->location() == VariableLocation::LOCAL) {
1300 pair.second = StringSet::Add(
isolate_, pair.second, var->name());
1306DirectHandle<ScopeInfo> LocalBlocklistsCollector::FindScopeInfoForScope(
1307 Scope* scope)
const {
1310 for (Tagged<SharedFunctionInfo> info = iterator.Next(); !info.is_null();
1311 info = iterator.Next()) {
1312 Tagged<ScopeInfo> scope_info = info->scope_info();
1313 if (info->is_compiled() && !scope_info.is_null() &&
1314 scope->start_position() == info->StartPosition() &&
1315 scope->end_position() == info->EndPosition() &&
1316 scope->scope_type() == scope_info->scope_type()) {
1320 return DirectHandle<ScopeInfo>();
1323void LocalBlocklistsCollector::StoreFunctionBlocklists(
1324 DirectHandle<ScopeInfo> outer_scope_info) {
1326 DirectHandle<ScopeInfo> scope_info = FindScopeInfoForScope(pair.first);
1331 if (scope_info.is_null())
continue;
1332 isolate_->LocalsBlockListCacheSet(scope_info, outer_scope_info,
1337void LocalBlocklistsCollector::CollectAndStore() {
1338 InitializeWithClosureScope();
1341 AdvanceToNextNonHiddenScope();
1343 CollectCurrentLocalsIntoBlocklists();
1348 if (
scope_->NeedsContext()) {
1366 }
else if (
scope_->is_function_scope()) {
1381void ScopeIterator::MaybeCollectAndStoreLocalBlocklists()
const {
1382 if (!calculate_blocklists_ || current_scope_ !=
closure_scope_ ||
1383 Type() == ScopeTypeScript) {
1391 collector.CollectAndStore();
V8_INLINE bool IsJust() const
V8_INLINE T FromJust() const &
static Handle< JSObject > FunctionGetArguments(JavaScriptFrame *frame, int inlined_jsframe_index)
static BreakLocation FromFrame(Handle< DebugInfo > debug_info, JavaScriptFrame *frame)
void SetExpression(int index, Tagged< Object > value)
static DirectHandle< Object > LoadScriptContextElement(DirectHandle< Context > script_context, int index, DirectHandle< Object > new_value, Isolate *isolate)
static void StoreScriptContextAndUpdateSlotProperty(DirectHandle< Context > script_context, int index, DirectHandle< Object > new_value, Isolate *isolate)
bool is_arrow_scope() const
Variable * function_var() const
Variable * arguments() const
bool has_this_declaration() const
Handle< FixedArray > NewFixedArray(int length, AllocationType allocation=AllocationType::kYoung)
Handle< JSObject > NewSlowJSObjectWithNullProto()
Handle< JSArray > NewJSArrayWithElements(DirectHandle< FixedArrayBase > elements, ElementsKind elements_kind, int length, AllocationType allocation=AllocationType::kYoung)
Handle< String > InternalizeString(base::Vector< const char > str, bool convert_encoding=false)
Handle< Object > GetParameter(int index)
int inlined_frame_index() const
Handle< JSFunction > GetFunction() const
Handle< Object > GetExpression(int index)
Handle< Script > GetScript()
Handle< Object > GetReceiver()
Handle< Object > GetContext()
V8_INLINE Address * location() const
v8::internal::Factory * factory()
Tagged< Object > LocalsBlockListCacheGet(DirectHandle< ScopeInfo > scope_info)
static DirectHandle< String > GetDebugName(DirectHandle< JSFunction > function)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > SetAccessor(DirectHandle< JSObject > object, DirectHandle< Name > name, DirectHandle< AccessorInfo > info, PropertyAttributes attributes)
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT Maybe< bool > HasOwnProperty(Isolate *isolate, DirectHandle< JSReceiver > object, DirectHandle< Name > name)
static Handle< Object > GetDataProperty(Isolate *isolate, DirectHandle< JSReceiver > object, DirectHandle< Name > name)
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT Maybe< bool > HasProperty(LookupIterator *it)
void SetParameterValue(int index, Tagged< Object > value) const
bool is_unoptimized() const
static MaybeHandle< FixedArray > GetKeys(Isolate *isolate, DirectHandle< JSReceiver > object, KeyCollectionMode mode, PropertyFilter filter, GetKeysConversion keys_conversion=GetKeysConversion::kKeepNumbers, bool is_for_in=false, bool skip_indices=false)
V8_INLINE bool is_null() const
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > SetPropertyOrElement(Isolate *isolate, DirectHandle< JSAny > object, DirectHandle< Name > name, DirectHandle< Object > value, Maybe< ShouldThrow > should_throw=Nothing< ShouldThrow >(), StoreOrigin store_origin=StoreOrigin::kMaybeKeyed)
static V8_WARN_UNUSED_RESULT Maybe< bool > SetDataProperty(LookupIterator *it, DirectHandle< Object > value)
static LocalNamesRange< DirectHandle< ScopeInfo > > IterateLocalNames(DirectHandle< ScopeInfo > scope_info)
static bool VariableIsSynthetic(Tagged< String > name)
bool DeclaresLocals(Mode mode) const
bool SetModuleVariableValue(DirectHandle< String > variable_name, DirectHandle< Object > new_value)
Handle< JSObject > ScopeObject(Mode mode)
static const int kScopeDetailsNameIndex
void CollectLocalsFromCurrentScope()
bool SetLocalVariableValue(DirectHandle< String > variable_name, DirectHandle< Object > new_value)
FrameInspector *const frame_inspector_
DirectHandle< JSObject > MaterializeScopeDetails()
bool SetVariableValue(Handle< String > variable_name, DirectHandle< Object > new_value)
void VisitLocalScope(const Visitor &visitor, Mode mode, ScopeType scope_type) const
DirectHandle< Object > GetFunctionDebugName() const
std::unique_ptr< ReusableUnoptimizedCompileState > reusable_compile_state_
JavaScriptFrame * GetFrame() const
void TryParseAndRetrieveScopes(ReparseStrategy strategy)
static const int kScopeDetailsTypeIndex
bool NeedsContext() const
bool SetScriptVariableValue(DirectHandle< String > variable_name, DirectHandle< Object > new_value)
static const int kScopeDetailsStartPositionIndex
Handle< StringSet > locals_
void VisitModuleScope(const Visitor &visitor) const
Handle< JSObject > WithContextExtension()
void MaybeCollectAndStoreLocalBlocklists() const
bool SetContextVariableValue(DirectHandle< String > variable_name, DirectHandle< Object > new_value)
bool VisitContextLocals(const Visitor &visitor, DirectHandle< ScopeInfo > scope_info, DirectHandle< Context > context, ScopeType scope_type) const
void VisitScriptScope(const Visitor &visitor) const
bool calculate_blocklists_
Handle< Context > context_
bool ClosureScopeHasThisReference() const
bool InInnerScope() const
bool VisitLocals(const Visitor &visitor, Mode mode, ScopeType scope_type) const
std::function< bool(Handle< String > name, Handle< Object > value, ScopeType scope_type)> Visitor
void UnwrapEvaluationContext()
static const int kScopeDetailsSize
ScopeIterator(Isolate *isolate, FrameInspector *frame_inspector, ReparseStrategy strategy)
bool SetContextExtensionValue(DirectHandle< String > variable_name, DirectHandle< Object > new_value)
std::unique_ptr< ParseInfo > info_
void VisitScope(const Visitor &visitor, Mode mode) const
DeclarationScope * closure_scope_
static const int kScopeDetailsFunctionIndex
Handle< JSFunction > function_
Handle< JSGeneratorObject > generator_
static const int kScopeDetailsObjectIndex
static const int kScopeDetailsEndPositionIndex
int GetSourcePosition() const
bool HasThisReference() const
Scope * outer_scope() const
DeclarationScope * AsDeclarationScope()
base::ThreadedList< Variable > * locals()
bool is_script_scope() const
bool is_function_scope() const
ScopeType scope_type() const
bool NeedsContext() const
int start_position() const
bool is_declaration_scope() const
static void EnsureSourcePositionsAvailable(Isolate *isolate, DirectHandle< SharedFunctionInfo > shared_info)
static constexpr Tagged< Smi > FromInt(int value)
static CellIndexKind GetCellIndexKind(int cell_index)
static void StoreVariable(DirectHandle< SourceTextModule > module, int cell_index, DirectHandle< Object > value)
static Handle< Object > LoadVariable(Isolate *isolate, DirectHandle< SourceTextModule > module, int cell_index)
static V8_EXPORT_PRIVATE Handle< StringSet > New(Isolate *isolate)
static V8_EXPORT_PRIVATE Handle< StringSet > Add(Isolate *isolate, Handle< StringSet > stringset, DirectHandle< String > name)
bool Equals(Tagged< String > other) const
static UnoptimizedCompileFlags ForFunctionCompile(Isolate *isolate, Tagged< SharedFunctionInfo > shared)
static UnoptimizedCompileFlags ForScriptCompile(Isolate *isolate, Tagged< Script > script)
Handle< String > name() const
const JSFunctionRef function_
const ScopeType break_scope_type_
std::map< Scope *, IndirectHandle< StringSet > > function_blocklists_
Handle< StringSet > context_blocklist_
DeclarationScope * scope_
Handle< Context > context_
DeclarationScope * closure_scope_
const int break_scope_start_
const int break_scope_end_
std::unique_ptr< icu::DateTimePatternGenerator > generator_
bool ParseFunction(ParseInfo *info, DirectHandle< SharedFunctionInfo > shared_info, Isolate *isolate, ReportStatisticsMode mode)
bool ParseProgram(ParseInfo *info, DirectHandle< Script > script, MaybeDirectHandle< ScopeInfo > maybe_outer_scope_info, Isolate *isolate, ReportStatisticsMode mode)
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
constexpr NullMaybeHandleType kNullMaybeHandle
PerThreadAssertScopeDebugOnly< false, SAFEPOINTS_ASSERT, HEAP_ALLOCATION_ASSERT > DisallowGarbageCollection
constexpr int kNoSourcePosition
bool IsLexicalVariableMode(VariableMode mode)
void PrintF(const char *format,...)
Tagged(T object) -> Tagged< T >
V8_INLINE IndirectHandle< T > indirect_handle(DirectHandle< T > handle)
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in name
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in allocation gc speed threshold for starting incremental marking via a task in percent of available threshold for starting incremental marking immediately in percent of available Use a single schedule for determining a marking schedule between JS and C objects schedules the minor GC task with kUserVisible priority max worker number of concurrent for NumberOfWorkerThreads start background threads that allocate memory concurrent_array_buffer_sweeping use parallel threads to clear weak refs in the atomic pause trace progress of the incremental marking trace object counts and memory usage report a tick only when allocated zone memory changes by this amount TracingFlags::gc_stats TracingFlags::gc_stats track native contexts that are expected to be garbage collected verify heap pointers before and after GC memory reducer runs GC with ReduceMemoryFootprint flag Maximum number of memory reducer GCs scheduled Old gen GC speed is computed directly from gc tracer counters Perform compaction on full GCs based on V8 s default heuristics Perform compaction on every full GC Perform code space compaction when finalizing a full GC with stack Stress GC compaction to flush out bugs with moving objects flush of baseline code when it has not been executed recently Use time base code flushing instead of age Use a progress bar to scan large objects in increments when incremental marking is active force incremental marking for small heaps and run it more often force marking at random points between and force scavenge at random points between and reclaim otherwise unreachable unmodified wrapper objects when possible less compaction in non memory reducing mode use high priority threads for concurrent Marking Test mode only flag It allows an unit test to select evacuation candidates use incremental marking for CppHeap cppheap_concurrent_marking c value for membalancer A special constant to balance between memory and space tradeoff The smaller the more memory it uses enable use of SSE4 instructions if available enable use of AVX VNNI instructions if available enable use of POPCNT instruction if available force all emitted branches to be in long mode(MIPS/PPC only)") DEFINE_BOOL(partial_constant_pool
void Print(Tagged< Object > obj)
V8_EXPORT_PRIVATE FlagValues v8_flags
V8_INLINE bool IsWasmObject(T obj, Isolate *=nullptr)
kInterpreterTrampolineOffset script
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
static constexpr AcquireLoadTag kAcquireLoad
Maybe< T > Just(const T &t)
std::vector< ValueType > locals_
#define CHECK_IMPLIES(lhs, rhs)
#define DCHECK_NOT_NULL(val)
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK_NE(v1, v2)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)