aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/test/cctest/test-field-type-tracking.cc
diff options
context:
space:
mode:
authorMichaƫl Zasso <targos@protonmail.com>2019-05-21 08:21:34 +0200
committerRuben Bridgewater <ruben@bridgewater.de>2019-05-22 14:24:41 +0200
commitf2fe1e5a78d6decf04536764c8c4cf3f6c5f8dd7 (patch)
treee11d1d4d1b71c3d8cd9741e6bd2d80009f7d05bb /deps/v8/test/cctest/test-field-type-tracking.cc
parentc3f72510c8f629ed2178b50bb2860efc3feb9249 (diff)
downloadandroid-node-v8-f2fe1e5a78d6decf04536764c8c4cf3f6c5f8dd7.tar.gz
android-node-v8-f2fe1e5a78d6decf04536764c8c4cf3f6c5f8dd7.tar.bz2
android-node-v8-f2fe1e5a78d6decf04536764c8c4cf3f6c5f8dd7.zip
deps: V8: cherry-pick 94c87fe
Original commit message: [ic] Fix handling of +0/-0 when constant field tracking is enabled ... and ensure that runtime behaviour is in sync with the IC code. Bug: chromium:950747, v8:9113 Change-Id: Ied66c9514cbe3a4d75fc71d4fc3b19ea1538f9b2 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1561319 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Igor Sheludko <ishell@chromium.org> Cr-Commit-Position: refs/heads/master@{#60768} PR-URL: https://github.com/nodejs/node/pull/27792 Fixes: https://github.com/nodejs/node/issues/27784 Refs: https://github.com/v8/v8/commit/94c87fe0746fc95618ae091351f2f8c342212917 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Gus Caplan <me@gus.host>
Diffstat (limited to 'deps/v8/test/cctest/test-field-type-tracking.cc')
-rw-r--r--deps/v8/test/cctest/test-field-type-tracking.cc186
1 files changed, 186 insertions, 0 deletions
diff --git a/deps/v8/test/cctest/test-field-type-tracking.cc b/deps/v8/test/cctest/test-field-type-tracking.cc
index 49b0f92011..0253a16735 100644
--- a/deps/v8/test/cctest/test-field-type-tracking.cc
+++ b/deps/v8/test/cctest/test-field-type-tracking.cc
@@ -2883,6 +2883,192 @@ TEST(HoleyMutableHeapNumber) {
CHECK_EQ(kHoleNanInt64, MutableHeapNumber::cast(*obj)->value_as_bits());
}
+namespace {
+
+template <class... Args>
+MaybeHandle<Object> Call(Isolate* isolate, Handle<JSFunction> function,
+ Args... args) {
+ Handle<Object> argv[] = {args...};
+ return Execution::Call(isolate, function,
+ isolate->factory()->undefined_value(), sizeof...(args),
+ argv);
+}
+
+void TestStoreToConstantField(const char* store_func_source,
+ Handle<Object> value1, Handle<Object> value2,
+ Representation expected_rep,
+ PropertyConstness expected_constness,
+ int store_repetitions) {
+ Isolate* isolate = CcTest::i_isolate();
+ CompileRun(store_func_source);
+
+ Handle<JSFunction> store_func = GetGlobal<JSFunction>("store");
+
+ const PropertyConstness kExpectedInitialFieldConstness =
+ FLAG_track_constant_fields ? PropertyConstness::kConst
+ : PropertyConstness::kMutable;
+
+ Handle<Map> initial_map = Map::Create(isolate, 4);
+
+ // Store value1 to obj1 and check that it got property with expected
+ // representation and constness.
+ Handle<JSObject> obj1 = isolate->factory()->NewJSObjectFromMap(initial_map);
+ for (int i = 0; i < store_repetitions; i++) {
+ Call(isolate, store_func, obj1, value1).Check();
+ }
+
+ Handle<Map> map(obj1->map(), isolate);
+ CHECK(!map->is_dictionary_map());
+ CHECK(!map->is_deprecated());
+ CHECK_EQ(1, map->NumberOfOwnDescriptors());
+
+ CHECK(map->instance_descriptors()->GetDetails(0).representation().Equals(
+ expected_rep));
+ CHECK_EQ(kExpectedInitialFieldConstness,
+ map->instance_descriptors()->GetDetails(0).constness());
+
+ // Store value2 to obj2 and check that it got same map and property details
+ // did not change.
+ Handle<JSObject> obj2 = isolate->factory()->NewJSObjectFromMap(initial_map);
+ Call(isolate, store_func, obj2, value2).Check();
+
+ CHECK_EQ(*map, obj2->map());
+ CHECK(!map->is_dictionary_map());
+ CHECK(!map->is_deprecated());
+ CHECK_EQ(1, map->NumberOfOwnDescriptors());
+
+ CHECK(map->instance_descriptors()->GetDetails(0).representation().Equals(
+ expected_rep));
+ CHECK_EQ(kExpectedInitialFieldConstness,
+ map->instance_descriptors()->GetDetails(0).constness());
+
+ // Store value2 to obj1 and check that property became mutable.
+ Call(isolate, store_func, obj1, value2).Check();
+
+ CHECK_EQ(*map, obj1->map());
+ CHECK(!map->is_dictionary_map());
+ CHECK(!map->is_deprecated());
+ CHECK_EQ(1, map->NumberOfOwnDescriptors());
+
+ CHECK(map->instance_descriptors()->GetDetails(0).representation().Equals(
+ expected_rep));
+ CHECK_EQ(expected_constness,
+ map->instance_descriptors()->GetDetails(0).constness());
+}
+
+void TestStoreToConstantField_PlusMinusZero(const char* store_func_source,
+ int store_repetitions) {
+ Isolate* isolate = CcTest::i_isolate();
+ CompileRun(store_func_source);
+
+ Handle<Object> minus_zero = isolate->factory()->NewNumber(-0.0);
+ Handle<Object> plus_zero = isolate->factory()->NewNumber(0.0);
+
+ // +0 and -0 are treated as not equal upon stores.
+ const PropertyConstness kExpectedFieldConstness = PropertyConstness::kMutable;
+
+ TestStoreToConstantField(store_func_source, minus_zero, plus_zero,
+ Representation::Double(), kExpectedFieldConstness,
+ store_repetitions);
+}
+
+void TestStoreToConstantField_NaN(const char* store_func_source,
+ int store_repetitions) {
+ Isolate* isolate = CcTest::i_isolate();
+ CompileRun(store_func_source);
+
+ uint64_t nan_bits = uint64_t{0x7FF8000000000001};
+ double nan_double1 = bit_cast<double>(nan_bits);
+ double nan_double2 = bit_cast<double>(nan_bits | 0x12300);
+ CHECK(std::isnan(nan_double1));
+ CHECK(std::isnan(nan_double2));
+ CHECK_NE(nan_double1, nan_double2);
+ CHECK_NE(bit_cast<uint64_t>(nan_double1), bit_cast<uint64_t>(nan_double2));
+
+ Handle<Object> nan1 = isolate->factory()->NewNumber(nan_double1);
+ Handle<Object> nan2 = isolate->factory()->NewNumber(nan_double2);
+
+ // NaNs with different bit patters are treated as equal upon stores.
+ const PropertyConstness kExpectedFieldConstness =
+ FLAG_track_constant_fields ? PropertyConstness::kConst
+ : PropertyConstness::kMutable;
+
+ TestStoreToConstantField(store_func_source, nan1, nan2,
+ Representation::Double(), kExpectedFieldConstness,
+ store_repetitions);
+}
+
+} // namespace
+
+TEST(StoreToConstantField_PlusMinusZero) {
+ FLAG_allow_natives_syntax = true;
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+
+ const char* store_func_source =
+ "function store(o, v) {"
+ " %SetNamedProperty(o, 'v', v);"
+ "}";
+
+ TestStoreToConstantField_PlusMinusZero(store_func_source, 1);
+ TestStoreToConstantField_PlusMinusZero(store_func_source, 3);
+
+ TestStoreToConstantField_NaN(store_func_source, 1);
+ TestStoreToConstantField_NaN(store_func_source, 2);
+}
+
+TEST(StoreToConstantField_ObjectDefineProperty) {
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+
+ const char* store_func_source =
+ "function store(o, v) {"
+ " Object.defineProperty(o, 'v', "
+ " {value: v, "
+ " writable: true, "
+ " configurable: true, "
+ " enumerable: true});"
+ "}";
+
+ TestStoreToConstantField_PlusMinusZero(store_func_source, 1);
+ TestStoreToConstantField_PlusMinusZero(store_func_source, 3);
+
+ TestStoreToConstantField_NaN(store_func_source, 1);
+ TestStoreToConstantField_NaN(store_func_source, 2);
+}
+
+TEST(StoreToConstantField_ReflectSet) {
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+
+ const char* store_func_source =
+ "function store(o, v) {"
+ " Reflect.set(o, 'v', v);"
+ "}";
+
+ TestStoreToConstantField_PlusMinusZero(store_func_source, 1);
+ TestStoreToConstantField_PlusMinusZero(store_func_source, 3);
+
+ TestStoreToConstantField_NaN(store_func_source, 1);
+ TestStoreToConstantField_NaN(store_func_source, 2);
+}
+
+TEST(StoreToConstantField_StoreIC) {
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+
+ const char* store_func_source =
+ "function store(o, v) {"
+ " o.v = v;"
+ "}";
+
+ TestStoreToConstantField_PlusMinusZero(store_func_source, 1);
+ TestStoreToConstantField_PlusMinusZero(store_func_source, 3);
+
+ TestStoreToConstantField_NaN(store_func_source, 1);
+ TestStoreToConstantField_NaN(store_func_source, 2);
+}
+
} // namespace test_field_type_tracking
} // namespace compiler
} // namespace internal