| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 2b9d3b2 commit 5890d09
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,7 +11,7 @@ | |||
| 11 | 11 | #define V8_MAJOR_VERSION 10 | |
| 12 | 12 | #define V8_MINOR_VERSION 9 | |
| 13 | 13 | #define V8_BUILD_NUMBER 194 | |
| 14 | - #define V8_PATCH_LEVEL 4 | ||
| 14 | + #define V8_PATCH_LEVEL 6 | ||
| 15 | 15 | ||
| 16 | 16 | // Use 1 for candidates and 0 otherwise. | |
| 17 | 17 | // (Boolean macro values are not supported by all preprocessors.) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -885,9 +885,8 @@ void DeclarationScope::AddLocal(Variable* var) { | |||
| 885 | 885 | } | |
| 886 | 886 | ||
| 887 | 887 | void Scope::Snapshot::Reparent(DeclarationScope* new_parent) { | |
| 888 | - DCHECK(!IsCleared()); | ||
| 889 | - DCHECK_EQ(new_parent, outer_scope_and_calls_eval_.GetPointer()->inner_scope_); | ||
| 890 | - DCHECK_EQ(new_parent->outer_scope_, outer_scope_and_calls_eval_.GetPointer()); | ||
| 888 | + DCHECK_EQ(new_parent, outer_scope_->inner_scope_); | ||
| 889 | + DCHECK_EQ(new_parent->outer_scope_, outer_scope_); | ||
| 891 | 890 | DCHECK_EQ(new_parent, new_parent->GetClosureScope()); | |
| 892 | 891 | DCHECK_NULL(new_parent->inner_scope_); | |
| 893 | 892 | DCHECK(new_parent->unresolved_list_.is_empty()); | |
@@ -912,12 +911,11 @@ void Scope::Snapshot::Reparent(DeclarationScope* new_parent) { | |||
| 912 | 911 | new_parent->sibling_ = top_inner_scope_; | |
| 913 | 912 | } | |
| 914 | 913 | ||
| 915 | - Scope* outer_scope = outer_scope_and_calls_eval_.GetPointer(); | ||
| 916 | - new_parent->unresolved_list_.MoveTail(&outer_scope->unresolved_list_, | ||
| 914 | + new_parent->unresolved_list_.MoveTail(&outer_scope_->unresolved_list_, | ||
| 917 | 915 | top_unresolved_); | |
| 918 | 916 | ||
| 919 | 917 | // Move temporaries allocated for complex parameter initializers. | |
| 920 | - DeclarationScope* outer_closure = outer_scope->GetClosureScope(); | ||
| 918 | + DeclarationScope* outer_closure = outer_scope_->GetClosureScope(); | ||
| 921 | 919 | for (auto it = top_local_; it != outer_closure->locals()->end(); ++it) { | |
| 922 | 920 | Variable* local = *it; | |
| 923 | 921 | DCHECK_EQ(VariableMode::kTemporary, local->mode()); | |
@@ -929,16 +927,10 @@ void Scope::Snapshot::Reparent(DeclarationScope* new_parent) { | |||
| 929 | 927 | outer_closure->locals_.Rewind(top_local_); | |
| 930 | 928 | ||
| 931 | 929 | // Move eval calls since Snapshot's creation into new_parent. | |
| 932 | - if (outer_scope_and_calls_eval_->calls_eval_) { | ||
| 933 | - new_parent->RecordDeclarationScopeEvalCall(); | ||
| 934 | - new_parent->inner_scope_calls_eval_ = true; | ||
| 930 | + if (outer_scope_->calls_eval_) { | ||
| 931 | + new_parent->RecordEvalCall(); | ||
| 932 | + declaration_scope_->sloppy_eval_can_extend_vars_ = false; | ||
| 935 | 933 | } | |
| 936 | - | ||
| 937 | - // We are in the arrow function case. The calls eval we may have recorded | ||
| 938 | - // is intended for the inner scope and we should simply restore the | ||
| 939 | - // original "calls eval" flag of the outer scope. | ||
| 940 | - RestoreEvalFlag(); | ||
| 941 | - Clear(); | ||
| 942 | 934 | } | |
| 943 | 935 | ||
| 944 | 936 | void Scope::ReplaceOuterScope(Scope* outer) { | |
@@ -2576,6 +2568,9 @@ void Scope::AllocateVariablesRecursively() { | |||
| 2576 | 2568 | this->ForEach([](Scope* scope) -> Iteration { | |
| 2577 | 2569 | DCHECK(!scope->already_resolved_); | |
| 2578 | 2570 | if (WasLazilyParsed(scope)) return Iteration::kContinue; | |
| 2571 | + if (scope->sloppy_eval_can_extend_vars_) { | ||
| 2572 | + scope->num_heap_slots_ = Context::MIN_CONTEXT_EXTENDED_SLOTS; | ||
| 2573 | + } | ||
| 2579 | 2574 | DCHECK_EQ(scope->ContextHeaderLength(), scope->num_heap_slots_); | |
| 2580 | 2575 | ||
| 2581 | 2576 | // Allocate variables for this scope. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -110,58 +110,38 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { | |||
| 110 | 110 | ||
| 111 | 111 | class Snapshot final { | |
| 112 | 112 | public: | |
| 113 | - Snapshot() | ||
| 114 | - : outer_scope_and_calls_eval_(nullptr, false), | ||
| 115 | - top_unresolved_(), | ||
| 116 | - top_local_() { | ||
| 117 | - DCHECK(IsCleared()); | ||
| 118 | - } | ||
| 119 | 113 | inline explicit Snapshot(Scope* scope); | |
| 120 | 114 | ||
| 121 | 115 | // Disallow copy and move. | |
| 122 | 116 | Snapshot(const Snapshot&) = delete; | |
| 123 | 117 | Snapshot(Snapshot&&) = delete; | |
| 124 | 118 | ||
| 125 | 119 | ~Snapshot() { | |
| 126 | - // If we're still active, there was no arrow function. In that case outer | ||
| 127 | - // calls eval if it already called eval before this snapshot started, or | ||
| 128 | - // if the code during the snapshot called eval. | ||
| 129 | - if (!IsCleared() && outer_scope_and_calls_eval_.GetPayload()) { | ||
| 130 | - RestoreEvalFlag(); | ||
| 120 | + // Restore eval flags from before the scope was active. | ||
| 121 | + if (sloppy_eval_can_extend_vars_) { | ||
| 122 | + declaration_scope_->sloppy_eval_can_extend_vars_ = true; | ||
| 131 | 123 | } | |
| 132 | - } | ||
| 133 | - | ||
| 134 | - void RestoreEvalFlag() { | ||
| 135 | - if (outer_scope_and_calls_eval_.GetPayload()) { | ||
| 136 | - // This recreates both calls_eval and sloppy_eval_can_extend_vars. | ||
| 137 | - outer_scope_and_calls_eval_.GetPointer()->RecordEvalCall(); | ||
| 124 | + if (calls_eval_) { | ||
| 125 | + outer_scope_->calls_eval_ = true; | ||
| 138 | 126 | } | |
| 139 | 127 | } | |
| 140 | 128 | ||
| 141 | 129 | void Reparent(DeclarationScope* new_parent); | |
| 142 | - bool IsCleared() const { | ||
| 143 | - return outer_scope_and_calls_eval_.GetPointer() == nullptr; | ||
| 144 | - } | ||
| 145 | - | ||
| 146 | - void Clear() { | ||
| 147 | - outer_scope_and_calls_eval_.SetPointer(nullptr); | ||
| 148 | - #ifdef DEBUG | ||
| 149 | - outer_scope_and_calls_eval_.SetPayload(false); | ||
| 150 | - top_inner_scope_ = nullptr; | ||
| 151 | - top_local_ = base::ThreadedList<Variable>::Iterator(); | ||
| 152 | - top_unresolved_ = UnresolvedList::Iterator(); | ||
| 153 | - #endif | ||
| 154 | - } | ||
| 155 | 130 | ||
| 156 | 131 | private: | |
| 157 | - // During tracking calls_eval caches whether the outer scope called eval. | ||
| 158 | - // Upon move assignment we store whether the new inner scope calls eval into | ||
| 159 | - // the move target calls_eval bit, and restore calls eval on the outer | ||
| 160 | - // scope. | ||
| 161 | - base::PointerWithPayload<Scope, bool, 1> outer_scope_and_calls_eval_; | ||
| 132 | + Scope* outer_scope_; | ||
| 133 | + Scope* declaration_scope_; | ||
| 162 | 134 | Scope* top_inner_scope_; | |
| 163 | 135 | UnresolvedList::Iterator top_unresolved_; | |
| 164 | 136 | base::ThreadedList<Variable>::Iterator top_local_; | |
| 137 | + // While the scope is active, the scope caches the flag values for | ||
| 138 | + // outer_scope_ / declaration_scope_ they can be used to know what happened | ||
| 139 | + // while parsing the arrow head. If this turns out to be an arrow head, new | ||
| 140 | + // values on the respective scopes will be cleared and moved to the inner | ||
| 141 | + // scope. Otherwise the cached flags will be merged with the flags from the | ||
| 142 | + // arrow head. | ||
| 143 | + bool calls_eval_; | ||
| 144 | + bool sloppy_eval_can_extend_vars_; | ||
| 165 | 145 | }; | |
| 166 | 146 | ||
| 167 | 147 | enum class DeserializationMode { kIncludingVariables, kScopesOnly }; | |
@@ -907,8 +887,8 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope { | |||
| 907 | 887 | void RecordDeclarationScopeEvalCall() { | |
| 908 | 888 | calls_eval_ = true; | |
| 909 | 889 | ||
| 910 | - // If this isn't a sloppy eval, we don't care about it. | ||
| 911 | - if (language_mode() != LanguageMode::kSloppy) return; | ||
| 890 | + // The caller already checked whether we're in sloppy mode. | ||
| 891 | + CHECK(is_sloppy(language_mode())); | ||
| 912 | 892 | ||
| 913 | 893 | // Sloppy eval in script scopes can only introduce global variables anyway, | |
| 914 | 894 | // so we don't care that it calls sloppy eval. | |
@@ -942,7 +922,6 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope { | |||
| 942 | 922 | } | |
| 943 | 923 | ||
| 944 | 924 | sloppy_eval_can_extend_vars_ = true; | |
| 945 | - num_heap_slots_ = Context::MIN_CONTEXT_EXTENDED_SLOTS; | ||
| 946 | 925 | } | |
| 947 | 926 | ||
| 948 | 927 | bool sloppy_eval_can_extend_vars() const { | |
@@ -1367,7 +1346,9 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope { | |||
| 1367 | 1346 | ||
| 1368 | 1347 | void Scope::RecordEvalCall() { | |
| 1369 | 1348 | calls_eval_ = true; | |
| 1370 | - GetDeclarationScope()->RecordDeclarationScopeEvalCall(); | ||
| 1349 | + if (is_sloppy(language_mode())) { | ||
| 1350 | + GetDeclarationScope()->RecordDeclarationScopeEvalCall(); | ||
| 1351 | + } | ||
| 1371 | 1352 | RecordInnerScopeEvalCall(); | |
| 1372 | 1353 | // The eval contents might access "super" (if it's inside a function that | |
| 1373 | 1354 | // binds super). | |
@@ -1380,14 +1361,18 @@ void Scope::RecordEvalCall() { | |||
| 1380 | 1361 | } | |
| 1381 | 1362 | ||
| 1382 | 1363 | Scope::Snapshot::Snapshot(Scope* scope) | |
| 1383 | - : outer_scope_and_calls_eval_(scope, scope->calls_eval_), | ||
| 1364 | + : outer_scope_(scope), | ||
| 1365 | + declaration_scope_(scope->GetDeclarationScope()), | ||
| 1384 | 1366 | top_inner_scope_(scope->inner_scope_), | |
| 1385 | 1367 | top_unresolved_(scope->unresolved_list_.end()), | |
| 1386 | - top_local_(scope->GetClosureScope()->locals_.end()) { | ||
| 1387 | - // Reset in order to record eval calls during this Snapshot's lifetime. | ||
| 1388 | - outer_scope_and_calls_eval_.GetPointer()->calls_eval_ = false; | ||
| 1389 | - outer_scope_and_calls_eval_.GetPointer()->sloppy_eval_can_extend_vars_ = | ||
| 1390 | - false; | ||
| 1368 | + top_local_(scope->GetClosureScope()->locals_.end()), | ||
| 1369 | + calls_eval_(outer_scope_->calls_eval_), | ||
| 1370 | + sloppy_eval_can_extend_vars_( | ||
| 1371 | + declaration_scope_->sloppy_eval_can_extend_vars_) { | ||
| 1372 | + // Reset in order to record (sloppy) eval calls during this Snapshot's | ||
| 1373 | + // lifetime. | ||
| 1374 | + outer_scope_->calls_eval_ = false; | ||
| 1375 | + declaration_scope_->sloppy_eval_can_extend_vars_ = false; | ||
| 1391 | 1376 | } | |
| 1392 | 1377 | ||
| 1393 | 1378 | class ModuleScope final : public DeclarationScope { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -6,6 +6,7 @@ | |||
| 6 | 6 | #define V8_SANDBOX_EXTERNAL_POINTER_TABLE_INL_H_ | |
| 7 | 7 | ||
| 8 | 8 | #include "src/base/atomicops.h" | |
| 9 | + #include "src/common/assert-scope.h" | ||
| 9 | 10 | #include "src/sandbox/external-pointer-table.h" | |
| 10 | 11 | #include "src/sandbox/external-pointer.h" | |
| 11 | 12 | #include "src/utils/allocation.h" | |
@@ -75,6 +76,13 @@ ExternalPointerHandle ExternalPointerTable::AllocateAndInitializeEntry( | |||
| 75 | 76 | Isolate* isolate, Address initial_value, ExternalPointerTag tag) { | |
| 76 | 77 | DCHECK(is_initialized()); | |
| 77 | 78 | ||
| 79 | + // We currently don't want entry allocation to trigger garbage collection as | ||
| 80 | + // this may cause seemingly harmless pointer field assignments to trigger | ||
| 81 | + // garbage collection. This is especially true for lazily-initialized | ||
| 82 | + // external pointer slots which will typically only allocate the external | ||
| 83 | + // pointer table entry when the pointer is first set to a non-null value. | ||
| 84 | + DisallowGarbageCollection no_gc; | ||
| 85 | + | ||
| 78 | 86 | Freelist freelist; | |
| 79 | 87 | bool success = false; | |
| 80 | 88 | while (!success) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -315,18 +315,6 @@ ExternalPointerTable::Freelist ExternalPointerTable::Grow(Isolate* isolate) { | |||
| 315 | 315 | ||
| 316 | 316 | set_capacity(new_capacity); | |
| 317 | 317 | ||
| 318 | - // Schedule GC when the table's utilization crosses one of these thresholds. | ||
| 319 | - constexpr double kGCThresholds[] = {0.5, 0.75, 0.9, 0.95, 0.99}; | ||
| 320 | - constexpr double kMaxCapacity = static_cast<double>(kMaxExternalPointers); | ||
| 321 | - double old_utilization = static_cast<double>(old_capacity) / kMaxCapacity; | ||
| 322 | - double new_utilization = static_cast<double>(new_capacity) / kMaxCapacity; | ||
| 323 | - for (double threshold : kGCThresholds) { | ||
| 324 | - if (old_utilization < threshold && new_utilization >= threshold) { | ||
| 325 | - isolate->heap()->ReportExternalMemoryPressure(); | ||
| 326 | - break; | ||
| 327 | - } | ||
| 328 | - } | ||
| 329 | - | ||
| 330 | 318 | // Build freelist bottom to top, which might be more cache friendly. | |
| 331 | 319 | uint32_t start = std::max<uint32_t>(old_capacity, 1); // Skip entry zero | |
| 332 | 320 | uint32_t last = new_capacity - 1; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments