From: machenbach Date: Mon, 27 Apr 2015 10:07:30 +0000 (-0700) Subject: Revert of [turbofan] Optimize loads from the global object in JSTypeFeedbackSpecializ... X-Git-Tag: upstream/4.7.83~2977 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fbf300802f0b2dd3dcaca92790709a28216be859;p=platform%2Fupstream%2Fv8.git Revert of [turbofan] Optimize loads from the global object in JSTypeFeedbackSpecializer. (patchset #10 id:180001 of https://codereview.chromium.org/1063513003/) Reason for revert: [sheriff] Breaks nosnap debug: http://build.chromium.org/p/client.v8/builders/V8%20Linux%20-%20nosnap%20-%20debug%20-%201/builds/156 Original issue's description: > [turbofan] Optimize loads from the global object in JSTypeFeedbackSpecializer. > > Uses lazy deoptimization and code dependencies to introduce loads > from property cells and also to promote globals to constants. > > R=mstarzinger@chromium.org > BUG= > > Committed: https://crrev.com/aae4a62d07e839455b1d0ad4fa512cc5d48a1a68 > Cr-Commit-Position: refs/heads/master@{#28057} TBR=mstarzinger@chromium.org,titzer@chromium.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG= Review URL: https://codereview.chromium.org/1084533003 Cr-Commit-Position: refs/heads/master@{#28063} --- diff --git a/src/compiler.cc b/src/compiler.cc index a803d32..38a6276 100644 --- a/src/compiler.cc +++ b/src/compiler.cc @@ -400,7 +400,6 @@ OptimizedCompileJob::Status OptimizedCompileJob::CreateGraph() { compiler::Pipeline pipeline(info()); pipeline.GenerateCode(); if (!info()->code().is_null()) { - info()->dependencies()->Commit(info()->code()); return SetLastStatus(SUCCEEDED); } } diff --git a/src/compiler/access-builder.cc b/src/compiler/access-builder.cc index 1462c48..9e5a0bb 100644 --- a/src/compiler/access-builder.cc +++ b/src/compiler/access-builder.cc @@ -88,13 +88,6 @@ FieldAccess AccessBuilder::ForStatsCounter() { // static -FieldAccess AccessBuilder::ForPropertyCellValue() { - return {kTaggedBase, PropertyCell::kValueOffset, Handle(), Type::Any(), - kMachAnyTagged}; -} - - -// static ElementAccess AccessBuilder::ForFixedArrayElement() { return {kTaggedBase, FixedArray::kHeaderSize, Type::Any(), kMachAnyTagged}; } diff --git a/src/compiler/access-builder.h b/src/compiler/access-builder.h index 4d28db1..76f1d8a 100644 --- a/src/compiler/access-builder.h +++ b/src/compiler/access-builder.h @@ -49,9 +49,6 @@ class AccessBuilder final : public AllStatic { // Provides access to the backing store of a StatsCounter. static FieldAccess ForStatsCounter(); - // Provides access to PropertyCell::value() field. - static FieldAccess ForPropertyCellValue(); - // Provides access to FixedArray elements. static ElementAccess ForFixedArrayElement(); diff --git a/src/compiler/js-type-feedback.cc b/src/compiler/js-type-feedback.cc index 749eeba..fa5e33f 100644 --- a/src/compiler/js-type-feedback.cc +++ b/src/compiler/js-type-feedback.cc @@ -8,7 +8,6 @@ #include "src/accessors.h" #include "src/ast.h" -#include "src/compiler.h" #include "src/type-info.h" #include "src/compiler/access-builder.h" @@ -79,18 +78,6 @@ Reduction JSTypeFeedbackSpecializer::Reduce(Node* node) { } -static void AddFieldAccessTypes(FieldAccess* access, - PropertyDetails property_details) { - if (property_details.representation().IsSmi()) { - access->type = Type::SignedSmall(); - access->machine_type = static_cast(kTypeInt32 | kRepTagged); - } else if (property_details.representation().IsDouble()) { - access->type = Type::Number(); - access->machine_type = kMachFloat64; - } -} - - static bool GetInObjectFieldAccess(LoadOrStore mode, Handle map, Handle name, FieldAccess* access) { access->base_is_tagged = kTaggedBase; @@ -122,18 +109,26 @@ static bool GetInObjectFieldAccess(LoadOrStore mode, Handle map, return false; } - // Transfer known types from property details. - AddFieldAccessTypes(access, property_details); - if (mode == STORE) { - if (property_details.IsReadOnly()) { - // TODO(turbofan): deopt, ignore or throw on readonly stores. + if (property_details.IsReadOnly()) return false; + if (is_smi) { + // TODO(turbofan): SMI stores. return false; } - if (is_smi || is_double) { - // TODO(turbofan): check type and deopt for SMI/double stores. + if (is_double) { + // TODO(turbofan): double stores. return false; } + } else { + // Check property details for loads. + if (is_smi) { + access->type = Type::SignedSmall(); + access->machine_type = static_cast(kTypeInt32 | kRepTagged); + } + if (is_double) { + access->type = Type::Number(); + access->machine_type = kMachFloat64; + } } int index = map->instance_descriptors()->GetFieldIndex(number); @@ -149,20 +144,8 @@ static bool GetInObjectFieldAccess(LoadOrStore mode, Handle map, } -static bool IsGlobalObject(Node* node) { - return NodeProperties::IsTyped(node) && - NodeProperties::GetBounds(node).upper->Is(Type::GlobalObject()); -} - - Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamed(Node* node) { DCHECK(node->opcode() == IrOpcode::kJSLoadNamed); - Node* receiver = node->InputAt(0); - if (IsGlobalObject(receiver)) { - return ReduceJSLoadNamedForGlobalVariable(node); - } - - if (!FLAG_turbo_deoptimization) return NoChange(); // TODO(titzer): deopt locations are wrong for property accesses if (!EAGER_DEOPT_LOCATIONS_FOR_PROPERTY_ACCESS_ARE_CORRECT) return NoChange(); @@ -175,6 +158,7 @@ Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamed(Node* node) { const LoadNamedParameters& p = LoadNamedParametersOf(node->op()); SmallMapList maps; Handle name = p.name().handle(); + Node* receiver = node->InputAt(0); Node* effect = NodeProperties::GetEffectInput(node); GatherReceiverTypes(receiver, effect, id, name, &maps); @@ -207,74 +191,6 @@ Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamed(Node* node) { } -Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamedForGlobalVariable( - Node* node) { - Handle name = - Handle::cast(LoadNamedParametersOf(node->op()).name().handle()); - // Try to optimize loads from the global object. - Handle constant_value = - jsgraph()->isolate()->factory()->GlobalConstantFor(name); - if (!constant_value.is_null()) { - // Always optimize global constants. - Node* constant = jsgraph()->Constant(constant_value); - NodeProperties::ReplaceWithValue(node, constant); - return Replace(constant); - } - - if (global_object_.is_null()) { - // Nothing else can be done if we don't have a global object. - return NoChange(); - } - - if (FLAG_turbo_deoptimization) { - // Handle lookups in the script context. - { - Handle script_contexts( - global_object_->native_context()->script_context_table()); - ScriptContextTable::LookupResult lookup; - if (ScriptContextTable::Lookup(script_contexts, name, &lookup)) { - // TODO(turbofan): introduce a LoadContext here. - return NoChange(); - } - } - - // Constant promotion or cell access requires lazy deoptimization support. - LookupIterator it(global_object_, name, LookupIterator::OWN); - - if (it.state() == LookupIterator::DATA) { - Handle cell = it.GetPropertyCell(); - dependencies_->AssumePropertyCell(cell); - - if (it.property_details().cell_type() == PropertyCellType::kConstant) { - // Constant promote the global's current value. - Handle constant_value(cell->value(), jsgraph()->isolate()); - if (constant_value->IsConsString()) { - constant_value = - String::Flatten(Handle::cast(constant_value)); - } - Node* constant = jsgraph()->Constant(constant_value); - NodeProperties::ReplaceWithValue(node, constant); - return Replace(constant); - } else { - // Load directly from the property cell. - FieldAccess access = AccessBuilder::ForPropertyCellValue(); - Node* control = NodeProperties::GetControlInput(node); - Node* load_field = graph()->NewNode( - simplified()->LoadField(access), jsgraph()->Constant(cell), - NodeProperties::GetEffectInput(node), control); - NodeProperties::ReplaceWithValue(node, load_field, load_field, control); - return Replace(load_field); - } - } - } else { - // TODO(turbofan): non-configurable properties on the global object - // should be loadable through a cell without deoptimization support. - } - - return NoChange(); -} - - Reduction JSTypeFeedbackSpecializer::ReduceJSLoadProperty(Node* node) { return NoChange(); } diff --git a/src/compiler/js-type-feedback.h b/src/compiler/js-type-feedback.h index 51faee3..e879b31 100644 --- a/src/compiler/js-type-feedback.h +++ b/src/compiler/js-type-feedback.h @@ -17,7 +17,6 @@ namespace internal { class TypeFeedbackOracle; class SmallMapList; -class CompilationDependencies; namespace compiler { @@ -51,15 +50,11 @@ class JSTypeFeedbackSpecializer : public Reducer { public: JSTypeFeedbackSpecializer(JSGraph* jsgraph, JSTypeFeedbackTable* js_type_feedback, - TypeFeedbackOracle* oracle, - Handle global_object, - CompilationDependencies* dependencies) + TypeFeedbackOracle* oracle) : jsgraph_(jsgraph), simplified_(jsgraph->graph()->zone()), js_type_feedback_(js_type_feedback), - oracle_(oracle), - global_object_(global_object), - dependencies_(dependencies) { + oracle_(oracle) { CHECK(js_type_feedback); } @@ -67,7 +62,6 @@ class JSTypeFeedbackSpecializer : public Reducer { // Visible for unit testing. Reduction ReduceJSLoadNamed(Node* node); - Reduction ReduceJSLoadNamedForGlobalVariable(Node* node); Reduction ReduceJSLoadProperty(Node* node); Reduction ReduceJSStoreNamed(Node* node); Reduction ReduceJSStoreProperty(Node* node); @@ -77,8 +71,6 @@ class JSTypeFeedbackSpecializer : public Reducer { SimplifiedOperatorBuilder simplified_; JSTypeFeedbackTable* js_type_feedback_; TypeFeedbackOracle* oracle_; - Handle global_object_; - CompilationDependencies* dependencies_; TypeFeedbackOracle* oracle() { return oracle_; } Graph* graph() { return jsgraph_->graph(); } diff --git a/src/compiler/pipeline.cc b/src/compiler/pipeline.cc index 2698c68..022b6b5 100644 --- a/src/compiler/pipeline.cc +++ b/src/compiler/pipeline.cc @@ -542,16 +542,8 @@ struct JSTypeFeedbackPhase { data->info()->unoptimized_code(), data->info()->feedback_vector(), native_context); GraphReducer graph_reducer(data->graph(), temp_zone); - Handle global_object = Handle::null(); - if (data->info()->has_global_object()) { - global_object = - Handle(data->info()->global_object(), data->isolate()); - } - // TODO(titzer): introduce a specialization mode/flags enum to control - // specializing to the global object here. - JSTypeFeedbackSpecializer specializer( - data->jsgraph(), data->js_type_feedback(), &oracle, global_object, - data->info()->dependencies()); + JSTypeFeedbackSpecializer specializer(data->jsgraph(), + data->js_type_feedback(), &oracle); AddReducer(data, &graph_reducer, &specializer); graph_reducer.ReduceGraph(); } diff --git a/test/cctest/compiler/test-run-jsexceptions.cc b/test/cctest/compiler/test-run-jsexceptions.cc index 2e2e10e..f06dc5f 100644 --- a/test/cctest/compiler/test-run-jsexceptions.cc +++ b/test/cctest/compiler/test-run-jsexceptions.cc @@ -13,10 +13,7 @@ TEST(Throw) { i::FLAG_turbo_exceptions = true; FunctionTester T("(function(a,b) { if (a) { throw b; } else { return b; }})"); -// TODO(mstarzinger) -#if 0 T.CheckThrows(T.true_value(), T.NewObject("new Error")); -#endif T.CheckCall(T.Val(23), T.false_value(), T.Val(23)); } @@ -56,14 +53,11 @@ TEST(ThrowMessageDirectly) { FunctionTester T(src); v8::Handle message; -// TODO(mstarzinger) -#if 0 message = T.CheckThrowsReturnMessage(T.false_value(), T.Val("Wat?")); CHECK(message->Get()->Equals(v8_str("Uncaught Error: Wat?"))); message = T.CheckThrowsReturnMessage(T.true_value(), T.Val("Kaboom!")); CHECK(message->Get()->Equals(v8_str("Uncaught Kaboom!"))); -#endif } @@ -80,14 +74,11 @@ TEST(ThrowMessageIndirectly) { FunctionTester T(src); v8::Handle message; -// TODO(mstarzinger) -#if 0 message = T.CheckThrowsReturnMessage(T.false_value(), T.Val("Wat?")); CHECK(message->Get()->Equals(v8_str("Uncaught Error: Wat?"))); message = T.CheckThrowsReturnMessage(T.true_value(), T.Val("Kaboom!")); CHECK(message->Get()->Equals(v8_str("Uncaught Kaboom!"))); -#endif } diff --git a/test/mjsunit/compiler/global-delete.js b/test/mjsunit/compiler/global-delete.js deleted file mode 100644 index c32fda6..0000000 --- a/test/mjsunit/compiler/global-delete.js +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2015 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: --allow-natives-syntax - -function test(expected, f) { - assertEquals(expected, f()); - assertEquals(expected, f()); - %OptimizeFunctionOnNextCall(f); - assertEquals(expected, f()); - assertEquals(expected, f()); -} - -function testThrows(f) { - assertThrows(f); - assertThrows(f); - %OptimizeFunctionOnNextCall(f); - assertThrows(f); - assertThrows(f); -} - -// --- Constant case. -a = 11; - -function f1() { return a; } -test(11, f1); - -delete a; - -testThrows(f1); - - -// --- SMI case. - -b = 11; -b = 12; -b = 13; - -function f2() { return b; } -test(13, f2); - -delete b; - -testThrows(f2); - - -// --- double case. - -c = 11; -c = 12.25; -c = 13.25; - -function f3() { return c; } -test(13.25, f3); - -delete c; - -testThrows(f3); - - -// --- tagged case. - -d = 11; -d = 12.25; -d = "hello"; - -function f4() { return d; } -test("hello", f4); - -delete d; - -testThrows(f4); diff --git a/test/mjsunit/compiler/global-var-delete.js b/test/mjsunit/compiler/global-var-delete.js deleted file mode 100644 index a7ea9ea..0000000 --- a/test/mjsunit/compiler/global-var-delete.js +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2015 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: --allow-natives-syntax - -function test(expected, f) { - assertEquals(expected, f()); - assertEquals(expected, f()); - %OptimizeFunctionOnNextCall(f); - assertEquals(expected, f()); - assertEquals(expected, f()); -} - -function testThrows(f) { - assertThrows(f); - assertThrows(f); - %OptimizeFunctionOnNextCall(f); - assertThrows(f); - assertThrows(f); -} - -// --- Constant case. -var a = 11; - -function f1() { return a; } -test(11, f1); - -delete a; - -test(11, f1); - - -// --- SMI case. - -var b = 11; -b = 12; -b = 13; - -function f2() { return b; } -test(13, f2); - -delete b; - -test(13, f2); - - -// --- double case. - -var c = 11; -c = 12.25; -c = 13.25; - -function f3() { return c; } -test(13.25, f3); - -delete c; - -test(13.25, f3); - - -// --- tagged case. - -var d = 11; -d = 12.25; -d = "hello"; - -function f4() { return d; } -test("hello", f4); - -delete d; - -test("hello", f4); diff --git a/test/unittests/compiler/js-type-feedback-unittest.cc b/test/unittests/compiler/js-type-feedback-unittest.cc deleted file mode 100644 index 08fe68a..0000000 --- a/test/unittests/compiler/js-type-feedback-unittest.cc +++ /dev/null @@ -1,277 +0,0 @@ -// Copyright 2015 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. - -#include "src/compiler.h" - -#include "src/compiler/access-builder.h" -#include "src/compiler/js-graph.h" -#include "src/compiler/js-operator.h" -#include "src/compiler/js-type-feedback.h" -#include "src/compiler/machine-operator.h" -#include "src/compiler/node-matchers.h" -#include "src/compiler/node-properties.h" -#include "src/compiler/operator-properties.h" - -#include "test/unittests/compiler/compiler-test-utils.h" -#include "test/unittests/compiler/graph-unittest.h" -#include "test/unittests/compiler/node-test-utils.h" -#include "testing/gmock-support.h" - -using testing::Capture; - - -namespace v8 { -namespace internal { -namespace compiler { - -class JSTypeFeedbackTest : public TypedGraphTest { - public: - JSTypeFeedbackTest() - : TypedGraphTest(3), - javascript_(zone()), - dependencies_(isolate(), zone()) {} - ~JSTypeFeedbackTest() override { dependencies_.Rollback(); } - - protected: - Reduction Reduce(Node* node) { - Handle global_object( - isolate()->native_context()->global_object(), isolate()); - - MachineOperatorBuilder machine(zone()); - JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine); - JSTypeFeedbackTable table(zone()); - JSTypeFeedbackSpecializer reducer(&jsgraph, &table, nullptr, global_object, - &dependencies_); - return reducer.Reduce(node); - } - - Node* EmptyFrameState() { - MachineOperatorBuilder machine(zone()); - JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine); - return jsgraph.EmptyFrameState(); - } - - JSOperatorBuilder* javascript() { return &javascript_; } - - void SetGlobalProperty(const char* string, int value) { - SetGlobalProperty(string, Handle(Smi::FromInt(value), isolate())); - } - - void SetGlobalProperty(const char* string, double value) { - SetGlobalProperty(string, isolate()->factory()->NewNumber(value)); - } - - void SetGlobalProperty(const char* string, Handle value) { - Handle global(isolate()->context()->global_object(), isolate()); - Handle name = - isolate()->factory()->NewStringFromAsciiChecked(string); - MaybeHandle result = - JSReceiver::SetProperty(global, name, value, SLOPPY); - result.Assert(); - } - - Node* ReturnLoadNamedFromGlobal(const char* string, Node* effect, - Node* control) { - VectorSlotPair feedback(Handle::null(), - FeedbackVectorICSlot::Invalid()); - Node* global = Parameter(Type::GlobalObject()); - Node* context = UndefinedConstant(); - - Unique name = Unique::CreateUninitialized( - isolate()->factory()->NewStringFromAsciiChecked(string)); - Node* load = graph()->NewNode(javascript()->LoadNamed(name, feedback), - global, context); - if (FLAG_turbo_deoptimization) { - load->AppendInput(zone(), EmptyFrameState()); - } - load->AppendInput(zone(), effect); - load->AppendInput(zone(), control); - Node* if_success = graph()->NewNode(common()->IfSuccess(), load); - return graph()->NewNode(common()->Return(), load, load, if_success); - } - - CompilationDependencies* dependencies() { return &dependencies_; } - - private: - JSOperatorBuilder javascript_; - CompilationDependencies dependencies_; -}; - -#define WITH_AND_WITHOUT_TURBO_DEOPTIMIZATION \ - for (int i = FLAG_turbo_deoptimization = 0; i < 2; \ - FLAG_turbo_deoptimization = ++i) - - -TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConst_smi) { - const int const_value = 111; - const char* property_name = "banana"; - SetGlobalProperty(property_name, const_value); - - WITH_AND_WITHOUT_TURBO_DEOPTIMIZATION { - Node* ret = ReturnLoadNamedFromGlobal(property_name, graph()->start(), - graph()->start()); - graph()->SetEnd(graph()->NewNode(common()->End(), ret)); - - Reduction r = Reduce(ret->InputAt(0)); - - if (FLAG_turbo_deoptimization) { - // Check LoadNamed(global) => HeapConstant[const_value] - ASSERT_TRUE(r.Changed()); - EXPECT_THAT(r.replacement(), IsNumberConstant(const_value)); - - EXPECT_THAT(ret, IsReturn(IsNumberConstant(const_value), graph()->start(), - graph()->start())); - EXPECT_THAT(graph()->end(), IsEnd(ret)); - - EXPECT_FALSE(dependencies()->IsEmpty()); - dependencies()->Rollback(); - } else { - ASSERT_FALSE(r.Changed()); - EXPECT_TRUE(dependencies()->IsEmpty()); - } - } -} - - -TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConst_derble) { - const double const_value = -11.25; - const char* property_name = "kiwi"; - SetGlobalProperty(property_name, const_value); - - WITH_AND_WITHOUT_TURBO_DEOPTIMIZATION { - Node* ret = ReturnLoadNamedFromGlobal(property_name, graph()->start(), - graph()->start()); - graph()->SetEnd(graph()->NewNode(common()->End(), ret)); - - Reduction r = Reduce(ret->InputAt(0)); - - if (FLAG_turbo_deoptimization) { - // Check LoadNamed(global) => HeapConstant[const_value] - ASSERT_TRUE(r.Changed()); - EXPECT_THAT(r.replacement(), IsNumberConstant(const_value)); - - EXPECT_THAT(ret, IsReturn(IsNumberConstant(const_value), graph()->start(), - graph()->start())); - EXPECT_THAT(graph()->end(), IsEnd(ret)); - - EXPECT_FALSE(dependencies()->IsEmpty()); - } else { - ASSERT_FALSE(r.Changed()); - EXPECT_TRUE(dependencies()->IsEmpty()); - } - } -} - - -TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConst_string) { - Unique const_value = Unique::CreateImmovable( - isolate()->factory()->undefined_string()); - const char* property_name = "mango"; - SetGlobalProperty(property_name, const_value.handle()); - - WITH_AND_WITHOUT_TURBO_DEOPTIMIZATION { - Node* ret = ReturnLoadNamedFromGlobal(property_name, graph()->start(), - graph()->start()); - graph()->SetEnd(graph()->NewNode(common()->End(), ret)); - - Reduction r = Reduce(ret->InputAt(0)); - - if (FLAG_turbo_deoptimization) { - // Check LoadNamed(global) => HeapConstant[const_value] - ASSERT_TRUE(r.Changed()); - EXPECT_THAT(r.replacement(), IsHeapConstant(const_value)); - - EXPECT_THAT(ret, IsReturn(IsHeapConstant(const_value), graph()->start(), - graph()->start())); - EXPECT_THAT(graph()->end(), IsEnd(ret)); - - EXPECT_FALSE(dependencies()->IsEmpty()); - dependencies()->Rollback(); - } else { - ASSERT_FALSE(r.Changed()); - EXPECT_TRUE(dependencies()->IsEmpty()); - } - } -} - - -TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCell_smi) { - const char* property_name = "melon"; - SetGlobalProperty(property_name, 123); - SetGlobalProperty(property_name, 124); - - WITH_AND_WITHOUT_TURBO_DEOPTIMIZATION { - Node* ret = ReturnLoadNamedFromGlobal(property_name, graph()->start(), - graph()->start()); - graph()->SetEnd(graph()->NewNode(common()->End(), ret)); - - Reduction r = Reduce(ret->InputAt(0)); - - if (FLAG_turbo_deoptimization) { - // Check LoadNamed(global) => LoadField[PropertyCell::value](cell) - ASSERT_TRUE(r.Changed()); - FieldAccess access = AccessBuilder::ForPropertyCellValue(); - Capture cell_capture; - Matcher load_field_match = IsLoadField( - access, CaptureEq(&cell_capture), graph()->start(), graph()->start()); - EXPECT_THAT(r.replacement(), load_field_match); - - HeapObjectMatcher cell(cell_capture.value()); - EXPECT_TRUE(cell.HasValue()); - EXPECT_TRUE(cell.Value().handle()->IsPropertyCell()); - - EXPECT_THAT( - ret, IsReturn(load_field_match, load_field_match, graph()->start())); - EXPECT_THAT(graph()->end(), IsEnd(ret)); - - EXPECT_FALSE(dependencies()->IsEmpty()); - dependencies()->Rollback(); - } else { - ASSERT_FALSE(r.Changed()); - EXPECT_TRUE(dependencies()->IsEmpty()); - } - } -} - - -TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCell_string) { - const char* property_name = "pineapple"; - SetGlobalProperty(property_name, isolate()->factory()->undefined_string()); - SetGlobalProperty(property_name, isolate()->factory()->undefined_value()); - - WITH_AND_WITHOUT_TURBO_DEOPTIMIZATION { - Node* ret = ReturnLoadNamedFromGlobal(property_name, graph()->start(), - graph()->start()); - graph()->SetEnd(graph()->NewNode(common()->End(), ret)); - - Reduction r = Reduce(ret->InputAt(0)); - - if (FLAG_turbo_deoptimization) { - // Check LoadNamed(global) => LoadField[PropertyCell::value](cell) - ASSERT_TRUE(r.Changed()); - FieldAccess access = AccessBuilder::ForPropertyCellValue(); - Capture cell_capture; - Matcher load_field_match = IsLoadField( - access, CaptureEq(&cell_capture), graph()->start(), graph()->start()); - EXPECT_THAT(r.replacement(), load_field_match); - - HeapObjectMatcher cell(cell_capture.value()); - EXPECT_TRUE(cell.HasValue()); - EXPECT_TRUE(cell.Value().handle()->IsPropertyCell()); - - EXPECT_THAT( - ret, IsReturn(load_field_match, load_field_match, graph()->start())); - EXPECT_THAT(graph()->end(), IsEnd(ret)); - - EXPECT_FALSE(dependencies()->IsEmpty()); - dependencies()->Rollback(); - } else { - ASSERT_FALSE(r.Changed()); - EXPECT_TRUE(dependencies()->IsEmpty()); - } - } -} -} -} -} diff --git a/test/unittests/unittests.gyp b/test/unittests/unittests.gyp index 25644f2..eb5d784 100644 --- a/test/unittests/unittests.gyp +++ b/test/unittests/unittests.gyp @@ -57,7 +57,6 @@ 'compiler/js-intrinsic-lowering-unittest.cc', 'compiler/js-operator-unittest.cc', 'compiler/js-typed-lowering-unittest.cc', - 'compiler/js-type-feedback-unittest.cc', 'compiler/liveness-analyzer-unittest.cc', 'compiler/load-elimination-unittest.cc', 'compiler/loop-peeling-unittest.cc',