Commit ec554ec0 authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

[offthread] Make NextScriptId thread-safe

Make the NextScriptId value incrementing method thread-safe, using
CompareAndSwap primitives. This will allow it to be used in the
future for off-thread compilation.

Bug: chromium:1011762
Change-Id: I5b449e75c7dc63d24fa045ae880b0680b54c2f3d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2046883Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66200}
parent f6d988f9
......@@ -104,6 +104,16 @@ class AsAtomicImpl {
cast_helper<T>::to_storage_type(new_value)));
}
template <typename T>
static T Relaxed_CompareAndSwap(
T* addr, typename std::remove_reference<T>::type old_value,
typename std::remove_reference<T>::type new_value) {
STATIC_ASSERT(sizeof(T) <= sizeof(AtomicStorageType));
return cast_helper<T>::to_return_type(base::Relaxed_CompareAndSwap(
to_storage_addr(addr), cast_helper<T>::to_storage_type(old_value),
cast_helper<T>::to_storage_type(new_value)));
}
template <typename T>
static T AcquireRelease_CompareAndSwap(
T* addr, typename std::remove_reference<T>::type old_value,
......
......@@ -10,6 +10,7 @@
// Clients of this interface shouldn't depend on lots of heap internals.
// Do not include anything from src/heap other than src/heap/heap.h and its
// write barrier here!
#include "src/base/atomicops.h"
#include "src/heap/heap-write-barrier.h"
#include "src/heap/heap.h"
#include "src/heap/third-party/heap-api.h"
......@@ -575,11 +576,27 @@ Oddball Heap::ToBoolean(bool condition) {
}
int Heap::NextScriptId() {
int last_id = last_script_id().value();
if (last_id == Smi::kMaxValue) last_id = v8::UnboundScript::kNoScriptId;
last_id++;
set_last_script_id(Smi::FromInt(last_id));
return last_id;
FullObjectSlot last_script_id_slot(&roots_table()[RootIndex::kLastScriptId]);
Smi last_id = Smi::cast(last_script_id_slot.Relaxed_Load());
Smi new_id, last_id_before_cas;
do {
if (last_id.value() == Smi::kMaxValue) {
STATIC_ASSERT(v8::UnboundScript::kNoScriptId == 0);
new_id = Smi::FromInt(1);
} else {
new_id = Smi::FromInt(last_id.value() + 1);
}
// CAS returns the old value on success, and the current value in the slot
// on failure. Therefore, we want to break if the returned value matches the
// old value (last_id), and keep looping (with the new last_id value) if it
// doesn't.
last_id_before_cas = last_id;
last_id =
Smi::cast(last_script_id_slot.Relaxed_CompareAndSwap(last_id, new_id));
} while (last_id != last_id_before_cas);
return new_id.value();
}
int Heap::NextDebuggingId() {
......
......@@ -49,6 +49,12 @@ void FullObjectSlot::Release_Store(Object value) const {
base::AsAtomicPointer::Release_Store(location(), value.ptr());
}
Object FullObjectSlot::Relaxed_CompareAndSwap(Object old, Object target) const {
Address result = base::AsAtomicPointer::Relaxed_CompareAndSwap(
location(), old.ptr(), target.ptr());
return Object(result);
}
Object FullObjectSlot::Release_CompareAndSwap(Object old, Object target) const {
Address result = base::AsAtomicPointer::Release_CompareAndSwap(
location(), old.ptr(), target.ptr());
......
......@@ -116,6 +116,7 @@ class FullObjectSlot : public SlotBase<FullObjectSlot, Address> {
inline Object Relaxed_Load() const;
inline void Relaxed_Store(Object value) const;
inline void Release_Store(Object value) const;
inline Object Relaxed_CompareAndSwap(Object old, Object target) const;
inline Object Release_CompareAndSwap(Object old, Object target) const;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment