Revert "Do not allocate feedback vectors and feedback metadata in lite mode"

This reverts commit 62e86b88e5.

Reason for revert: Fails on arm sim lite debug: https://ci.chromium.org/p/v8/builders/luci.v8.ci/V8%20Linux%20-%20arm%20-%20sim%20-%20lite%20-%20debug/1075

Original change's description:
> Do not allocate feedback vectors and feedback metadata in lite mode
> 
> Don't allocate feedback vectors and feedback metadata in lite mode.
> Also updates to skip tests that require feedback vectors.
> 
> Bug: v8:8394
> Change-Id: I22c64a32c44bb8f25fb09003d6e9fc5a04e84f8a
> Reviewed-on: https://chromium-review.googlesource.com/c/1378173
> Commit-Queue: Mythri Alle <mythria@chromium.org>
> Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
> Reviewed-by: Yang Guo <yangguo@chromium.org>
> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#58351}

TBR=rmcilroy@chromium.org,yangguo@chromium.org,mlippautz@chromium.org,mythria@chromium.org

Change-Id: I88fd37ea4e21aa2cc81eceb87ddb35c23224beae
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: v8:8394
Reviewed-on: https://chromium-review.googlesource.com/c/1384087
Reviewed-by: Clemens Hammacher <clemensh@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58355}
This commit is contained in:
Clemens Hammacher 2018-12-19 11:31:17 +00:00 committed by Commit Bot
parent 4ee489b8b0
commit 9efa28bf00
19 changed files with 55 additions and 183 deletions

View File

@ -106,7 +106,7 @@ namespace internal {
V(kNotEnoughVirtualRegistersRegalloc, \
"Not enough virtual registers (regalloc)") \
V(kOptimizationDisabled, "Optimization disabled") \
V(kNeverOptimize, "Optimization is always disabled")
V(kOptimizationDisabledForTest, "Optimization disabled for test")
#define ERROR_MESSAGES_CONSTANTS(C, T) C,
enum class BailoutReason : uint8_t {

View File

@ -356,18 +356,12 @@ void InstallUnoptimizedCode(UnoptimizedCompilationInfo* compilation_info,
DCHECK(!compilation_info->has_asm_wasm_data());
DCHECK(!shared_info->HasFeedbackMetadata());
Handle<FeedbackMetadata> feedback_metadata = FeedbackMetadata::New(
isolate, compilation_info->feedback_vector_spec());
InstallBytecodeArray(compilation_info->bytecode_array(), shared_info,
parse_info, isolate);
if (FLAG_lite_mode) {
// Clear the feedback metadata field. In lite mode we don't need feedback
// metadata since we never allocate feedback vectors.
shared_info->set_raw_outer_scope_info_or_feedback_metadata(
HeapObjectPtr::cast(ReadOnlyRoots(isolate).undefined_value()));
} else {
Handle<FeedbackMetadata> feedback_metadata = FeedbackMetadata::New(
isolate, compilation_info->feedback_vector_spec());
shared_info->set_feedback_metadata(*feedback_metadata);
}
shared_info->set_feedback_metadata(*feedback_metadata);
} else {
DCHECK(compilation_info->has_asm_wasm_data());
shared_info->set_asm_wasm_data(*compilation_info->asm_wasm_data());
@ -745,11 +739,6 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function,
function->ClearOptimizationMarker();
}
if (shared->optimization_disabled() &&
shared->disable_optimization_reason() == BailoutReason::kNeverOptimize) {
return MaybeHandle<Code>();
}
if (isolate->debug()->needs_check_on_function_call()) {
// Do not optimize when debugger needs to hook into every call.
return MaybeHandle<Code>();
@ -792,6 +781,15 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function,
return MaybeHandle<Code>();
}
// Do not use TurboFan when %NeverOptimizeFunction was applied.
if (shared->optimization_disabled() &&
shared->disable_optimization_reason() ==
BailoutReason::kOptimizationDisabledForTest) {
compilation_info->AbortOptimization(
BailoutReason::kOptimizationDisabledForTest);
return MaybeHandle<Code>();
}
// Do not use TurboFan if optimization is disabled or function doesn't pass
// turbo_filter.
if (!FLAG_opt || !shared->PassesFilter(FLAG_turbo_filter)) {

View File

@ -46,8 +46,7 @@ std::unique_ptr<TypeProfile> TypeProfile::Collect(Isolate* isolate) {
if (script != info->script()) {
continue;
}
if (!info->HasFeedbackMetadata() ||
info->feedback_metadata()->is_empty() ||
if (info->feedback_metadata()->is_empty() ||
!info->feedback_metadata()->HasTypeProfileSlot()) {
continue;
}

View File

@ -3664,12 +3664,6 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
share->set_raw_function_token_offset(0);
// All flags default to false or 0.
share->set_flags(0);
// For lite mode disable optimization.
if (FLAG_lite_mode) {
share->set_flags(
SharedFunctionInfo::DisabledOptimizationReasonBits::encode(
BailoutReason::kNeverOptimize));
}
share->CalculateConstructAsBuiltin();
share->set_kind(kind);

View File

@ -1102,7 +1102,8 @@ void SharedFunctionInfo::SharedFunctionInfoVerify(Isolate* isolate) {
CHECK(!HasFeedbackMetadata());
CHECK(outer_scope_info()->IsScopeInfo() ||
outer_scope_info()->IsTheHole(isolate));
} else if (HasBytecodeArray() && HasFeedbackMetadata()) {
} else if (HasBytecodeArray()) {
CHECK(HasFeedbackMetadata());
CHECK(feedback_metadata()->IsFeedbackMetadata());
}

View File

@ -12714,9 +12714,7 @@ void JSFunction::MarkForOptimization(ConcurrencyMode mode) {
void JSFunction::EnsureFeedbackVector(Handle<JSFunction> function) {
Isolate* const isolate = function->GetIsolate();
DCHECK(function->shared()->is_compiled());
DCHECK(FLAG_lite_mode || function->shared()->HasFeedbackMetadata());
if (!function->has_feedback_vector() &&
function->shared()->HasFeedbackMetadata()) {
if (!function->has_feedback_vector()) {
Handle<SharedFunctionInfo> shared(function->shared(), isolate);
if (!shared->HasAsmWasmData()) {
DCHECK(function->shared()->HasBytecodeArray());

View File

@ -233,12 +233,6 @@ RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) {
return ReadOnlyRoots(isolate).undefined_value();
}
if (function->shared()->optimization_disabled() &&
function->shared()->disable_optimization_reason() ==
BailoutReason::kNeverOptimize) {
return ReadOnlyRoots(isolate).undefined_value();
}
// If the function is already optimized, just return.
if (function->IsOptimized() || function->shared()->HasAsmWasmData()) {
return ReadOnlyRoots(isolate).undefined_value();
@ -302,12 +296,6 @@ RUNTIME_FUNCTION(Runtime_OptimizeOsr) {
// If the function is already optimized, just return.
if (function->IsOptimized()) return ReadOnlyRoots(isolate).undefined_value();
if (function->shared()->optimization_disabled() &&
function->shared()->disable_optimization_reason() ==
BailoutReason::kNeverOptimize) {
return ReadOnlyRoots(isolate).undefined_value();
}
// Ensure that the function is marked for non-concurrent optimization, so that
// subsequent runs don't also optimize.
if (!function->HasOptimizedCode()) {
@ -340,7 +328,8 @@ RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) {
return ReadOnlyRoots(isolate).undefined_value();
}
Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
function->shared()->DisableOptimization(BailoutReason::kNeverOptimize);
function->shared()->DisableOptimization(
BailoutReason::kOptimizationDisabledForTest);
return ReadOnlyRoots(isolate).undefined_value();
}

View File

@ -34,7 +34,7 @@
# This test is so detailed in it's look at the literals array, I can't
# maintain it until the CL is done.
'test-heap-profiler/AllocationSitesAreVisible': [FAIL, ['lite_mode == True', SKIP]],
'test-heap-profiler/AllocationSitesAreVisible': [FAIL],
# These tests always fail. They are here to test test.py. If
# they don't fail then test.py has failed.
@ -464,33 +464,4 @@
'test-unwinder/*': [SKIP]
}],
##############################################################################
['lite_mode == True', {
# TODO(8394): First execution events don't work in lite_mode. Enable this after
# we fix the lite mode to track the first execution.
'test-log/LogFunctionEvents': [SKIP],
# Skip compiler tests that need optimizer to be enabled.
'test-run-intrinsics/*': [SKIP],
'test-run-jsbranches/*': [SKIP],
'test-run-jscalls/*': [SKIP],
'test-run-jsexceptions/*': [SKIP],
'test-run-jsobjects/*': [SKIP],
'test-run-jsops/*': [SKIP],
'test-run-load-store/*': [SKIP],
'test-run-machops/*': [SKIP],
'test-run-native-calls/*': [SKIP],
'test-run-retpoline/*': [SKIP],
'test-run-stackcheck/*': [SKIP],
'test-run-tail-calls/*': [SKIP],
'test-run-unwinding-info/*': [SKIP],
'test-run-variables/*': [SKIP],
'test-run-bytecode-graph-builder/*': [SKIP],
'test-run-deopt/*': [SKIP],
'test-js-context-specialization/*': [SKIP],
'test-code-assembler/*': [SKIP],
'test-code-stub-assembler/*': [SKIP],
}],
]

View File

@ -3250,7 +3250,6 @@ static void CheckVectorIC(Handle<JSFunction> f, int slot_index,
}
TEST(IncrementalMarkingPreservesMonomorphicConstructor) {
if (FLAG_lite_mode) return;
if (!FLAG_incremental_marking) return;
if (FLAG_always_opt) return;
CcTest::InitializeVM();
@ -3814,8 +3813,6 @@ void CheckNumberOfAllocations(Heap* heap, const char* source,
}
TEST(AllocationSiteCreation) {
// No feedback vectors and hence no allocation sites.
if (FLAG_lite_mode) return;
FLAG_always_opt = false;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
@ -4278,7 +4275,6 @@ static void ClearWeakIC(
TEST(WeakFunctionInConstructor) {
if (FLAG_lite_mode) return;
if (FLAG_always_opt) return;
FLAG_stress_compaction = false;
FLAG_stress_incremental_marking = false;

View File

@ -30,10 +30,8 @@ InterpreterTester::InterpreterTester(
InterpreterTester::InterpreterTester(
Isolate* isolate, Handle<BytecodeArray> bytecode,
MaybeHandle<FeedbackMetadata> feedback_metadata, const char* filter)
: InterpreterTester(
isolate, nullptr, bytecode,
FLAG_lite_mode ? MaybeHandle<FeedbackMetadata>() : feedback_metadata,
filter) {}
: InterpreterTester(isolate, nullptr, bytecode, feedback_metadata, filter) {
}
InterpreterTester::InterpreterTester(Isolate* isolate, const char* source,
const char* filter)

View File

@ -89,8 +89,6 @@ class InterpreterTester {
return RegisterList(first_reg_index, register_count);
}
inline bool HasFeedbackMetadata() { return !feedback_metadata_.is_null(); }
private:
Isolate* isolate_;
const char* source_;
@ -124,7 +122,7 @@ class InterpreterTester {
if (!bytecode_.is_null()) {
function->shared()->set_function_data(*bytecode_.ToHandleChecked());
}
if (HasFeedbackMetadata()) {
if (!feedback_metadata_.is_null()) {
function->set_raw_feedback_cell(isolate_->heap()->many_closures_cell());
// Set the raw feedback metadata to circumvent checks that we are not
// overwriting existing metadata.

View File

@ -422,11 +422,9 @@ TEST(InterpreterBinaryOpsBigInt) {
auto callable = tester.GetCallable<>();
Handle<Object> return_value = callable().ToHandleChecked();
CHECK(return_value->IsBigInt());
if (tester.HasFeedbackMetadata()) {
MaybeObject feedback = callable.vector()->Get(slot);
CHECK(feedback->IsSmi());
CHECK_EQ(BinaryOperationFeedback::kBigInt, feedback->ToSmi().value());
}
MaybeObject feedback = callable.vector()->Get(slot);
CHECK(feedback->IsSmi());
CHECK_EQ(BinaryOperationFeedback::kBigInt, feedback->ToSmi().value());
}
}
}
@ -544,11 +542,9 @@ TEST(InterpreterStringAdd) {
Handle<Object> return_value = callable().ToHandleChecked();
CHECK(return_value->SameValue(*test_cases[i].expected_value));
if (tester.HasFeedbackMetadata()) {
MaybeObject feedback = callable.vector()->Get(slot);
CHECK(feedback->IsSmi());
CHECK_EQ(test_cases[i].expected_feedback, feedback->ToSmi().value());
}
MaybeObject feedback = callable.vector()->Get(slot);
CHECK(feedback->IsSmi());
CHECK_EQ(test_cases[i].expected_feedback, feedback->ToSmi().value());
}
}
@ -627,8 +623,6 @@ TEST(InterpreterParameter8) {
}
TEST(InterpreterBinaryOpTypeFeedback) {
if (FLAG_lite_mode) return;
HandleAndZoneScope handles;
i::Isolate* isolate = handles.main_isolate();
Zone* zone = handles.main_zone();
@ -761,8 +755,6 @@ TEST(InterpreterBinaryOpTypeFeedback) {
}
TEST(InterpreterBinaryOpSmiTypeFeedback) {
if (FLAG_lite_mode) return;
HandleAndZoneScope handles;
i::Isolate* isolate = handles.main_isolate();
Zone* zone = handles.main_zone();
@ -869,8 +861,6 @@ TEST(InterpreterBinaryOpSmiTypeFeedback) {
}
TEST(InterpreterUnaryOpFeedback) {
if (FLAG_lite_mode) return;
HandleAndZoneScope handles;
i::Isolate* isolate = handles.main_isolate();
Zone* zone = handles.main_zone();
@ -957,8 +947,6 @@ TEST(InterpreterUnaryOpFeedback) {
}
TEST(InterpreterBitwiseTypeFeedback) {
if (FLAG_lite_mode) return;
HandleAndZoneScope handles;
i::Isolate* isolate = handles.main_isolate();
Zone* zone = handles.main_zone();
@ -1826,12 +1814,10 @@ TEST(InterpreterSmiComparisons) {
CHECK(return_value->IsBoolean());
CHECK_EQ(return_value->BooleanValue(isolate),
CompareC(comparison, inputs[i], inputs[j]));
if (tester.HasFeedbackMetadata()) {
MaybeObject feedback = callable.vector()->Get(slot);
CHECK(feedback->IsSmi());
CHECK_EQ(CompareOperationFeedback::kSignedSmall,
feedback->ToSmi().value());
}
MaybeObject feedback = callable.vector()->Get(slot);
CHECK(feedback->IsSmi());
CHECK_EQ(CompareOperationFeedback::kSignedSmall,
feedback->ToSmi().value());
}
}
}
@ -1877,12 +1863,9 @@ TEST(InterpreterHeapNumberComparisons) {
CHECK(return_value->IsBoolean());
CHECK_EQ(return_value->BooleanValue(isolate),
CompareC(comparison, inputs[i], inputs[j]));
if (tester.HasFeedbackMetadata()) {
MaybeObject feedback = callable.vector()->Get(slot);
CHECK(feedback->IsSmi());
CHECK_EQ(CompareOperationFeedback::kNumber,
feedback->ToSmi().value());
}
MaybeObject feedback = callable.vector()->Get(slot);
CHECK(feedback->IsSmi());
CHECK_EQ(CompareOperationFeedback::kNumber, feedback->ToSmi().value());
}
}
}
@ -1922,12 +1905,9 @@ TEST(InterpreterBigIntComparisons) {
auto callable = tester.GetCallable<>();
Handle<Object> return_value = callable().ToHandleChecked();
CHECK(return_value->IsBoolean());
if (tester.HasFeedbackMetadata()) {
MaybeObject feedback = callable.vector()->Get(slot);
CHECK(feedback->IsSmi());
CHECK_EQ(CompareOperationFeedback::kBigInt,
feedback->ToSmi().value());
}
MaybeObject feedback = callable.vector()->Get(slot);
CHECK(feedback->IsSmi());
CHECK_EQ(CompareOperationFeedback::kBigInt, feedback->ToSmi().value());
}
}
}
@ -1972,15 +1952,13 @@ TEST(InterpreterStringComparisons) {
CHECK(return_value->IsBoolean());
CHECK_EQ(return_value->BooleanValue(isolate),
CompareC(comparison, inputs[i], inputs[j]));
if (tester.HasFeedbackMetadata()) {
MaybeObject feedback = callable.vector()->Get(slot);
CHECK(feedback->IsSmi());
int const expected_feedback =
Token::IsOrderedRelationalCompareOp(comparison)
? CompareOperationFeedback::kString
: CompareOperationFeedback::kInternalizedString;
CHECK_EQ(expected_feedback, feedback->ToSmi().value());
}
MaybeObject feedback = callable.vector()->Get(slot);
CHECK(feedback->IsSmi());
int const expected_feedback =
Token::IsOrderedRelationalCompareOp(comparison)
? CompareOperationFeedback::kString
: CompareOperationFeedback::kInternalizedString;
CHECK_EQ(expected_feedback, feedback->ToSmi().value());
}
}
}
@ -2085,13 +2063,10 @@ TEST(InterpreterMixedComparisons) {
CHECK(return_value->IsBoolean());
CHECK_EQ(return_value->BooleanValue(isolate),
CompareC(comparison, lhs, rhs, true));
if (tester.HasFeedbackMetadata()) {
MaybeObject feedback = callable.vector()->Get(slot);
CHECK(feedback->IsSmi());
// Comparison with a number and string collects kAny feedback.
CHECK_EQ(CompareOperationFeedback::kAny,
feedback->ToSmi().value());
}
MaybeObject feedback = callable.vector()->Get(slot);
CHECK(feedback->IsSmi());
// Comparison with a number and string collects kAny feedback.
CHECK_EQ(CompareOperationFeedback::kAny, feedback->ToSmi().value());
}
}
}

View File

@ -338,7 +338,7 @@ TEST(FeedbackVectorPreservedAcrossRecompiles) {
TEST(FeedbackVectorUnaffectedByScopeChanges) {
if (i::FLAG_always_opt || !i::FLAG_lazy || i::FLAG_lite_mode) {
if (i::FLAG_always_opt || !i::FLAG_lazy) {
return;
}
CcTest::InitializeVM();
@ -772,7 +772,6 @@ TEST(CompileFunctionInContextFunctionToString) {
}
TEST(InvocationCount) {
if (FLAG_lite_mode) return;
FLAG_allow_natives_syntax = true;
FLAG_always_opt = false;
CcTest::InitializeVM();

View File

@ -4031,8 +4031,6 @@ UNINITIALIZED_TEST(DebugSetOutOfMemoryListener) {
}
TEST(DebugCoverage) {
// Coverage needs feedback vectors.
if (i::FLAG_lite_mode) return;
i::FLAG_always_opt = false;
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
@ -4086,8 +4084,6 @@ v8::debug::Coverage::ScriptData GetScriptDataAndDeleteCoverage(
} // namespace
TEST(DebugCoverageWithCoverageOutOfScope) {
// Coverage needs feedback vectors.
if (i::FLAG_lite_mode) return;
i::FLAG_always_opt = false;
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
@ -4157,8 +4153,6 @@ v8::debug::Coverage::FunctionData GetFunctionDataAndDeleteCoverage(
} // namespace
TEST(DebugCoverageWithScriptDataOutOfScope) {
// Coverage needs feedback vectors.
if (i::FLAG_lite_mode) return;
i::FLAG_always_opt = false;
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();

View File

@ -2447,8 +2447,6 @@ TEST(ManyLocalsInSharedContext) {
TEST(AllocationSitesAreVisible) {
if (i::FLAG_lite_mode) return;
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate);
@ -2692,9 +2690,7 @@ TEST(TrackHeapAllocationsWithInlining) {
const char* names[] = {"", "start", "f_0_0"};
AllocationTraceNode* node = FindNode(tracker, ArrayVector(names));
CHECK(node);
// In lite mode, there is feedback and feedback metadata.
unsigned int num_nodes = (i::FLAG_lite_mode) ? 6 : 8;
CHECK_GE(node->allocation_count(), num_nodes);
CHECK_GE(node->allocation_count(), 8u);
CHECK_GE(node->allocation_size(), 4 * node->allocation_count());
heap_profiler->StopTrackingHeapObjects();
}

View File

@ -752,8 +752,7 @@ TEST(BailoutReason) {
current = PickChild(current, "Debugger");
CHECK(const_cast<v8::CpuProfileNode*>(current));
CHECK(
!strcmp("Optimization is always disabled", current->GetBailoutReason()));
CHECK(!strcmp("Optimization disabled for test", current->GetBailoutReason()));
#endif // V8_LITE_MODE
}

View File

@ -2185,8 +2185,7 @@ static bool toplevel_test_code_event_found = false;
static void SerializerCodeEventListener(const v8::JitCodeEvent* event) {
if (event->type == v8::JitCodeEvent::CODE_ADDED &&
(memcmp(event->name.str, "Script:~test", 12) == 0 ||
memcmp(event->name.str, "Script:test", 11) == 0)) {
memcmp(event->name.str, "Script:~test", 12) == 0) {
toplevel_test_code_event_found = true;
}
}

View File

@ -34,16 +34,6 @@
'debugger/evaluate-on-call-frame-in-module': [PASS, FAIL],
}], # variant != default
['lite_mode == True', {
# Lite mode does not allocate feedback vector.
'type-profiler/type-profile-start-stop': [SKIP],
'type-profiler/type-profile': [SKIP],
'type-profiler/type-profile-with-to-string-tag': [SKIP],
'type-profiler/type-profile-with-classes': [SKIP],
'type-profiler/type-profile-disable': [SKIP]
}], # 'lite_mode == True'
##############################################################################
['(arch == arm or arch == arm64) and simulator_run', {
# Slow tests: https://crbug.com/v8/7783

View File

@ -321,28 +321,6 @@
'regress/regress-crbug-762472': [SKIP],
}], # 'gc_stress == True'
##############################################################################
['lite_mode == True', {
# Skip tests not suitable for lite_mode.
# TODO(8596): We cache the templates in the feedback vector. In lite mode
# without feedback vectors we need to implement some other mechanism to cache
# them. Enable this test after fixing it.
'es6/templates': [SKIP],
# code coverage needs feedback vectors
'code-coverage-ad-hoc': [SKIP],
'code-coverage-class-fields': [SKIP],
'code-coverage-block-noopt': [SKIP],
'code-coverage-block': [SKIP],
'code-coverage-precise': [SKIP],
# Needs feedback vector - tests for allocation sites
'array-constructor-feedback': [SKIP],
'regress/regress-trap-allocation-memento': [SKIP],
'regress/regress-4121': [SKIP],
}], # 'lite_mode == True'
##############################################################################
['byteorder == big', {
# Emscripten requires little-endian, skip all tests on big endian platforms.