| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 29faf0f commit 05f41cd
8 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -69,6 +69,7 @@ Ben Newman <ben@meteor.com> | |||
| 69 | 69 | Ben Noordhuis <info@bnoordhuis.nl> | |
| 70 | 70 | Benjamin Tan <demoneaux@gmail.com> | |
| 71 | 71 | Bert Belder <bertbelder@gmail.com> | |
| 72 | + Brendon Tiszka <btiszka@gmail.com> | ||
| 72 | 73 | Brice Dobry <brice.dobry@futurewei.com> | |
| 73 | 74 | Burcu Dogan <burcujdogan@gmail.com> | |
| 74 | 75 | Caitlin Potter <caitpotter88@gmail.com> | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,7 +11,7 @@ | |||
| 11 | 11 | #define V8_MAJOR_VERSION 9 | |
| 12 | 12 | #define V8_MINOR_VERSION 0 | |
| 13 | 13 | #define V8_BUILD_NUMBER 257 | |
| 14 | - #define V8_PATCH_LEVEL 17 | ||
| 14 | + #define V8_PATCH_LEVEL 19 | ||
| 15 | 15 | ||
| 16 | 16 | // Use 1 for candidates and 0 otherwise. | |
| 17 | 17 | // (Boolean macro values are not supported by all preprocessors.) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -650,11 +650,14 @@ class ArrayConcatVisitor { | |||
| 650 | 650 | index_offset_(0u), | |
| 651 | 651 | bit_field_(FastElementsField::encode(fast_elements) | | |
| 652 | 652 | ExceedsLimitField::encode(false) | | |
| 653 | - IsFixedArrayField::encode(storage->IsFixedArray()) | | ||
| 653 | + IsFixedArrayField::encode(storage->IsFixedArray(isolate)) | | ||
| 654 | 654 | HasSimpleElementsField::encode( | |
| 655 | - storage->IsFixedArray() || | ||
| 656 | - !storage->map().IsCustomElementsReceiverMap())) { | ||
| 657 | - DCHECK(!(this->fast_elements() && !is_fixed_array())); | ||
| 655 | + storage->IsFixedArray(isolate) || | ||
| 656 | + // Don't take fast path for storages that might have | ||
| 657 | + // side effects when storing to them. | ||
| 658 | + (!storage->map(isolate).IsCustomElementsReceiverMap() && | ||
| 659 | + !storage->IsJSTypedArray(isolate)))) { | ||
| 660 | + DCHECK_IMPLIES(this->fast_elements(), is_fixed_array()); | ||
| 658 | 661 | } | |
| 659 | 662 | ||
| 660 | 663 | ~ArrayConcatVisitor() { clear_storage(); } | |
@@ -1065,8 +1068,8 @@ bool IterateElements(Isolate* isolate, Handle<JSReceiver> receiver, | |||
| 1065 | 1068 | return IterateElementsSlow(isolate, receiver, length, visitor); | |
| 1066 | 1069 | } | |
| 1067 | 1070 | ||
| 1068 | - if (!HasOnlySimpleElements(isolate, *receiver) || | ||
| 1069 | - !visitor->has_simple_elements()) { | ||
| 1071 | + if (!visitor->has_simple_elements() || | ||
| 1072 | + !HasOnlySimpleElements(isolate, *receiver)) { | ||
| 1070 | 1073 | return IterateElementsSlow(isolate, receiver, length, visitor); | |
| 1071 | 1074 | } | |
| 1072 | 1075 | Handle<JSObject> array = Handle<JSObject>::cast(receiver); | |
@@ -1082,6 +1085,9 @@ bool IterateElements(Isolate* isolate, Handle<JSReceiver> receiver, | |||
| 1082 | 1085 | case HOLEY_SEALED_ELEMENTS: | |
| 1083 | 1086 | case HOLEY_NONEXTENSIBLE_ELEMENTS: | |
| 1084 | 1087 | case HOLEY_ELEMENTS: { | |
| 1088 | + // Disallow execution so the cached elements won't change mid execution. | ||
| 1089 | + DisallowJavascriptExecution no_js(isolate); | ||
| 1090 | + | ||
| 1085 | 1091 | // Run through the elements FixedArray and use HasElement and GetElement | |
| 1086 | 1092 | // to check the prototype for missing elements. | |
| 1087 | 1093 | Handle<FixedArray> elements(FixedArray::cast(array->elements()), isolate); | |
@@ -1108,6 +1114,9 @@ bool IterateElements(Isolate* isolate, Handle<JSReceiver> receiver, | |||
| 1108 | 1114 | } | |
| 1109 | 1115 | case HOLEY_DOUBLE_ELEMENTS: | |
| 1110 | 1116 | case PACKED_DOUBLE_ELEMENTS: { | |
| 1117 | + // Disallow execution so the cached elements won't change mid execution. | ||
| 1118 | + DisallowJavascriptExecution no_js(isolate); | ||
| 1119 | + | ||
| 1111 | 1120 | // Empty array is FixedArray but not FixedDoubleArray. | |
| 1112 | 1121 | if (length == 0) break; | |
| 1113 | 1122 | // Run through the elements FixedArray and use HasElement and GetElement | |
@@ -1144,6 +1153,9 @@ bool IterateElements(Isolate* isolate, Handle<JSReceiver> receiver, | |||
| 1144 | 1153 | } | |
| 1145 | 1154 | ||
| 1146 | 1155 | case DICTIONARY_ELEMENTS: { | |
| 1156 | + // Disallow execution so the cached dictionary won't change mid execution. | ||
| 1157 | + DisallowJavascriptExecution no_js(isolate); | ||
| 1158 | + | ||
| 1147 | 1159 | Handle<NumberDictionary> dict(array->element_dictionary(), isolate); | |
| 1148 | 1160 | std::vector<uint32_t> indices; | |
| 1149 | 1161 | indices.reserve(dict->Capacity() / 2); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -949,10 +949,10 @@ Node* RepresentationChanger::GetWord32RepresentationFor( | |||
| 949 | 949 | return node; | |
| 950 | 950 | } else if (output_rep == MachineRepresentation::kWord64) { | |
| 951 | 951 | if (output_type.Is(Type::Signed32()) || | |
| 952 | - output_type.Is(Type::Unsigned32())) { | ||
| 953 | - op = machine()->TruncateInt64ToInt32(); | ||
| 954 | - } else if (output_type.Is(cache_->kSafeInteger) && | ||
| 955 | - use_info.truncation().IsUsedAsWord32()) { | ||
| 952 | + (output_type.Is(Type::Unsigned32()) && | ||
| 953 | + use_info.type_check() == TypeCheckKind::kNone) || | ||
| 954 | + (output_type.Is(cache_->kSafeInteger) && | ||
| 955 | + use_info.truncation().IsUsedAsWord32())) { | ||
| 956 | 956 | op = machine()->TruncateInt64ToInt32(); | |
| 957 | 957 | } else if (use_info.type_check() == TypeCheckKind::kSignedSmall || | |
| 958 | 958 | use_info.type_check() == TypeCheckKind::kSigned32 || | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -368,15 +368,15 @@ int Search(T* array, Name name, int valid_entries, int* out_insertion_index, | |||
| 368 | 368 | double FixedDoubleArray::get_scalar(int index) { | |
| 369 | 369 | DCHECK(map() != GetReadOnlyRoots().fixed_cow_array_map() && | |
| 370 | 370 | map() != GetReadOnlyRoots().fixed_array_map()); | |
| 371 | - DCHECK(index >= 0 && index < this->length()); | ||
| 371 | + DCHECK_LT(static_cast<unsigned>(index), static_cast<unsigned>(length())); | ||
| 372 | 372 | DCHECK(!is_the_hole(index)); | |
| 373 | 373 | return ReadField<double>(kHeaderSize + index * kDoubleSize); | |
| 374 | 374 | } | |
| 375 | 375 | ||
| 376 | 376 | uint64_t FixedDoubleArray::get_representation(int index) { | |
| 377 | 377 | DCHECK(map() != GetReadOnlyRoots().fixed_cow_array_map() && | |
| 378 | 378 | map() != GetReadOnlyRoots().fixed_array_map()); | |
| 379 | - DCHECK(index >= 0 && index < this->length()); | ||
| 379 | + DCHECK_LT(static_cast<unsigned>(index), static_cast<unsigned>(length())); | ||
| 380 | 380 | int offset = kHeaderSize + index * kDoubleSize; | |
| 381 | 381 | // Bug(v8:8875): Doubles may be unaligned. | |
| 382 | 382 | return base::ReadUnalignedValue<uint64_t>(field_address(offset)); | |
@@ -394,6 +394,7 @@ Handle<Object> FixedDoubleArray::get(FixedDoubleArray array, int index, | |||
| 394 | 394 | void FixedDoubleArray::set(int index, double value) { | |
| 395 | 395 | DCHECK(map() != GetReadOnlyRoots().fixed_cow_array_map() && | |
| 396 | 396 | map() != GetReadOnlyRoots().fixed_array_map()); | |
| 397 | + DCHECK_LT(static_cast<unsigned>(index), static_cast<unsigned>(length())); | ||
| 397 | 398 | int offset = kHeaderSize + index * kDoubleSize; | |
| 398 | 399 | if (std::isnan(value)) { | |
| 399 | 400 | WriteField<double>(offset, std::numeric_limits<double>::quiet_NaN()); | |
@@ -410,6 +411,7 @@ void FixedDoubleArray::set_the_hole(Isolate* isolate, int index) { | |||
| 410 | 411 | void FixedDoubleArray::set_the_hole(int index) { | |
| 411 | 412 | DCHECK(map() != GetReadOnlyRoots().fixed_cow_array_map() && | |
| 412 | 413 | map() != GetReadOnlyRoots().fixed_array_map()); | |
| 414 | + DCHECK_LT(static_cast<unsigned>(index), static_cast<unsigned>(length())); | ||
| 413 | 415 | int offset = kHeaderSize + index * kDoubleSize; | |
| 414 | 416 | base::WriteUnalignedValue<uint64_t>(field_address(offset), kHoleNanInt64); | |
| 415 | 417 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -139,11 +139,20 @@ Handle<Map> MapUpdater::ReconfigureToDataField(InternalIndex descriptor, | |||
| 139 | 139 | if (old_details.constness() == PropertyConstness::kConst && | |
| 140 | 140 | old_details.location() == kField && | |
| 141 | 141 | old_details.attributes() != new_attributes_) { | |
| 142 | + // Ensure we'll be updating constness of the up-to-date version of old_map_. | ||
| 143 | + Handle<Map> old_map = Map::Update(isolate_, old_map_); | ||
| 144 | + PropertyDetails details = | ||
| 145 | + old_map->instance_descriptors(kRelaxedLoad).GetDetails(descriptor); | ||
| 142 | 146 | Handle<FieldType> field_type( | |
| 143 | - old_descriptors_->GetFieldType(modified_descriptor_), isolate_); | ||
| 144 | - Map::GeneralizeField(isolate_, old_map_, descriptor, | ||
| 145 | - PropertyConstness::kMutable, | ||
| 146 | - old_details.representation(), field_type); | ||
| 147 | + old_map->instance_descriptors(kRelaxedLoad).GetFieldType(descriptor), | ||
| 148 | + isolate_); | ||
| 149 | + Map::GeneralizeField(isolate_, old_map, descriptor, | ||
| 150 | + PropertyConstness::kMutable, details.representation(), | ||
| 151 | + field_type); | ||
| 152 | + DCHECK_EQ(PropertyConstness::kMutable, | ||
| 153 | + old_map->instance_descriptors(kRelaxedLoad) | ||
| 154 | + .GetDetails(descriptor) | ||
| 155 | + .constness()); | ||
| 147 | 156 | // The old_map_'s property must become mutable. | |
| 148 | 157 | // Note, that the {old_map_} and {old_descriptors_} are not expected to be | |
| 149 | 158 | // updated by the generalization if the map is already deprecated. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,62 @@ | |||
| 1 | + // Copyright 2021 the V8 project authors. All rights reserved. | ||
| 2 | + // Use of this source code is governed by a BSD-style license that can be | ||
| 3 | + // found in the LICENSE file. | ||
| 4 | + | ||
| 5 | + // Flags: --allow-natives-syntax | ||
| 6 | + | ||
| 7 | + | ||
| 8 | + (function() { | ||
| 9 | + function foo(b) { | ||
| 10 | + let y = (new Date(42)).getMilliseconds(); | ||
| 11 | + let x = -1; | ||
| 12 | + if (b) x = 0xFFFF_FFFF; | ||
| 13 | + return y < Math.max(1 << y, x, 1 + y); | ||
| 14 | + } | ||
| 15 | + assertTrue(foo(true)); | ||
| 16 | + %PrepareFunctionForOptimization(foo); | ||
| 17 | + assertTrue(foo(false)); | ||
| 18 | + %OptimizeFunctionOnNextCall(foo); | ||
| 19 | + assertTrue(foo(true)); | ||
| 20 | + })(); | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + (function() { | ||
| 24 | + function foo(b) { | ||
| 25 | + let x = 0; | ||
| 26 | + if (b) x = -1; | ||
| 27 | + return x == Math.max(-1, x >>> Infinity); | ||
| 28 | + } | ||
| 29 | + assertFalse(foo(true)); | ||
| 30 | + %PrepareFunctionForOptimization(foo); | ||
| 31 | + assertTrue(foo(false)); | ||
| 32 | + %OptimizeFunctionOnNextCall(foo); | ||
| 33 | + assertFalse(foo(true)); | ||
| 34 | + })(); | ||
| 35 | + | ||
| 36 | + | ||
| 37 | + (function() { | ||
| 38 | + function foo(b) { | ||
| 39 | + let x = -1; | ||
| 40 | + if (b) x = 0xFFFF_FFFF; | ||
| 41 | + return -1 < Math.max(0, x, -1); | ||
| 42 | + } | ||
| 43 | + assertTrue(foo(true)); | ||
| 44 | + %PrepareFunctionForOptimization(foo); | ||
| 45 | + assertTrue(foo(false)); | ||
| 46 | + %OptimizeFunctionOnNextCall(foo); | ||
| 47 | + assertTrue(foo(true)); | ||
| 48 | + })(); | ||
| 49 | + | ||
| 50 | + | ||
| 51 | + (function() { | ||
| 52 | + function foo(b) { | ||
| 53 | + let x = 0x7FFF_FFFF; | ||
| 54 | + if (b) x = 0; | ||
| 55 | + return 0 < (Math.max(-5 >>> x, -5) % -5); | ||
| 56 | + } | ||
| 57 | + assertTrue(foo(true)); | ||
| 58 | + %PrepareFunctionForOptimization(foo); | ||
| 59 | + assertTrue(foo(false)); | ||
| 60 | + %OptimizeFunctionOnNextCall(foo); | ||
| 61 | + assertTrue(foo(true)); | ||
| 62 | + })(); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,36 @@ | |||
| 1 | + // Copyright 2021 the V8 project authors. All rights reserved. | ||
| 2 | + // Use of this source code is governed by a BSD-style license that can be | ||
| 3 | + // found in the LICENSE file. | ||
| 4 | + | ||
| 5 | + // Flags: --allow-natives-syntax | ||
| 6 | + | ||
| 7 | + let o1 = { a: 1, b: 0 }; | ||
| 8 | + let o2 = { a: 2, b: 0 }; | ||
| 9 | + assertTrue(%HaveSameMap(o1, o2)); | ||
| 10 | + assertTrue(%HasOwnConstDataProperty(o1, "a")); | ||
| 11 | + assertTrue(%HasOwnConstDataProperty(o1, "b")); | ||
| 12 | + | ||
| 13 | + Object.defineProperty(o1, "b", { | ||
| 14 | + value: 4.2, enumerable: true, configurable: true, writable: true, | ||
| 15 | + }); | ||
| 16 | + assertFalse(%HaveSameMap(o1, o2)); | ||
| 17 | + assertTrue(%HasOwnConstDataProperty(o1, "a")); | ||
| 18 | + assertFalse(%HasOwnConstDataProperty(o1, "b")); | ||
| 19 | + assertTrue(%HasOwnConstDataProperty(o2, "a")); | ||
| 20 | + assertTrue(%HasOwnConstDataProperty(o2, "b")); | ||
| 21 | + | ||
| 22 | + let o3 = { a: "foo", b: 0 }; | ||
| 23 | + assertFalse(%HaveSameMap(o2, o3)); | ||
| 24 | + assertTrue(%HasOwnConstDataProperty(o3, "a")); | ||
| 25 | + assertFalse(%HasOwnConstDataProperty(o3, "b")); | ||
| 26 | + | ||
| 27 | + Object.defineProperty(o2, "a", { | ||
| 28 | + value:2, enumerable: false, configurable: true, writable: true, | ||
| 29 | + }); | ||
| 30 | + assertFalse(%HasOwnConstDataProperty(o1, "a")); | ||
| 31 | + assertFalse(%HasOwnConstDataProperty(o1, "b")); | ||
| 32 | + assertFalse(%HasOwnConstDataProperty(o3, "a")); | ||
| 33 | + assertFalse(%HasOwnConstDataProperty(o3, "b")); | ||
| 34 | + | ||
| 35 | + assertFalse(%HasOwnConstDataProperty(o2, "a")); | ||
| 36 | + assertTrue(%HasOwnConstDataProperty(o2, "b")); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments