diff options
Diffstat (limited to 'chromium/v8/src')
-rw-r--r-- | chromium/v8/src/builtins/builtins-date.cc | 2 | ||||
-rw-r--r-- | chromium/v8/src/builtins/builtins-regexp-gen.cc | 24 | ||||
-rw-r--r-- | chromium/v8/src/compiler/js-call-reducer.cc | 17 | ||||
-rw-r--r-- | chromium/v8/src/compiler/representation-change.cc | 22 | ||||
-rw-r--r-- | chromium/v8/src/compiler/representation-change.h | 2 | ||||
-rw-r--r-- | chromium/v8/src/flag-definitions.h | 8 | ||||
-rw-r--r-- | chromium/v8/src/heap/array-buffer-tracker-inl.h | 12 | ||||
-rw-r--r-- | chromium/v8/src/heap/array-buffer-tracker.cc | 14 | ||||
-rw-r--r-- | chromium/v8/src/heap/array-buffer-tracker.h | 9 | ||||
-rw-r--r-- | chromium/v8/src/inspector/wasm-translation.cc | 8 | ||||
-rw-r--r-- | chromium/v8/src/intl.cc | 14 | ||||
-rw-r--r-- | chromium/v8/src/intl.h | 7 | ||||
-rw-r--r-- | chromium/v8/src/isolate.cc | 82 | ||||
-rw-r--r-- | chromium/v8/src/isolate.h | 27 | ||||
-rw-r--r-- | chromium/v8/src/objects.cc | 2 | ||||
-rw-r--r-- | chromium/v8/src/objects/js-array.h | 4 | ||||
-rw-r--r-- | chromium/v8/src/v8.cc | 1 | ||||
-rw-r--r-- | chromium/v8/src/wasm/wasm-memory.cc | 2 |
18 files changed, 136 insertions, 121 deletions
diff --git a/chromium/v8/src/builtins/builtins-date.cc b/chromium/v8/src/builtins/builtins-date.cc index c60275d94ea..73c7098c06b 100644 --- a/chromium/v8/src/builtins/builtins-date.cc +++ b/chromium/v8/src/builtins/builtins-date.cc @@ -166,11 +166,13 @@ void ToDateString(double time_val, Vector<char> str, DateCache* date_cache, kShortMonths[month], day, year); return; case kTimeOnly: + // TODO(842085): str may be silently truncated. SNPrintF(str, "%02d:%02d:%02d GMT%c%02d%02d (%s)", hour, min, sec, (timezone_offset < 0) ? '-' : '+', timezone_hour, timezone_min, local_timezone); return; case kDateAndTime: + // TODO(842085): str may be silently truncated. SNPrintF(str, "%s %s %02d %04d %02d:%02d:%02d GMT%c%02d%02d (%s)", kShortWeekDays[weekday], kShortMonths[month], day, year, hour, min, sec, (timezone_offset < 0) ? '-' : '+', timezone_hour, diff --git a/chromium/v8/src/builtins/builtins-regexp-gen.cc b/chromium/v8/src/builtins/builtins-regexp-gen.cc index 392c60d90e6..2cc354cb945 100644 --- a/chromium/v8/src/builtins/builtins-regexp-gen.cc +++ b/chromium/v8/src/builtins/builtins-regexp-gen.cc @@ -1866,27 +1866,9 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context, Branch(IsNull(result), &if_didnotmatch, &load_match); BIND(&load_match); - { - Label fast_result(this), slow_result(this); - BranchIfFastRegExpResult(context, result, &fast_result, &slow_result); - - BIND(&fast_result); - { - Node* const result_fixed_array = LoadElements(result); - Node* const match = LoadFixedArrayElement(result_fixed_array, 0); - - var_match.Bind(ToString_Inline(context, match)); - Goto(&if_didmatch); - } - - BIND(&slow_result); - { - // TODO(ishell): Use GetElement stub once it's available. - Node* const match = GetProperty(context, result, smi_zero); - var_match.Bind(ToString_Inline(context, match)); - Goto(&if_didmatch); - } - } + Node* const match = GetProperty(context, result, smi_zero); + var_match.Bind(ToString_Inline(context, match)); + Goto(&if_didmatch); } BIND(&if_didnotmatch); diff --git a/chromium/v8/src/compiler/js-call-reducer.cc b/chromium/v8/src/compiler/js-call-reducer.cc index 8a50aa20f6d..451ec80a8d4 100644 --- a/chromium/v8/src/compiler/js-call-reducer.cc +++ b/chromium/v8/src/compiler/js-call-reducer.cc @@ -2506,6 +2506,7 @@ Reduction JSCallReducer::ReduceArrayIndexOfIncludes( if (!NodeProperties::GetMapWitness(node).ToHandle(&receiver_map)) return NoChange(); + if (receiver_map->instance_type() != JS_ARRAY_TYPE) return NoChange(); if (!IsFastElementsKind(receiver_map->elements_kind())) return NoChange(); Callable const callable = @@ -2535,8 +2536,20 @@ Reduction JSCallReducer::ReduceArrayIndexOfIncludes( Node* new_from_index = jsgraph()->ZeroConstant(); if (node->op()->ValueInputCount() >= 4) { Node* from_index = NodeProperties::GetValueInput(node, 3); - new_from_index = effect = graph()->NewNode( - simplified()->CheckSmi(p.feedback()), from_index, effect, control); + from_index = effect = graph()->NewNode(simplified()->CheckSmi(p.feedback()), + from_index, effect, control); + // If the index is negative, it means the offset from the end and therefore + // needs to be added to the length. If the result is still negative, it + // needs to be clamped to 0. + new_from_index = graph()->NewNode( + common()->Select(MachineRepresentation::kTagged, BranchHint::kFalse), + graph()->NewNode(simplified()->NumberLessThan(), from_index, + jsgraph()->ZeroConstant()), + graph()->NewNode( + simplified()->NumberMax(), + graph()->NewNode(simplified()->NumberAdd(), length, from_index), + jsgraph()->ZeroConstant()), + from_index); } Node* context = NodeProperties::GetContextInput(node); diff --git a/chromium/v8/src/compiler/representation-change.cc b/chromium/v8/src/compiler/representation-change.cc index 71aa1433711..34b532a6c6c 100644 --- a/chromium/v8/src/compiler/representation-change.cc +++ b/chromium/v8/src/compiler/representation-change.cc @@ -608,6 +608,16 @@ Node* RepresentationChanger::MakeTruncatedInt32Constant(double value) { return jsgraph()->Int32Constant(DoubleToInt32(value)); } +void RepresentationChanger::InsertUnconditionalDeopt(Node* node, + DeoptimizeReason reason) { + Node* effect = NodeProperties::GetEffectInput(node); + Node* control = NodeProperties::GetControlInput(node); + Node* deopt = + jsgraph()->graph()->NewNode(simplified()->CheckIf(reason), + jsgraph()->Int32Constant(0), effect, control); + NodeProperties::ReplaceEffectInput(node, deopt); +} + Node* RepresentationChanger::GetWord32RepresentationFor( Node* node, MachineRepresentation output_rep, Type* output_type, Node* use_node, UseInfo use_info) { @@ -639,7 +649,17 @@ Node* RepresentationChanger::GetWord32RepresentationFor( return jsgraph()->graph()->NewNode( jsgraph()->common()->DeadValue(MachineRepresentation::kWord32), node); } else if (output_rep == MachineRepresentation::kBit) { - return node; // Sloppy comparison -> word32 + CHECK(output_type->Is(Type::Boolean())); + if (use_info.truncation().IsUsedAsWord32()) { + return node; + } else { + CHECK(Truncation::Any(kIdentifyZeros) + .IsLessGeneralThan(use_info.truncation())); + CHECK_NE(use_info.type_check(), TypeCheckKind::kNone); + InsertUnconditionalDeopt(use_node, DeoptimizeReason::kNotASmi); + return jsgraph()->graph()->NewNode( + jsgraph()->common()->DeadValue(MachineRepresentation::kWord32), node); + } } else if (output_rep == MachineRepresentation::kFloat64) { if (output_type->Is(Type::Signed32())) { op = machine()->ChangeFloat64ToInt32(); diff --git a/chromium/v8/src/compiler/representation-change.h b/chromium/v8/src/compiler/representation-change.h index 571f13cd7dc..ed6c0a596e9 100644 --- a/chromium/v8/src/compiler/representation-change.h +++ b/chromium/v8/src/compiler/representation-change.h @@ -337,8 +337,8 @@ class RepresentationChanger final { Node* InsertChangeTaggedSignedToInt32(Node* node); Node* InsertChangeTaggedToFloat64(Node* node); Node* InsertChangeUint32ToFloat64(Node* node); - Node* InsertConversion(Node* node, const Operator* op, Node* use_node); + void InsertUnconditionalDeopt(Node* node, DeoptimizeReason reason); JSGraph* jsgraph() const { return jsgraph_; } Isolate* isolate() const { return isolate_; } diff --git a/chromium/v8/src/flag-definitions.h b/chromium/v8/src/flag-definitions.h index 7c12b8ba72e..311620ebc5f 100644 --- a/chromium/v8/src/flag-definitions.h +++ b/chromium/v8/src/flag-definitions.h @@ -681,7 +681,13 @@ DEFINE_BOOL(incremental_marking_wrappers, true, DEFINE_BOOL(trace_unmapper, false, "Trace the unmapping") DEFINE_BOOL(parallel_scavenge, true, "parallel scavenge") DEFINE_BOOL(trace_parallel_scavenge, false, "trace parallel scavenge") -DEFINE_BOOL(write_protect_code_memory, true, "write protect code memory") +#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_ARM64) +#define V8_WRITE_PROTECT_CODE_MEMORY_BOOL false +#else +#define V8_WRITE_PROTECT_CODE_MEMORY_BOOL true +#endif +DEFINE_BOOL(write_protect_code_memory, V8_WRITE_PROTECT_CODE_MEMORY_BOOL, + "write protect code memory") #ifdef V8_CONCURRENT_MARKING #define V8_CONCURRENT_MARKING_BOOL true #else diff --git a/chromium/v8/src/heap/array-buffer-tracker-inl.h b/chromium/v8/src/heap/array-buffer-tracker-inl.h index 3ab5aefaaf6..8ed4a66664b 100644 --- a/chromium/v8/src/heap/array-buffer-tracker-inl.h +++ b/chromium/v8/src/heap/array-buffer-tracker-inl.h @@ -51,12 +51,15 @@ void ArrayBufferTracker::Unregister(Heap* heap, JSArrayBuffer* buffer) { template <typename Callback> void LocalArrayBufferTracker::Free(Callback should_free) { size_t new_retained_size = 0; + Isolate* isolate = heap_->isolate(); for (TrackingData::iterator it = array_buffers_.begin(); it != array_buffers_.end();) { - JSArrayBuffer* buffer = reinterpret_cast<JSArrayBuffer*>(*it); - const size_t length = buffer->byte_length()->Number(); + JSArrayBuffer* buffer = reinterpret_cast<JSArrayBuffer*>(it->first); + const size_t length = it->second; if (should_free(buffer)) { - buffer->FreeBackingStore(); + JSArrayBuffer::FreeBackingStore( + isolate, {buffer->backing_store(), length, buffer->backing_store(), + buffer->allocation_mode(), buffer->is_wasm_memory()}); it = array_buffers_.erase(it); } else { new_retained_size += length; @@ -87,7 +90,7 @@ void ArrayBufferTracker::FreeDead(Page* page, MarkingState* marking_state) { void LocalArrayBufferTracker::Add(JSArrayBuffer* buffer, size_t length) { DCHECK_GE(retained_size_ + length, retained_size_); retained_size_ += length; - auto ret = array_buffers_.insert(buffer); + auto ret = array_buffers_.insert({buffer, length}); USE(ret); // Check that we indeed inserted a new value and did not overwrite an existing // one (which would be a bug). @@ -100,6 +103,7 @@ void LocalArrayBufferTracker::Remove(JSArrayBuffer* buffer, size_t length) { TrackingData::iterator it = array_buffers_.find(buffer); // Check that we indeed find a key to remove. DCHECK(it != array_buffers_.end()); + DCHECK_EQ(length, it->second); array_buffers_.erase(it); } diff --git a/chromium/v8/src/heap/array-buffer-tracker.cc b/chromium/v8/src/heap/array-buffer-tracker.cc index 1b870491ac2..589756fdc37 100644 --- a/chromium/v8/src/heap/array-buffer-tracker.cc +++ b/chromium/v8/src/heap/array-buffer-tracker.cc @@ -29,7 +29,7 @@ void LocalArrayBufferTracker::Process(Callback callback) { size_t moved_size = 0; for (TrackingData::iterator it = array_buffers_.begin(); it != array_buffers_.end();) { - old_buffer = reinterpret_cast<JSArrayBuffer*>(*it); + old_buffer = reinterpret_cast<JSArrayBuffer*>(it->first); const CallbackResult result = callback(old_buffer, &new_buffer); if (result == kKeepEntry) { new_retained_size += NumberToSize(old_buffer->byte_length()); @@ -51,14 +51,12 @@ void LocalArrayBufferTracker::Process(Callback callback) { } it = array_buffers_.erase(it); } else if (result == kRemoveEntry) { - // Size of freed memory is computed to avoid looking at dead objects. - void* allocation_base = old_buffer->allocation_base(); - DCHECK_NOT_NULL(allocation_base); - + // We pass backing_store() and stored length to the collector for freeing + // the backing store. Wasm allocations will go through their own tracker + // based on the backing store. backing_stores_to_free->emplace_back( - allocation_base, old_buffer->allocation_length(), - old_buffer->backing_store(), old_buffer->allocation_mode(), - old_buffer->is_wasm_memory()); + old_buffer->backing_store(), it->second, old_buffer->backing_store(), + old_buffer->allocation_mode(), old_buffer->is_wasm_memory()); it = array_buffers_.erase(it); } else { UNREACHABLE(); diff --git a/chromium/v8/src/heap/array-buffer-tracker.h b/chromium/v8/src/heap/array-buffer-tracker.h index 6bf4f79261b..c9c1a5b645e 100644 --- a/chromium/v8/src/heap/array-buffer-tracker.h +++ b/chromium/v8/src/heap/array-buffer-tracker.h @@ -5,7 +5,7 @@ #ifndef V8_HEAP_ARRAY_BUFFER_TRACKER_H_ #define V8_HEAP_ARRAY_BUFFER_TRACKER_H_ -#include <unordered_set> +#include <unordered_map> #include "src/allocation.h" #include "src/base/platform/mutex.h" @@ -111,7 +111,12 @@ class LocalArrayBufferTracker { } }; - typedef std::unordered_set<JSArrayBuffer*, Hasher> TrackingData; + // Keep track of the backing store and the corresponding length at time of + // registering. The length is accessed from JavaScript and can be a + // HeapNumber. The reason for tracking the length is that in the case of + // length being a HeapNumber, the buffer and its length may be stored on + // different memory pages, making it impossible to guarantee order of freeing. + typedef std::unordered_map<JSArrayBuffer*, size_t, Hasher> TrackingData; Heap* heap_; // The set contains raw heap pointers which are removed by the GC upon diff --git a/chromium/v8/src/inspector/wasm-translation.cc b/chromium/v8/src/inspector/wasm-translation.cc index 1982f4932ab..4754af5442c 100644 --- a/chromium/v8/src/inspector/wasm-translation.cc +++ b/chromium/v8/src/inspector/wasm-translation.cc @@ -88,7 +88,13 @@ class WasmTranslation::TranslatorImpl::RawTranslator void TranslateBack(TransLocation*) override {} const WasmSourceInformation& GetSourceInformation(v8::Isolate*, int index) override { - static const WasmSourceInformation singleEmptySourceInformation; + // NOTE(mmarchini): prior to 3.9, clang won't accept const object + // instantiations with non-user-provided default constructors, unless an + // empty initializer is explicitly given. Node.js still supports older + // clang versions, therefore we must take care when using const objects + // with default constructors. For more informations, please refer to CWG + // 253 (http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#253) + static const WasmSourceInformation singleEmptySourceInformation = {}; return singleEmptySourceInformation; } const String16 GetHash(v8::Isolate*, int index) override { diff --git a/chromium/v8/src/intl.cc b/chromium/v8/src/intl.cc index 5c2cb4e8fe1..139bb4daf54 100644 --- a/chromium/v8/src/intl.cc +++ b/chromium/v8/src/intl.cc @@ -358,17 +358,17 @@ ICUTimezoneCache::~ICUTimezoneCache() { Clear(); } const char* ICUTimezoneCache::LocalTimezone(double time_ms) { bool is_dst = DaylightSavingsOffset(time_ms) != 0; - char* name = is_dst ? dst_timezone_name_ : timezone_name_; - if (name[0] == '\0') { + std::string* name = is_dst ? &dst_timezone_name_ : &timezone_name_; + if (name->empty()) { icu::UnicodeString result; GetTimeZone()->getDisplayName(is_dst, icu::TimeZone::LONG, result); result += '\0'; - icu::CheckedArrayByteSink byte_sink(name, kMaxTimezoneChars); + icu::StringByteSink<std::string> byte_sink(name); result.toUTF8(byte_sink); - CHECK(!byte_sink.Overflowed()); } - return const_cast<const char*>(name); + DCHECK(!name->empty()); + return name->c_str(); } icu::TimeZone* ICUTimezoneCache::GetTimeZone() { @@ -418,8 +418,8 @@ double ICUTimezoneCache::LocalTimeOffset(double time_ms, bool is_utc) { void ICUTimezoneCache::Clear() { delete timezone_; timezone_ = nullptr; - timezone_name_[0] = '\0'; - dst_timezone_name_[0] = '\0'; + timezone_name_.clear(); + dst_timezone_name_.clear(); } } // namespace internal diff --git a/chromium/v8/src/intl.h b/chromium/v8/src/intl.h index 967a3e92777..627cb4980de 100644 --- a/chromium/v8/src/intl.h +++ b/chromium/v8/src/intl.h @@ -9,6 +9,8 @@ #ifndef V8_INTL_H_ #define V8_INTL_H_ +#include <string> + #include "src/base/timezone-cache.h" #include "src/objects.h" #include "src/objects/string.h" @@ -64,9 +66,8 @@ class ICUTimezoneCache : public base::TimezoneCache { icu::TimeZone* timezone_; - static const int32_t kMaxTimezoneChars = 100; - char timezone_name_[kMaxTimezoneChars]; - char dst_timezone_name_[kMaxTimezoneChars]; + std::string timezone_name_; + std::string dst_timezone_name_; }; } // namespace internal diff --git a/chromium/v8/src/isolate.cc b/chromium/v8/src/isolate.cc index 2502ea3edd0..adb30b12ace 100644 --- a/chromium/v8/src/isolate.cc +++ b/chromium/v8/src/isolate.cc @@ -9,6 +9,7 @@ #include <atomic> #include <fstream> // NOLINT(readability/streams) #include <sstream> +#include <unordered_map> #include "src/api.h" #include "src/assembler-inl.h" @@ -178,8 +179,6 @@ void ThreadLocalTop::Free() { base::Thread::LocalStorageKey Isolate::isolate_key_; base::Thread::LocalStorageKey Isolate::thread_id_key_; base::Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_; -base::LazyMutex Isolate::thread_data_table_mutex_ = LAZY_MUTEX_INITIALIZER; -Isolate::ThreadDataTable* Isolate::thread_data_table_ = nullptr; base::Atomic32 Isolate::isolate_counter_ = 0; #if DEBUG base::Atomic32 Isolate::isolate_key_created_ = 0; @@ -190,13 +189,13 @@ Isolate::PerIsolateThreadData* ThreadId thread_id = ThreadId::Current(); PerIsolateThreadData* per_thread = nullptr; { - base::LockGuard<base::Mutex> lock_guard(thread_data_table_mutex_.Pointer()); - per_thread = thread_data_table_->Lookup(this, thread_id); + base::LockGuard<base::Mutex> lock_guard(&thread_data_table_mutex_); + per_thread = thread_data_table_.Lookup(thread_id); if (per_thread == nullptr) { per_thread = new PerIsolateThreadData(this, thread_id); - thread_data_table_->Insert(per_thread); + thread_data_table_.Insert(per_thread); } - DCHECK(thread_data_table_->Lookup(this, thread_id) == per_thread); + DCHECK(thread_data_table_.Lookup(thread_id) == per_thread); } return per_thread; } @@ -207,12 +206,11 @@ void Isolate::DiscardPerThreadDataForThisThread() { if (thread_id_int) { ThreadId thread_id = ThreadId(thread_id_int); DCHECK(!thread_manager_->mutex_owner_.Equals(thread_id)); - base::LockGuard<base::Mutex> lock_guard(thread_data_table_mutex_.Pointer()); - PerIsolateThreadData* per_thread = - thread_data_table_->Lookup(this, thread_id); + base::LockGuard<base::Mutex> lock_guard(&thread_data_table_mutex_); + PerIsolateThreadData* per_thread = thread_data_table_.Lookup(thread_id); if (per_thread) { DCHECK(!per_thread->thread_state_); - thread_data_table_->Remove(per_thread); + thread_data_table_.Remove(per_thread); } } } @@ -228,23 +226,20 @@ Isolate::PerIsolateThreadData* Isolate::FindPerThreadDataForThread( ThreadId thread_id) { PerIsolateThreadData* per_thread = nullptr; { - base::LockGuard<base::Mutex> lock_guard(thread_data_table_mutex_.Pointer()); - per_thread = thread_data_table_->Lookup(this, thread_id); + base::LockGuard<base::Mutex> lock_guard(&thread_data_table_mutex_); + per_thread = thread_data_table_.Lookup(thread_id); } return per_thread; } void Isolate::InitializeOncePerProcess() { - base::LockGuard<base::Mutex> lock_guard(thread_data_table_mutex_.Pointer()); - CHECK_NULL(thread_data_table_); isolate_key_ = base::Thread::CreateThreadLocalKey(); #if DEBUG base::Relaxed_Store(&isolate_key_created_, 1); #endif thread_id_key_ = base::Thread::CreateThreadLocalKey(); per_isolate_thread_data_key_ = base::Thread::CreateThreadLocalKey(); - thread_data_table_ = new Isolate::ThreadDataTable(); } Address Isolate::get_address_from_id(IsolateAddressId id) { @@ -2292,14 +2287,9 @@ char* Isolate::RestoreThread(char* from) { return from + sizeof(ThreadLocalTop); } -Isolate::ThreadDataTable::ThreadDataTable() : list_(nullptr) {} +Isolate::ThreadDataTable::ThreadDataTable() : table_() {} -Isolate::ThreadDataTable::~ThreadDataTable() { - // TODO(svenpanne) The assertion below would fire if an embedder does not - // cleanly dispose all Isolates before disposing v8, so we are conservative - // and leave it out for now. - // DCHECK_NULL(list_); -} +Isolate::ThreadDataTable::~ThreadDataTable() {} void Isolate::ReleaseManagedObjects() { Isolate::ManagedObjectFinalizer* current = @@ -2346,40 +2336,30 @@ Isolate::PerIsolateThreadData::~PerIsolateThreadData() { #endif } - -Isolate::PerIsolateThreadData* - Isolate::ThreadDataTable::Lookup(Isolate* isolate, - ThreadId thread_id) { - for (PerIsolateThreadData* data = list_; data != nullptr; - data = data->next_) { - if (data->Matches(isolate, thread_id)) return data; - } - return nullptr; +Isolate::PerIsolateThreadData* Isolate::ThreadDataTable::Lookup( + ThreadId thread_id) { + auto t = table_.find(thread_id); + if (t == table_.end()) return nullptr; + return t->second; } void Isolate::ThreadDataTable::Insert(Isolate::PerIsolateThreadData* data) { - if (list_ != nullptr) list_->prev_ = data; - data->next_ = list_; - list_ = data; + bool inserted = table_.insert(std::make_pair(data->thread_id_, data)).second; + CHECK(inserted); } void Isolate::ThreadDataTable::Remove(PerIsolateThreadData* data) { - if (list_ == data) list_ = data->next_; - if (data->next_ != nullptr) data->next_->prev_ = data->prev_; - if (data->prev_ != nullptr) data->prev_->next_ = data->next_; + table_.erase(data->thread_id_); delete data; } - -void Isolate::ThreadDataTable::RemoveAllThreads(Isolate* isolate) { - PerIsolateThreadData* data = list_; - while (data != nullptr) { - PerIsolateThreadData* next = data->next_; - if (data->isolate() == isolate) Remove(data); - data = next; +void Isolate::ThreadDataTable::RemoveAllThreads() { + for (auto& x : table_) { + delete x.second; } + table_.clear(); } @@ -2554,10 +2534,6 @@ Isolate::Isolate(bool enable_serializer) cancelable_task_manager_(new CancelableTaskManager()), abort_on_uncaught_exception_callback_(nullptr), total_regexp_code_generated_(0) { - { - base::LockGuard<base::Mutex> lock_guard(thread_data_table_mutex_.Pointer()); - CHECK(thread_data_table_); - } id_ = base::Relaxed_AtomicIncrement(&isolate_counter_, 1); TRACE_ISOLATE(constructor); @@ -2615,8 +2591,8 @@ void Isolate::TearDown() { Deinit(); { - base::LockGuard<base::Mutex> lock_guard(thread_data_table_mutex_.Pointer()); - thread_data_table_->RemoveAllThreads(this); + base::LockGuard<base::Mutex> lock_guard(&thread_data_table_mutex_); + thread_data_table_.RemoveAllThreads(); } #ifdef DEBUG @@ -2630,12 +2606,6 @@ void Isolate::TearDown() { } -void Isolate::GlobalTearDown() { - delete thread_data_table_; - thread_data_table_ = nullptr; -} - - void Isolate::ClearSerializerData() { delete external_reference_map_; external_reference_map_ = nullptr; diff --git a/chromium/v8/src/isolate.h b/chromium/v8/src/isolate.h index 16b4d663cb8..75b447f1629 100644 --- a/chromium/v8/src/isolate.h +++ b/chromium/v8/src/isolate.h @@ -8,6 +8,7 @@ #include <cstddef> #include <memory> #include <queue> +#include <unordered_map> #include <vector> #include "include/v8-inspector.h" @@ -248,6 +249,8 @@ class ThreadId { return *this; } + bool operator==(const ThreadId& other) const { return Equals(other); } + // Returns ThreadId for current thread. static ThreadId Current() { return ThreadId(GetCurrentThreadId()); } @@ -288,7 +291,6 @@ class ThreadId { friend class Isolate; }; - #define FIELD_ACCESSOR(type, name) \ inline void set_##name(type v) { name##_ = v; } \ inline type name() const { return name##_; } @@ -551,8 +553,6 @@ class Isolate { void ReleaseManagedObjects(); - static void GlobalTearDown(); - void ClearSerializerData(); // Find the PerThread for this particular (isolate, thread) combination @@ -1398,20 +1398,24 @@ class Isolate { void* embedder_data_[Internals::kNumIsolateDataSlots]; Heap heap_; - // The per-process lock should be acquired before the ThreadDataTable is - // modified. class ThreadDataTable { public: ThreadDataTable(); ~ThreadDataTable(); - PerIsolateThreadData* Lookup(Isolate* isolate, ThreadId thread_id); + PerIsolateThreadData* Lookup(ThreadId thread_id); void Insert(PerIsolateThreadData* data); void Remove(PerIsolateThreadData* data); - void RemoveAllThreads(Isolate* isolate); + void RemoveAllThreads(); private: - PerIsolateThreadData* list_; + struct Hasher { + std::size_t operator()(const ThreadId& t) const { + return std::hash<int>()(t.ToInteger()); + } + }; + + std::unordered_map<ThreadId, PerIsolateThreadData*, Hasher> table_; }; // These items form a stack synchronously with threads Enter'ing and Exit'ing @@ -1439,12 +1443,15 @@ class Isolate { DISALLOW_COPY_AND_ASSIGN(EntryStackItem); }; - static base::LazyMutex thread_data_table_mutex_; + // TODO(kenton@cloudflare.com): This mutex can be removed if + // thread_data_table_ is always accessed under the isolate lock. I do not + // know if this is the case, so I'm preserving it for now. + base::Mutex thread_data_table_mutex_; static base::Thread::LocalStorageKey per_isolate_thread_data_key_; static base::Thread::LocalStorageKey isolate_key_; static base::Thread::LocalStorageKey thread_id_key_; - static ThreadDataTable* thread_data_table_; + ThreadDataTable thread_data_table_; // A global counter for all generated Isolates, might overflow. static base::Atomic32 isolate_counter_; diff --git a/chromium/v8/src/objects.cc b/chromium/v8/src/objects.cc index 1412e4baf36..8057cb837b1 100644 --- a/chromium/v8/src/objects.cc +++ b/chromium/v8/src/objects.cc @@ -19122,7 +19122,7 @@ void JSArrayBuffer::Neuter() { } } -void JSArrayBuffer::FreeBackingStore() { +void JSArrayBuffer::FreeBackingStoreFromMainThread() { if (allocation_base() == nullptr) { return; } diff --git a/chromium/v8/src/objects/js-array.h b/chromium/v8/src/objects/js-array.h index 157ce29c6f2..6df0af17cb8 100644 --- a/chromium/v8/src/objects/js-array.h +++ b/chromium/v8/src/objects/js-array.h @@ -140,6 +140,8 @@ class JSArrayBuffer : public JSObject { // [backing_store]: backing memory for this array DECL_ACCESSORS(backing_store, void) + // For non-wasm, allocation_length and allocation_base are byte_length and + // backing_store, respectively. inline size_t allocation_length() const; inline void* allocation_base() const; @@ -194,7 +196,7 @@ class JSArrayBuffer : public JSObject { // Sets whether the buffer is tracked by the WasmMemoryTracker. void set_is_wasm_memory(bool is_wasm_memory); - void FreeBackingStore(); + void FreeBackingStoreFromMainThread(); static void FreeBackingStore(Isolate* isolate, Allocation allocation); V8_EXPORT_PRIVATE static void Setup( diff --git a/chromium/v8/src/v8.cc b/chromium/v8/src/v8.cc index ab4918efec2..d3b4c471a4f 100644 --- a/chromium/v8/src/v8.cc +++ b/chromium/v8/src/v8.cc @@ -49,7 +49,6 @@ void V8::TearDown() { Bootstrapper::TearDownExtensions(); ElementsAccessor::TearDown(); RegisteredExtension::UnregisterAll(); - Isolate::GlobalTearDown(); sampler::Sampler::TearDown(); FlagList::ResetAllFlags(); // Frees memory held by string arguments. } diff --git a/chromium/v8/src/wasm/wasm-memory.cc b/chromium/v8/src/wasm/wasm-memory.cc index cd55cc1cf7f..9bb8002a4f0 100644 --- a/chromium/v8/src/wasm/wasm-memory.cc +++ b/chromium/v8/src/wasm/wasm-memory.cc @@ -294,7 +294,7 @@ void DetachMemoryBuffer(Isolate* isolate, Handle<JSArrayBuffer> buffer, // by Neuter. This means there is a dangling pointer until we neuter the // buffer. Since there is no way for the user to directly call // FreeBackingStore, we can ensure this is safe. - buffer->FreeBackingStore(); + buffer->FreeBackingStoreFromMainThread(); } } |