Commit 1e921dae authored by Santiago Aboy Solanes's avatar Santiago Aboy Solanes Committed by V8 LUCI CQ

[compiler] Mark FeedbackVector::invocation_count as relaxed

Bug: v8:7790, chromium:1236962
Change-Id: Idd84f7e154cc8977db7aef14d6b999ac929784dd
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3075363
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#76223}
parent 9740901a
...@@ -2237,8 +2237,6 @@ BytecodeArrayRef::incoming_new_target_or_generator_register() const { ...@@ -2237,8 +2237,6 @@ BytecodeArrayRef::incoming_new_target_or_generator_register() const {
return object()->incoming_new_target_or_generator_register(); return object()->incoming_new_target_or_generator_register();
} }
HEAP_ACCESSOR_C(FeedbackVector, double, invocation_count)
BIMODAL_ACCESSOR(HeapObject, Map, map) BIMODAL_ACCESSOR(HeapObject, Map, map)
HEAP_ACCESSOR_C(HeapNumber, double, value) HEAP_ACCESSOR_C(HeapNumber, double, value)
......
...@@ -649,7 +649,6 @@ class FeedbackVectorRef : public HeapObjectRef { ...@@ -649,7 +649,6 @@ class FeedbackVectorRef : public HeapObjectRef {
Handle<FeedbackVector> object() const; Handle<FeedbackVector> object() const;
SharedFunctionInfoRef shared_function_info() const; SharedFunctionInfoRef shared_function_info() const;
double invocation_count() const;
FeedbackCellRef GetClosureFeedbackCell(int index) const; FeedbackCellRef GetClosureFeedbackCell(int index) const;
}; };
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "src/ast/ast-source-ranges.h" #include "src/ast/ast-source-ranges.h"
#include "src/ast/ast.h" #include "src/ast/ast.h"
#include "src/base/hashmap.h" #include "src/base/hashmap.h"
#include "src/common/globals.h"
#include "src/debug/debug.h" #include "src/debug/debug.h"
#include "src/deoptimizer/deoptimizer.h" #include "src/deoptimizer/deoptimizer.h"
#include "src/execution/frames-inl.h" #include "src/execution/frames-inl.h"
...@@ -516,7 +517,7 @@ void CollectAndMaybeResetCounts(Isolate* isolate, ...@@ -516,7 +517,7 @@ void CollectAndMaybeResetCounts(Isolate* isolate,
SharedFunctionInfo shared = vector.shared_function_info(); SharedFunctionInfo shared = vector.shared_function_info();
DCHECK(shared.IsSubjectToDebugging()); DCHECK(shared.IsSubjectToDebugging());
uint32_t count = static_cast<uint32_t>(vector.invocation_count()); uint32_t count = static_cast<uint32_t>(vector.invocation_count());
if (reset_count) vector.clear_invocation_count(); if (reset_count) vector.clear_invocation_count(kRelaxedStore);
counter_map->Add(shared, count); counter_map->Add(shared, count);
} }
break; break;
...@@ -793,7 +794,7 @@ void Coverage::SelectMode(Isolate* isolate, debug::CoverageMode mode) { ...@@ -793,7 +794,7 @@ void Coverage::SelectMode(Isolate* isolate, debug::CoverageMode mode) {
shared.set_has_reported_binary_coverage(false); shared.set_has_reported_binary_coverage(false);
} else if (o.IsFeedbackVector()) { } else if (o.IsFeedbackVector()) {
// In any case, clear any collected invocation counts. // In any case, clear any collected invocation counts.
FeedbackVector::cast(o).clear_invocation_count(); FeedbackVector::cast(o).clear_invocation_count(kRelaxedStore);
} }
} }
} }
......
...@@ -30,7 +30,8 @@ ACCESSORS(AllocationSite, transition_info_or_boilerplate, Object, ...@@ -30,7 +30,8 @@ ACCESSORS(AllocationSite, transition_info_or_boilerplate, Object,
RELEASE_ACQUIRE_ACCESSORS(AllocationSite, transition_info_or_boilerplate, RELEASE_ACQUIRE_ACCESSORS(AllocationSite, transition_info_or_boilerplate,
Object, kTransitionInfoOrBoilerplateOffset) Object, kTransitionInfoOrBoilerplateOffset)
ACCESSORS(AllocationSite, nested_site, Object, kNestedSiteOffset) ACCESSORS(AllocationSite, nested_site, Object, kNestedSiteOffset)
RELAXED_INT32_ACCESSORS(AllocationSite, pretenure_data, kPretenureDataOffset) IMPLICIT_TAG_RELAXED_INT32_ACCESSORS(AllocationSite, pretenure_data,
kPretenureDataOffset)
INT32_ACCESSORS(AllocationSite, pretenure_create_count, INT32_ACCESSORS(AllocationSite, pretenure_create_count,
kPretenureCreateCountOffset) kPretenureCreateCountOffset)
ACCESSORS(AllocationSite, dependent_code, DependentCode, kDependentCodeOffset) ACCESSORS(AllocationSite, dependent_code, DependentCode, kDependentCodeOffset)
......
...@@ -800,8 +800,8 @@ bool Code::IsExecutable() { ...@@ -800,8 +800,8 @@ bool Code::IsExecutable() {
// concurrent marker. // concurrent marker.
STATIC_ASSERT(FIELD_SIZE(CodeDataContainer::kKindSpecificFlagsOffset) == STATIC_ASSERT(FIELD_SIZE(CodeDataContainer::kKindSpecificFlagsOffset) ==
kInt32Size); kInt32Size);
RELAXED_INT32_ACCESSORS(CodeDataContainer, kind_specific_flags, IMPLICIT_TAG_RELAXED_INT32_ACCESSORS(CodeDataContainer, kind_specific_flags,
kKindSpecificFlagsOffset) kKindSpecificFlagsOffset)
ACCESSORS_CHECKED(CodeDataContainer, raw_code, Object, kCodeOffset, ACCESSORS_CHECKED(CodeDataContainer, raw_code, Object, kCodeOffset,
V8_EXTERNAL_CODE_SPACE_BOOL) V8_EXTERNAL_CODE_SPACE_BOOL)
RELAXED_ACCESSORS_CHECKED(CodeDataContainer, raw_code, Object, kCodeOffset, RELAXED_ACCESSORS_CHECKED(CodeDataContainer, raw_code, Object, kCodeOffset,
......
...@@ -112,7 +112,12 @@ FeedbackMetadata FeedbackVector::metadata() const { ...@@ -112,7 +112,12 @@ FeedbackMetadata FeedbackVector::metadata() const {
return shared_function_info().feedback_metadata(); return shared_function_info().feedback_metadata();
} }
void FeedbackVector::clear_invocation_count() { set_invocation_count(0); } RELAXED_INT32_ACCESSORS(FeedbackVector, invocation_count,
kInvocationCountOffset)
void FeedbackVector::clear_invocation_count(RelaxedStoreTag tag) {
set_invocation_count(0, tag);
}
Code FeedbackVector::optimized_code() const { Code FeedbackVector::optimized_code() const {
MaybeObject slot = maybe_optimized_code(kAcquireLoad); MaybeObject slot = maybe_optimized_code(kAcquireLoad);
......
...@@ -1020,7 +1020,7 @@ CallFeedbackContent FeedbackNexus::GetCallFeedbackContent() { ...@@ -1020,7 +1020,7 @@ CallFeedbackContent FeedbackNexus::GetCallFeedbackContent() {
float FeedbackNexus::ComputeCallFrequency() { float FeedbackNexus::ComputeCallFrequency() {
DCHECK(IsCallICKind(kind())); DCHECK(IsCallICKind(kind()));
double const invocation_count = vector().invocation_count(); double const invocation_count = vector().invocation_count(kRelaxedLoad);
double const call_count = GetCallCount(); double const call_count = GetCallCount();
if (invocation_count == 0.0) { // Prevent division by 0. if (invocation_count == 0.0) { // Prevent division by 0.
return 0.0f; return 0.0f;
......
...@@ -219,7 +219,11 @@ class FeedbackVector ...@@ -219,7 +219,11 @@ class FeedbackVector
// Increment profiler ticks, saturating at the maximal value. // Increment profiler ticks, saturating at the maximal value.
void SaturatingIncrementProfilerTicks(); void SaturatingIncrementProfilerTicks();
inline void clear_invocation_count(); // Forward declare the non-atomic accessors.
using TorqueGeneratedFeedbackVector::invocation_count;
using TorqueGeneratedFeedbackVector::set_invocation_count;
DECL_RELAXED_INT32_ACCESSORS(invocation_count)
inline void clear_invocation_count(RelaxedStoreTag tag);
inline Code optimized_code() const; inline Code optimized_code() const;
inline bool has_optimized_code() const; inline bool has_optimized_code() const;
......
...@@ -17,11 +17,14 @@ ...@@ -17,11 +17,14 @@
#undef DECL_BOOLEAN_ACCESSORS #undef DECL_BOOLEAN_ACCESSORS
#undef DECL_INT_ACCESSORS #undef DECL_INT_ACCESSORS
#undef DECL_INT32_ACCESSORS #undef DECL_INT32_ACCESSORS
#undef DECL_RELAXED_INT32_ACCESSORS
#undef DECL_UINT16_ACCESSORS #undef DECL_UINT16_ACCESSORS
#undef DECL_INT16_ACCESSORS #undef DECL_INT16_ACCESSORS
#undef DECL_UINT8_ACCESSORS #undef DECL_UINT8_ACCESSORS
#undef DECL_GETTER #undef DECL_GETTER
#undef DEF_GETTER #undef DEF_GETTER
#undef DEF_RELAXED_GETTER
#undef DEF_ACQUIRE_GETTER
#undef DECL_SETTER #undef DECL_SETTER
#undef DECL_ACCESSORS #undef DECL_ACCESSORS
#undef DECL_ACCESSORS_LOAD_TAG #undef DECL_ACCESSORS_LOAD_TAG
...@@ -37,6 +40,7 @@ ...@@ -37,6 +40,7 @@
#undef CAST_ACCESSOR #undef CAST_ACCESSOR
#undef INT_ACCESSORS #undef INT_ACCESSORS
#undef INT32_ACCESSORS #undef INT32_ACCESSORS
#undef IMPLICIT_TAG_RELAXED_INT32_ACCESSORS
#undef RELAXED_INT32_ACCESSORS #undef RELAXED_INT32_ACCESSORS
#undef UINT16_ACCESSORS #undef UINT16_ACCESSORS
#undef UINT8_ACCESSORS #undef UINT8_ACCESSORS
...@@ -45,6 +49,9 @@ ...@@ -45,6 +49,9 @@
#undef ACCESSORS #undef ACCESSORS
#undef RENAME_TORQUE_ACCESSORS #undef RENAME_TORQUE_ACCESSORS
#undef RENAME_UINT16_TORQUE_ACCESSORS #undef RENAME_UINT16_TORQUE_ACCESSORS
#undef ACCESSORS_RELAXED_CHECKED2
#undef ACCESSORS_RELAXED_CHECKED
#undef ACCESSORS_RELAXED
#undef RELAXED_ACCESSORS_CHECKED2 #undef RELAXED_ACCESSORS_CHECKED2
#undef RELAXED_ACCESSORS_CHECKED #undef RELAXED_ACCESSORS_CHECKED
#undef RELAXED_ACCESSORS #undef RELAXED_ACCESSORS
......
...@@ -62,6 +62,10 @@ ...@@ -62,6 +62,10 @@
#define DECL_INT32_ACCESSORS(name) DECL_PRIMITIVE_ACCESSORS(name, int32_t) #define DECL_INT32_ACCESSORS(name) DECL_PRIMITIVE_ACCESSORS(name, int32_t)
#define DECL_RELAXED_INT32_ACCESSORS(name) \
inline int32_t name(RelaxedLoadTag) const; \
inline void set_##name(int32_t value, RelaxedStoreTag);
#define DECL_UINT16_ACCESSORS(name) \ #define DECL_UINT16_ACCESSORS(name) \
inline uint16_t name() const; \ inline uint16_t name() const; \
inline void set_##name(int value); inline void set_##name(int value);
...@@ -159,12 +163,21 @@ ...@@ -159,12 +163,21 @@
int32_t holder::name() const { return ReadField<int32_t>(offset); } \ int32_t holder::name() const { return ReadField<int32_t>(offset); } \
void holder::set_##name(int32_t value) { WriteField<int32_t>(offset, value); } void holder::set_##name(int32_t value) { WriteField<int32_t>(offset, value); }
#define RELAXED_INT32_ACCESSORS(holder, name, offset) \ // TODO(solanes): Use the non-implicit one, and change the uses to use the tag.
int32_t holder::name() const { \ #define IMPLICIT_TAG_RELAXED_INT32_ACCESSORS(holder, name, offset) \
return RELAXED_READ_INT32_FIELD(*this, offset); \ int32_t holder::name() const { \
} \ return RELAXED_READ_INT32_FIELD(*this, offset); \
void holder::set_##name(int32_t value) { \ } \
RELAXED_WRITE_INT32_FIELD(*this, offset, value); \ void holder::set_##name(int32_t value) { \
RELAXED_WRITE_INT32_FIELD(*this, offset, value); \
}
#define RELAXED_INT32_ACCESSORS(holder, name, offset) \
int32_t holder::name(RelaxedLoadTag) const { \
return RELAXED_READ_INT32_FIELD(*this, offset); \
} \
void holder::set_##name(int32_t value, RelaxedStoreTag) { \
RELAXED_WRITE_INT32_FIELD(*this, offset, value); \
} }
#define UINT16_ACCESSORS(holder, name, offset) \ #define UINT16_ACCESSORS(holder, name, offset) \
......
...@@ -128,7 +128,7 @@ RENAME_UINT16_TORQUE_ACCESSORS(SharedFunctionInfo, ...@@ -128,7 +128,7 @@ RENAME_UINT16_TORQUE_ACCESSORS(SharedFunctionInfo,
RENAME_UINT16_TORQUE_ACCESSORS(SharedFunctionInfo, raw_function_token_offset, RENAME_UINT16_TORQUE_ACCESSORS(SharedFunctionInfo, raw_function_token_offset,
function_token_offset) function_token_offset)
RELAXED_INT32_ACCESSORS(SharedFunctionInfo, flags, kFlagsOffset) IMPLICIT_TAG_RELAXED_INT32_ACCESSORS(SharedFunctionInfo, flags, kFlagsOffset)
UINT8_ACCESSORS(SharedFunctionInfo, flags2, kFlags2Offset) UINT8_ACCESSORS(SharedFunctionInfo, flags2, kFlags2Offset)
bool SharedFunctionInfo::HasSharedName() const { bool SharedFunctionInfo::HasSharedName() const {
......
...@@ -343,7 +343,7 @@ void BytecodeBudgetInterruptFromBytecode(Isolate* isolate, ...@@ -343,7 +343,7 @@ void BytecodeBudgetInterruptFromBytecode(Isolate* isolate,
// Also initialize the invocation count here. This is only really needed for // Also initialize the invocation count here. This is only really needed for
// OSR. When we OSR functions with lazy feedback allocation we want to have // OSR. When we OSR functions with lazy feedback allocation we want to have
// a non zero invocation count so we can inline functions. // a non zero invocation count so we can inline functions.
function->feedback_vector().set_invocation_count(1); function->feedback_vector().set_invocation_count(1, kRelaxedStore);
} }
if (CanCompileWithBaseline(isolate, function->shared()) && if (CanCompileWithBaseline(isolate, function->shared()) &&
!function->ActiveTierIsBaseline()) { !function->ActiveTierIsBaseline()) {
......
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --budget-for-feedback-vector-allocation=0 --interrupt-budget=1000
(function() {
Empty = function() {};
var FuncImpl = new Function();
Func = function() {
if (FuncImpl === undefined) {
try {
FuncImpl = new Function();
} catch (e) {
throw new Error('');
}
}
return FuncImpl();
};
})();
var object = {};
main = function(unused = true) {
var func = Func();
Empty(func & object.a & object.a & object.a & object.a !== 0, '');
Empty(func & object.a !== 0, '');
};
for (let i = 0; i < 40; i++) {
main();
}
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