Commit 8da583ee authored by Nico Hartmann's avatar Nico Hartmann Committed by V8 LUCI CQ

[Torque] Finalize torque-generated synchronized accessors

Torque-generated relaxed/acquire/release accessors now expect an
additional Tag argument to be more consistent with handwritten
accessors.

Torque's annotations are renamed from @relaxedRead, @relaxedWrite,
@acquireRead and @releaseWrite to @cppRelaxedLoad, @cppRelaxedStore,
@cppAcquireLoad and @cppReleaseStore, repesectively. This renaming
shall better reflect the fact that those annotations just generate
corresponding synchronization on the generated C++ accessors
(not CSA code) and be more consistent with the C++ side of things
where "Load" and "Store" is used instead of "Read" and "Write".

This CL uses these new annotations on a few fields in DebugInfo and
FunctionTemplateInfo to have Torque generate accessors automatically.

Bug: v8:11122
Change-Id: Ibdf3e6b37a254605ff69ba9a50d7b1646790ea15
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2876857Reviewed-by: 's avatarSeth Brenith <seth.brenith@microsoft.com>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Auto-Submit: Nico Hartmann <nicohartmann@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74463}
parent 6a34bd2b
......@@ -2071,7 +2071,7 @@ void SourceTextModuleData::Serialize(JSHeapBroker* broker) {
TRACE(broker, "Copied " << exports_.size() << " exports");
DCHECK_NULL(import_meta_);
import_meta_ = broker->GetOrCreateData(module->import_meta());
import_meta_ = broker->GetOrCreateData(module->import_meta(kAcquireLoad));
TRACE(broker, "Copied import_meta");
}
......@@ -4001,7 +4001,7 @@ base::Optional<CellRef> SourceTextModuleRef::GetCell(int cell_index) const {
base::Optional<ObjectRef> SourceTextModuleRef::import_meta() const {
if (data_->should_access_heap()) {
return TryMakeRef(broker(), object()->import_meta());
return TryMakeRef(broker(), object()->import_meta(kAcquireLoad));
}
return ObjectRef(broker(),
data()->AsSourceTextModule()->GetImportMeta(broker()));
......
......@@ -1349,7 +1349,8 @@ void Debug::PrepareFunctionForDebugExecution(
DCHECK(shared->is_compiled());
DCHECK(shared->HasDebugInfo());
Handle<DebugInfo> debug_info = GetOrCreateDebugInfo(shared);
if (debug_info->flags() & DebugInfo::kPreparedForDebugExecution) return;
if (debug_info->flags(kRelaxedLoad) & DebugInfo::kPreparedForDebugExecution)
return;
if (shared->HasBytecodeArray()) {
SharedFunctionInfo::InstallDebugBytecode(shared, isolate_);
......@@ -1368,8 +1369,9 @@ void Debug::PrepareFunctionForDebugExecution(
redirect_visitor.VisitThread(isolate_, isolate_->thread_local_top());
isolate_->thread_manager()->IterateArchivedThreads(&redirect_visitor);
}
debug_info->set_flags(debug_info->flags() |
DebugInfo::kPreparedForDebugExecution);
debug_info->set_flags(
debug_info->flags(kRelaxedLoad) | DebugInfo::kPreparedForDebugExecution,
kRelaxedStore);
}
void Debug::InstallDebugBreakTrampoline() {
......@@ -1749,10 +1751,10 @@ void Debug::CreateBreakInfo(Handle<SharedFunctionInfo> shared) {
Handle<FixedArray> break_points(
factory->NewFixedArray(DebugInfo::kEstimatedNofBreakPointsInFunction));
int flags = debug_info->flags();
int flags = debug_info->flags(kRelaxedLoad);
flags |= DebugInfo::kHasBreakInfo;
if (CanBreakAtEntry(shared)) flags |= DebugInfo::kCanBreakAtEntry;
debug_info->set_flags(flags);
debug_info->set_flags(flags, kRelaxedStore);
debug_info->set_break_points(*break_points);
SharedFunctionInfo::EnsureSourcePositionsAvailable(isolate_, shared);
......@@ -1779,7 +1781,9 @@ void Debug::InstallCoverageInfo(Handle<SharedFunctionInfo> shared,
DCHECK(!debug_info->HasCoverageInfo());
debug_info->set_flags(debug_info->flags() | DebugInfo::kHasCoverageInfo);
debug_info->set_flags(
debug_info->flags(kRelaxedLoad) | DebugInfo::kHasCoverageInfo,
kRelaxedStore);
debug_info->set_coverage_info(*coverage_info);
}
......
......@@ -680,7 +680,7 @@ void SloppyArgumentsElementsVerify(Isolate* isolate,
for (int i = 0; i < nofMappedParameters; i++) {
// Verify that each context-mapped argument is either the hole or a valid
// Smi within context length range.
Object mapped = elements.mapped_entries(i);
Object mapped = elements.mapped_entries(i, kRelaxedLoad);
if (mapped.IsTheHole(isolate)) {
// Slow sloppy arguments can be holey.
if (!is_fast) continue;
......
......@@ -448,7 +448,7 @@ void PrintSloppyArgumentElements(std::ostream& os, ElementsKind kind,
<< "\n 1: arguments_store: " << Brief(arguments_store)
<< "\n parameter to context slot map:";
for (int i = 0; i < elements.length(); i++) {
Object mapped_entry = elements.mapped_entries(i);
Object mapped_entry = elements.mapped_entries(i, kRelaxedLoad);
os << "\n " << i << ": param(" << i << "): " << Brief(mapped_entry);
if (mapped_entry.IsTheHole()) {
os << " in the arguments_store[" << i << "]";
......@@ -1741,7 +1741,7 @@ void SourceTextModule::SourceTextModulePrint(std::ostream& os) {
os << "\n - script: " << Brief(script);
os << "\n - origin: " << Brief(script.GetNameOrSourceURL());
os << "\n - requested_modules: " << Brief(requested_modules());
os << "\n - import_meta: " << Brief(import_meta());
os << "\n - import_meta: " << Brief(import_meta(kAcquireLoad));
os << "\n - cycle_root: " << Brief(cycle_root());
os << "\n - async_evaluating_ordinal: " << async_evaluating_ordinal();
os << "\n";
......
......@@ -4408,7 +4408,7 @@ void Isolate::SetHostImportModuleDynamicallyCallback(
MaybeHandle<JSObject> Isolate::RunHostInitializeImportMetaObjectCallback(
Handle<SourceTextModule> module) {
CHECK(module->import_meta().IsTheHole(this));
CHECK(module->import_meta(kAcquireLoad).IsTheHole(this));
Handle<JSObject> import_meta = factory()->NewJSObjectWithNullProto();
if (host_initialize_import_meta_object_callback_ != nullptr) {
v8::Local<v8::Context> api_context =
......
......@@ -2475,7 +2475,8 @@ Handle<SourceTextModule> Factory::NewSourceTextModule(
module.set_status(Module::kUninstantiated);
module.set_exception(roots.the_hole_value(), SKIP_WRITE_BARRIER);
module.set_top_level_capability(roots.undefined_value(), SKIP_WRITE_BARRIER);
module.set_import_meta(roots.the_hole_value(), SKIP_WRITE_BARRIER);
module.set_import_meta(roots.the_hole_value(), kReleaseStore,
SKIP_WRITE_BARRIER);
module.set_dfs_index(-1);
module.set_dfs_ancestor_index(-1);
module.set_flags(0);
......@@ -3069,7 +3070,7 @@ Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) {
NewStructInternal<DebugInfo>(DEBUG_INFO_TYPE, AllocationType::kOld);
DisallowGarbageCollection no_gc;
SharedFunctionInfo raw_shared = *shared;
debug_info.set_flags(DebugInfo::kNone);
debug_info.set_flags(DebugInfo::kNone, kRelaxedStore);
debug_info.set_shared(raw_shared);
debug_info.set_debugger_hints(0);
DCHECK_EQ(DebugInfo::kNoDebuggingId, debug_info.debugging_id());
......
......@@ -80,7 +80,7 @@ extern shape JSStrictArgumentsObject extends JSArgumentsObject {
class SloppyArgumentsElements extends FixedArrayBase {
context: Context;
arguments: FixedArray|NumberDictionary;
@relaxedRead mapped_entries[length]: Smi|TheHole;
@cppRelaxedLoad mapped_entries[length]: Smi|TheHole;
}
macro NewSloppyArgumentsElements<Iterator: type>(
......
......@@ -55,15 +55,17 @@ NEVER_READ_ONLY_SPACE_IMPL(Context)
CAST_ACCESSOR(NativeContext)
V8_INLINE Object Context::get(int index) const { return elements(index); }
V8_INLINE Object Context::get(int index) const {
return elements(index, kRelaxedLoad);
}
V8_INLINE Object Context::get(PtrComprCageBase cage_base, int index) const {
return elements(cage_base, index);
return elements(cage_base, index, kRelaxedLoad);
}
V8_INLINE void Context::set(int index, Object value) {
set_elements(index, value);
set_elements(index, value, kRelaxedStore);
}
V8_INLINE void Context::set(int index, Object value, WriteBarrierMode mode) {
set_elements(index, value, mode);
set_elements(index, value, kRelaxedStore, mode);
}
void Context::set_scope_info(ScopeInfo scope_info, WriteBarrierMode mode) {
......
......@@ -13,7 +13,7 @@ class Context extends HeapObject {
return *ContextSlot(this, ContextSlot::SCOPE_INFO_INDEX);
}
const length: Smi;
@relaxedRead @relaxedWrite elements[length]: Object;
@cppRelaxedLoad @cppRelaxedStore elements[length]: Object;
}
extern class AwaitContext extends Context generates 'TNode<Context>';
......
......@@ -36,12 +36,6 @@ BIT_FIELD_ACCESSORS(DebugInfo, debugger_hints, computed_debug_is_blackboxed,
BIT_FIELD_ACCESSORS(DebugInfo, debugger_hints, debugging_id,
DebugInfo::DebuggingIdBits)
// TODO(nicohartmann@, v8:11122): Remove once Torque can generate them.
RELEASE_ACQUIRE_ACCESSORS(DebugInfo, debug_bytecode_array, HeapObject,
kDebugBytecodeArrayOffset)
RELEASE_ACQUIRE_ACCESSORS(DebugInfo, original_bytecode_array, HeapObject,
kOriginalBytecodeArrayOffset)
bool DebugInfo::HasInstrumentedBytecodeArray() {
return debug_bytecode_array(kAcquireLoad).IsBytecodeArray();
}
......
......@@ -14,18 +14,23 @@ namespace v8 {
namespace internal {
bool DebugInfo::IsEmpty() const {
return flags() == kNone && debugger_hints() == 0;
return flags(kRelaxedLoad) == kNone && debugger_hints() == 0;
}
bool DebugInfo::HasBreakInfo() const { return (flags() & kHasBreakInfo) != 0; }
bool DebugInfo::HasBreakInfo() const {
return (flags(kRelaxedLoad) & kHasBreakInfo) != 0;
}
DebugInfo::ExecutionMode DebugInfo::DebugExecutionMode() const {
return (flags() & kDebugExecutionMode) != 0 ? kSideEffects : kBreakpoints;
return (flags(kRelaxedLoad) & kDebugExecutionMode) != 0 ? kSideEffects
: kBreakpoints;
}
void DebugInfo::SetDebugExecutionMode(ExecutionMode value) {
set_flags(value == kSideEffects ? (flags() | kDebugExecutionMode)
: (flags() & ~kDebugExecutionMode));
set_flags(value == kSideEffects
? (flags(kRelaxedLoad) | kDebugExecutionMode)
: (flags(kRelaxedLoad) & ~kDebugExecutionMode),
kRelaxedStore);
}
void DebugInfo::ClearBreakInfo(Isolate* isolate) {
......@@ -45,27 +50,29 @@ void DebugInfo::ClearBreakInfo(Isolate* isolate) {
}
set_break_points(ReadOnlyRoots(isolate).empty_fixed_array());
int new_flags = flags();
int new_flags = flags(kRelaxedLoad);
new_flags &= ~kHasBreakInfo & ~kPreparedForDebugExecution;
new_flags &= ~kBreakAtEntry & ~kCanBreakAtEntry;
new_flags &= ~kDebugExecutionMode;
set_flags(new_flags);
set_flags(new_flags, kRelaxedStore);
}
void DebugInfo::SetBreakAtEntry() {
DCHECK(CanBreakAtEntry());
set_flags(flags() | kBreakAtEntry);
set_flags(flags(kRelaxedLoad) | kBreakAtEntry, kRelaxedStore);
}
void DebugInfo::ClearBreakAtEntry() {
DCHECK(CanBreakAtEntry());
set_flags(flags() & ~kBreakAtEntry);
set_flags(flags(kRelaxedLoad) & ~kBreakAtEntry, kRelaxedStore);
}
bool DebugInfo::BreakAtEntry() const { return (flags() & kBreakAtEntry) != 0; }
bool DebugInfo::BreakAtEntry() const {
return (flags(kRelaxedLoad) & kBreakAtEntry) != 0;
}
bool DebugInfo::CanBreakAtEntry() const {
return (flags() & kCanBreakAtEntry) != 0;
return (flags(kRelaxedLoad) & kCanBreakAtEntry) != 0;
}
// Check if there is a break point at this source position.
......@@ -199,15 +206,15 @@ Handle<Object> DebugInfo::FindBreakPointInfo(Isolate* isolate,
}
bool DebugInfo::HasCoverageInfo() const {
return (flags() & kHasCoverageInfo) != 0;
return (flags(kRelaxedLoad) & kHasCoverageInfo) != 0;
}
void DebugInfo::ClearCoverageInfo(Isolate* isolate) {
if (HasCoverageInfo()) {
set_coverage_info(ReadOnlyRoots(isolate).undefined_value());
int new_flags = flags() & ~kHasCoverageInfo;
set_flags(new_flags);
int new_flags = flags(kRelaxedLoad) & ~kHasCoverageInfo;
set_flags(new_flags, kRelaxedStore);
}
}
......
......@@ -45,9 +45,6 @@ class DebugInfo : public TorqueGeneratedDebugInfo<DebugInfo, Struct> {
ExecutionMode DebugExecutionMode() const;
void SetDebugExecutionMode(ExecutionMode value);
DECL_RELEASE_ACQUIRE_ACCESSORS(debug_bytecode_array, HeapObject)
DECL_RELEASE_ACQUIRE_ACCESSORS(original_bytecode_array, HeapObject)
// Specifies whether the associated function has an instrumented bytecode
// array. If so, OriginalBytecodeArray returns the non-instrumented bytecode,
// and DebugBytecodeArray returns the instrumented bytecode.
......
......@@ -44,14 +44,18 @@ extern class DebugInfo extends Struct {
script: Undefined|Script;
// The original uninstrumented bytecode array for functions with break
// points - the instrumented bytecode is held in the shared function info.
@cppAcquireLoad
@cppReleaseStore
original_bytecode_array: Undefined|BytecodeArray;
// The debug instrumented bytecode array for functions with break points
// - also pointed to by the shared function info.
@cppAcquireLoad
@cppReleaseStore
debug_bytecode_array: Undefined|BytecodeArray;
// Fixed array holding status information for each active break point.
break_points: FixedArray;
// A bitfield that lists uses of the current instance.
@relaxedRead @relaxedWrite flags: SmiTagged<DebugInfoFlags>;
@cppRelaxedLoad @cppRelaxedStore flags: SmiTagged<DebugInfoFlags>;
coverage_info: CoverageInfo|Undefined;
}
......
......@@ -4232,7 +4232,7 @@ class SloppyArgumentsElementsAccessor
if (entry.as_uint32() < length) {
// Read context mapped entry.
DisallowGarbageCollection no_gc;
Object probe = elements->mapped_entries(entry.as_uint32());
Object probe = elements->mapped_entries(entry.as_uint32(), kRelaxedLoad);
DCHECK(!probe.IsTheHole(isolate));
Context context = elements->context();
int context_entry = Smi::ToInt(probe);
......@@ -4268,7 +4268,7 @@ class SloppyArgumentsElementsAccessor
if (entry.as_uint32() < length) {
// Store context mapped entry.
DisallowGarbageCollection no_gc;
Object probe = elements.mapped_entries(entry.as_uint32());
Object probe = elements.mapped_entries(entry.as_uint32(), kRelaxedLoad);
DCHECK(!probe.IsTheHole());
Context context = Context::cast(elements.context());
int context_entry = Smi::ToInt(probe);
......@@ -4401,7 +4401,7 @@ class SloppyArgumentsElementsAccessor
size_t index) {
uint32_t length = elements.length();
if (index >= length) return false;
return !elements.mapped_entries(static_cast<uint32_t>(index))
return !elements.mapped_entries(static_cast<uint32_t>(index), kRelaxedLoad)
.IsTheHole(isolate);
}
......@@ -4456,7 +4456,8 @@ class SloppyArgumentsElementsAccessor
uint32_t length = elements->length();
for (uint32_t i = 0; i < length; ++i) {
if (elements->mapped_entries(i).IsTheHole(isolate)) continue;
if (elements->mapped_entries(i, kRelaxedLoad).IsTheHole(isolate))
continue;
if (convert == GetKeysConversion::kConvertToString) {
Handle<String> index_string = isolate->factory()->Uint32ToString(i);
list->set(insertion_index, *index_string);
......@@ -4621,7 +4622,7 @@ class SlowSloppyArgumentsElementsAccessor
Handle<SloppyArgumentsElements>::cast(store);
uint32_t length = elements->length();
if (entry.as_uint32() < length) {
Object probe = elements->mapped_entries(entry.as_uint32());
Object probe = elements->mapped_entries(entry.as_uint32(), kRelaxedLoad);
DCHECK(!probe.IsTheHole(isolate));
Context context = elements->context();
int context_entry = Smi::ToInt(probe);
......
......@@ -182,14 +182,15 @@ bool FeedbackVector::IsOfLegacyType(MaybeObject value) {
#endif // DEBUG
MaybeObject FeedbackVector::Get(FeedbackSlot slot) const {
MaybeObject value = raw_feedback_slots(GetIndex(slot));
MaybeObject value = raw_feedback_slots(GetIndex(slot), kRelaxedLoad);
DCHECK(!IsOfLegacyType(value));
return value;
}
MaybeObject FeedbackVector::Get(PtrComprCageBase cage_base,
FeedbackSlot slot) const {
MaybeObject value = raw_feedback_slots(cage_base, GetIndex(slot));
MaybeObject value =
raw_feedback_slots(cage_base, GetIndex(slot), kRelaxedLoad);
DCHECK(!IsOfLegacyType(value));
return value;
}
......
......@@ -24,7 +24,7 @@ extern class FeedbackVector extends HeapObject {
shared_function_info: SharedFunctionInfo;
maybe_optimized_code: Weak<Code>;
closure_feedback_cell_array: ClosureFeedbackCellArray;
@relaxedRead raw_feedback_slots[length]: MaybeObject;
@cppRelaxedLoad raw_feedback_slots[length]: MaybeObject;
}
extern class FeedbackMetadata extends HeapObject;
......@@ -444,7 +444,7 @@ MaybeObject WeakFixedArray::Get(int index) const {
MaybeObject WeakFixedArray::Get(PtrComprCageBase cage_base, int index) const {
DCHECK_LT(static_cast<unsigned>(index), static_cast<unsigned>(length()));
return objects(cage_base, index);
return objects(cage_base, index, kRelaxedLoad);
}
void WeakFixedArray::Set(int index, MaybeObject value, WriteBarrierMode mode) {
......@@ -479,7 +479,7 @@ MaybeObject WeakArrayList::Get(int index) const {
MaybeObject WeakArrayList::Get(PtrComprCageBase cage_base, int index) const {
DCHECK_LT(static_cast<unsigned>(index), static_cast<unsigned>(capacity()));
return objects(cage_base, index);
return objects(cage_base, index, kRelaxedLoad);
}
void WeakArrayList::Set(int index, MaybeObject value, WriteBarrierMode mode) {
......
......@@ -26,7 +26,7 @@ extern class FixedDoubleArray extends FixedArrayBase {
@generateCppClass
extern class WeakFixedArray extends HeapObject {
const length: Smi;
@relaxedRead objects[length]: MaybeObject;
@cppRelaxedLoad objects[length]: MaybeObject;
}
@generateCppClass
......@@ -51,7 +51,7 @@ extern class TemplateList extends FixedArray {
extern class WeakArrayList extends HeapObject {
const capacity: Smi;
length: Smi;
@relaxedRead objects[capacity]: MaybeObject;
@cppRelaxedLoad objects[capacity]: MaybeObject;
}
extern operator '.length_intptr' macro LoadAndUntagFixedArrayBaseLength(
......
......@@ -672,13 +672,13 @@ Handle<JSModuleNamespace> SourceTextModule::GetModuleNamespace(
MaybeHandle<JSObject> SourceTextModule::GetImportMeta(
Isolate* isolate, Handle<SourceTextModule> module) {
Handle<HeapObject> import_meta(module->import_meta(), isolate);
Handle<HeapObject> import_meta(module->import_meta(kAcquireLoad), isolate);
if (import_meta->IsTheHole(isolate)) {
if (!isolate->RunHostInitializeImportMetaObjectCallback(module).ToHandle(
&import_meta)) {
return {};
}
module->set_import_meta(*import_meta);
module->set_import_meta(*import_meta, kReleaseStore);
}
return Handle<JSObject>::cast(import_meta);
}
......@@ -1181,7 +1181,7 @@ void SourceTextModule::Reset(Isolate* isolate,
Handle<SourceTextModule> module) {
Factory* factory = isolate->factory();
DCHECK(module->import_meta().IsTheHole(isolate));
DCHECK(module->import_meta(kAcquireLoad).IsTheHole(isolate));
Handle<FixedArray> regular_exports =
factory->NewFixedArray(module->regular_exports().length());
......
......@@ -29,7 +29,7 @@ extern class SourceTextModule extends Module {
// The value of import.meta inside of this module.
// Lazily initialized on first access. It's the hole before first access and
// a JSObject afterwards.
@acquireRead @releaseWrite import_meta: TheHole|JSObject;
@cppAcquireLoad @cppReleaseStore import_meta: TheHole|JSObject;
// The first visited module of a cycle. For modules not in a cycle, this is
// the module itself. It's the hole before the module state transitions to
......
......@@ -38,29 +38,6 @@ BOOL_ACCESSORS(FunctionTemplateInfo, flag, accept_any_receiver,
AcceptAnyReceiverBit::kShift)
BOOL_ACCESSORS(FunctionTemplateInfo, flag, published, PublishedBit::kShift)
// TODO(nicohartmann@, v8:11122): Let Torque generate this accessor.
RELEASE_ACQUIRE_ACCESSORS(FunctionTemplateInfo, call_code, HeapObject,
kCallCodeOffset)
// TODO(nicohartmann@, v8:11122): Let Torque generate this accessor.
HeapObject FunctionTemplateInfo::rare_data(AcquireLoadTag) const {
PtrComprCageBase cage_base = GetPtrComprCageBase(*this);
return rare_data(cage_base, kAcquireLoad);
}
HeapObject FunctionTemplateInfo::rare_data(PtrComprCageBase cage_base,
AcquireLoadTag) const {
HeapObject value =
TaggedField<HeapObject>::Acquire_Load(cage_base, *this, kRareDataOffset);
DCHECK(value.IsUndefined() || value.IsFunctionTemplateRareData());
return value;
}
void FunctionTemplateInfo::set_rare_data(HeapObject value, ReleaseStoreTag,
WriteBarrierMode mode) {
DCHECK(value.IsUndefined() || value.IsFunctionTemplateRareData());
RELEASE_WRITE_FIELD(*this, kRareDataOffset, value);
CONDITIONAL_WRITE_BARRIER(*this, kRareDataOffset, value, mode);
}
// static
FunctionTemplateRareData FunctionTemplateInfo::EnsureFunctionTemplateRareData(
Isolate* isolate, Handle<FunctionTemplateInfo> function_template_info) {
......
......@@ -97,16 +97,6 @@ class FunctionTemplateInfo
DECL_RARE_ACCESSORS(c_signature, CSignature, Object)
#undef DECL_RARE_ACCESSORS
// TODO(nicohartmann@, v8:11122): Let Torque generate the following accessor.
DECL_RELEASE_ACQUIRE_ACCESSORS(call_code, HeapObject)
// TODO(nicohartmann@, v8:11122): Let Torque generate the following accessor.
inline HeapObject rare_data(AcquireLoadTag) const;
inline HeapObject rare_data(PtrComprCageBase cage_base, AcquireLoadTag) const;
inline void set_rare_data(
HeapObject value, ReleaseStoreTag,
WriteBarrierMode mode = WriteBarrierMode::UPDATE_WRITE_BARRIER);
// Begin flag bits ---------------------
DECL_BOOLEAN_ACCESSORS(undetectable)
......
......@@ -41,7 +41,7 @@ bitfield struct FunctionTemplateInfoFlags extends uint31 {
extern class FunctionTemplateInfo extends TemplateInfo {
// Handler invoked when calling an instance of this FunctionTemplateInfo.
// Either CallHandlerInfo or Undefined.
call_code: CallHandlerInfo|Undefined;
@cppAcquireLoad @cppReleaseStore call_code: CallHandlerInfo|Undefined;
class_name: String|Undefined;
// If the signature is a FunctionTemplateInfo it is used to check whether the
// receiver calling the associated JSFunction is a compatible receiver, i.e.
......@@ -51,6 +51,8 @@ extern class FunctionTemplateInfo extends TemplateInfo {
// If any of the setters declared by DECL_RARE_ACCESSORS are used then a
// FunctionTemplateRareData will be stored here. Until then this contains
// undefined.
@cppAcquireLoad
@cppReleaseStore
rare_data: FunctionTemplateRareData|Undefined;
shared_function_info: SharedFunctionInfo|Undefined;
// Internal field to store a flag bitfield.
......
......@@ -107,15 +107,15 @@ static const char* const ANNOTATION_EXPORT = "@export";
static const char* const ANNOTATION_DO_NOT_GENERATE_CAST = "@doNotGenerateCast";
static const char* const ANNOTATION_USE_PARENT_TYPE_CHECKER =
"@useParentTypeChecker";
// Generate C++ accessors with relaxed write semantics.
// Weak<T> and MaybeObject fields always use relaxed write.
static const char* const ANNOTATION_RELAXED_WRITE = "@relaxedWrite";
// Generate C++ accessors with relaxed read semantics.
static const char* const ANNOTATION_RELAXED_READ = "@relaxedRead";
// Generate C++ accessors with release write semantics.
static const char* const ANNOTATION_RELEASE_WRITE = "@releaseWrite";
// Generate C++ accessors with acquire read semantics.
static const char* const ANNOTATION_ACQUIRE_READ = "@acquireRead";
// Generate C++ accessors with relaxed store semantics.
// Weak<T> and MaybeObject fields always use relaxed store.
static const char* const ANNOTATION_CPP_RELAXED_STORE = "@cppRelaxedStore";
// Generate C++ accessors with relaxed load semantics.
static const char* const ANNOTATION_CPP_RELAXED_LOAD = "@cppRelaxedLoad";
// Generate C++ accessors with release store semantics.
static const char* const ANNOTATION_CPP_RELEASE_STORE = "@cppReleaseStore";
// Generate C++ accessors with acquire load semantics.
static const char* const ANNOTATION_CPP_ACQUIRE_LOAD = "@cppAcquireLoad";
inline bool IsConstexprName(const std::string& name) {
return name.substr(0, std::strlen(CONSTEXPR_TYPE_PREFIX)) ==
......
......@@ -11,6 +11,7 @@
#include "src/base/optional.h"
#include "src/common/globals.h"
#include "src/torque/cc-generator.h"
#include "src/torque/cfg.h"
#include "src/torque/constants.h"
#include "src/torque/csa-generator.h"
#include "src/torque/declaration-visitor.h"
......@@ -4250,15 +4251,47 @@ void CppClassGenerator::GenerateFieldAccessors(
}
hdr_ << " inline " << type_name << " " << name << "("
<< (indexed ? "int i" : "") << ") const;\n";
<< (indexed ? "int i" : "");
switch (class_field.read_synchronization) {
case FieldSynchronization::kNone:
break;
case FieldSynchronization::kRelaxed:
hdr_ << (indexed ? ", RelaxedLoadTag" : "RelaxedLoadTag");
break;
case FieldSynchronization::kAcquireRelease:
hdr_ << (indexed ? ", AcquireLoadTag" : "AcquireLoadTag");
break;
}
hdr_ << ") const;\n";
if (can_contain_heap_objects) {
hdr_ << " inline " << type_name << " " << name
<< "(PtrComprCageBase cage_base" << (indexed ? ", int i" : "")
<< ") const;\n";
<< "(PtrComprCageBase cage_base" << (indexed ? ", int i" : "");
switch (class_field.read_synchronization) {
case FieldSynchronization::kNone:
break;
case FieldSynchronization::kRelaxed:
hdr_ << ", RelaxedLoadTag";
break;
case FieldSynchronization::kAcquireRelease:
hdr_ << ", AcquireLoadTag";
break;
}
hdr_ << ") const;\n";
}
hdr_ << " inline void set_" << name << "(" << (indexed ? "int i, " : "")
<< type_name << " value"
<< (can_contain_heap_objects
<< type_name << " value";
switch (class_field.write_synchronization) {
case FieldSynchronization::kNone:
break;
case FieldSynchronization::kRelaxed:
hdr_ << ", RelaxedStoreTag";
break;
case FieldSynchronization::kAcquireRelease:
hdr_ << ", ReleaseStoreTag";
break;
}
hdr_ << (can_contain_heap_objects
? ", WriteBarrierMode mode = UPDATE_WRITE_BARRIER"
: "")
<< ");\n\n";
......@@ -4268,10 +4301,32 @@ void CppClassGenerator::GenerateFieldAccessors(
if (can_contain_heap_objects) {
inl_ << "template <class D, class P>\n";
inl_ << type_name << " " << gen_name_ << "<D, P>::" << name << "("
<< (indexed ? "int i" : "") << ") const {\n";
<< (indexed ? "int i" : "");
switch (class_field.read_synchronization) {
case FieldSynchronization::kNone:
break;
case FieldSynchronization::kRelaxed:
inl_ << (indexed ? ", RelaxedLoadTag" : "RelaxedLoadTag");
break;
case FieldSynchronization::kAcquireRelease:
inl_ << (indexed ? ", AcquireLoadTag" : "AcquireLoadTag");
break;
}
inl_ << ") const {\n";
inl_ << " PtrComprCageBase cage_base = GetPtrComprCageBase(*this);\n";
inl_ << " return " << gen_name_ << "::" << name << "(cage_base"
<< (indexed ? ", i" : "") << ");\n";
<< (indexed ? ", i" : "");
switch (class_field.read_synchronization) {
case FieldSynchronization::kNone:
break;
case FieldSynchronization::kRelaxed:
inl_ << ", kRelaxedLoad";
break;
case FieldSynchronization::kAcquireRelease:
inl_ << ", kAcquireLoad";
break;
}
inl_ << ");\n";
inl_ << "}\n";
}
......@@ -4281,6 +4336,18 @@ void CppClassGenerator::GenerateFieldAccessors(
if (can_contain_heap_objects) inl_ << "PtrComprCageBase cage_base";
if (can_contain_heap_objects && indexed) inl_ << ", ";
if (indexed) inl_ << "int i";
switch (class_field.read_synchronization) {
case FieldSynchronization::kNone:
break;
case FieldSynchronization::kRelaxed:
inl_ << ((can_contain_heap_objects || indexed) ? ", RelaxedLoadTag"
: "RelaxedLoadTag");
break;
case FieldSynchronization::kAcquireRelease:
inl_ << ((can_contain_heap_objects || indexed) ? ", AcquireLoadTag"
: "AcquireLoadTag");
break;
}
inl_ << ") const {\n";
inl_ << " " << type_name << " value;\n";
......@@ -4295,6 +4362,16 @@ void CppClassGenerator::GenerateFieldAccessors(
inl_ << "int i, ";
}
inl_ << type_name << " value";
switch (class_field.write_synchronization) {
case FieldSynchronization::kNone:
break;
case FieldSynchronization::kRelaxed:
inl_ << ", RelaxedStoreTag";
break;
case FieldSynchronization::kAcquireRelease:
inl_ << ", ReleaseStoreTag";
break;
}
if (can_contain_heap_objects) {
inl_ << ", WriteBarrierMode mode";
}
......@@ -4368,10 +4445,10 @@ void CppClassGenerator::EmitLoadFieldStatement(
if (!field_type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
if (class_field.read_synchronization ==
FieldSynchronization::kAcquireRelease) {
ReportError("Torque doesn't support @acquireRead on untagged data");
ReportError("Torque doesn't support @cppAcquireRead on untagged data");
} else if (class_field.read_synchronization ==
FieldSynchronization::kRelaxed) {
ReportError("Torque doesn't support @relaxedRead on untagged data");
ReportError("Torque doesn't support @cppRelaxedRead on untagged data");
}
inl_ << "this->template ReadField<" << type_name << ">(" << offset
<< ");\n";
......@@ -4665,11 +4742,33 @@ void GeneratePrintDefinitionsForClass(std::ostream& impl, const ClassType* type,
// TODO(turbofan): Print struct fields too.
impl << "\" <struct field printing still unimplemented>\";\n";
} else {
impl << "this->" << f.name_and_type.name << "();\n";
impl << "this->" << f.name_and_type.name;
switch (f.read_synchronization) {
case FieldSynchronization::kNone:
impl << "();\n";
break;
case FieldSynchronization::kRelaxed:
impl << "(kRelaxedLoad);\n";
break;
case FieldSynchronization::kAcquireRelease:
impl << "(kAcquireLoad);\n";
break;
}
}
} else {
impl << " os << \"\\n - " << f.name_and_type.name << ": \" << "
<< "Brief(this->" << f.name_and_type.name << "());\n";
<< "Brief(this->" << f.name_and_type.name;
switch (f.read_synchronization) {
case FieldSynchronization::kNone:
impl << "());\n";
break;
case FieldSynchronization::kRelaxed:
impl << "(kRelaxedLoad));\n";
break;
case FieldSynchronization::kAcquireRelease:
impl << "(kAcquireLoad));\n";
break;
}
}
}
}
......
......@@ -1954,22 +1954,23 @@ base::Optional<ParseResult> MakeAnnotation(ParseResultIterator* child_results) {
}
base::Optional<ParseResult> MakeClassField(ParseResultIterator* child_results) {
AnnotationSet annotations(child_results,
{ANNOTATION_NO_VERIFIER, ANNOTATION_RELAXED_WRITE,
ANNOTATION_RELAXED_READ, ANNOTATION_RELEASE_WRITE,
ANNOTATION_ACQUIRE_READ},
{ANNOTATION_IF, ANNOTATION_IFNOT});
AnnotationSet annotations(
child_results,
{ANNOTATION_NO_VERIFIER, ANNOTATION_CPP_RELAXED_STORE,
ANNOTATION_CPP_RELAXED_LOAD, ANNOTATION_CPP_RELEASE_STORE,
ANNOTATION_CPP_ACQUIRE_LOAD},
{ANNOTATION_IF, ANNOTATION_IFNOT});
bool generate_verify = !annotations.Contains(ANNOTATION_NO_VERIFIER);
FieldSynchronization write_synchronization = FieldSynchronization::kNone;
if (annotations.Contains(ANNOTATION_RELEASE_WRITE)) {
if (annotations.Contains(ANNOTATION_CPP_RELEASE_STORE)) {
write_synchronization = FieldSynchronization::kAcquireRelease;
} else if (annotations.Contains(ANNOTATION_RELAXED_WRITE)) {
} else if (annotations.Contains(ANNOTATION_CPP_RELAXED_STORE)) {
write_synchronization = FieldSynchronization::kRelaxed;
}
FieldSynchronization read_synchronization = FieldSynchronization::kNone;
if (annotations.Contains(ANNOTATION_ACQUIRE_READ)) {
if (annotations.Contains(ANNOTATION_CPP_ACQUIRE_LOAD)) {
read_synchronization = FieldSynchronization::kAcquireRelease;
} else if (annotations.Contains(ANNOTATION_RELAXED_READ)) {
} else if (annotations.Contains(ANNOTATION_CPP_RELAXED_LOAD)) {
read_synchronization = FieldSynchronization::kRelaxed;
}
std::vector<ConditionalAnnotation> conditions;
......
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