summaryrefslogtreecommitdiff
path: root/chromium/v8/src
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/v8/src')
-rw-r--r--chromium/v8/src/builtins/builtins-date.cc2
-rw-r--r--chromium/v8/src/builtins/builtins-regexp-gen.cc24
-rw-r--r--chromium/v8/src/compiler/js-call-reducer.cc17
-rw-r--r--chromium/v8/src/compiler/representation-change.cc22
-rw-r--r--chromium/v8/src/compiler/representation-change.h2
-rw-r--r--chromium/v8/src/flag-definitions.h8
-rw-r--r--chromium/v8/src/heap/array-buffer-tracker-inl.h12
-rw-r--r--chromium/v8/src/heap/array-buffer-tracker.cc14
-rw-r--r--chromium/v8/src/heap/array-buffer-tracker.h9
-rw-r--r--chromium/v8/src/inspector/wasm-translation.cc8
-rw-r--r--chromium/v8/src/intl.cc14
-rw-r--r--chromium/v8/src/intl.h7
-rw-r--r--chromium/v8/src/isolate.cc82
-rw-r--r--chromium/v8/src/isolate.h27
-rw-r--r--chromium/v8/src/objects.cc2
-rw-r--r--chromium/v8/src/objects/js-array.h4
-rw-r--r--chromium/v8/src/v8.cc1
-rw-r--r--chromium/v8/src/wasm/wasm-memory.cc2
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();
}
}