| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 45b54ee commit 413bf9a
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,7 +11,7 @@ | |||
| 11 | 11 | #define V8_MAJOR_VERSION 10 | |
| 12 | 12 | #define V8_MINOR_VERSION 7 | |
| 13 | 13 | #define V8_BUILD_NUMBER 193 | |
| 14 | - #define V8_PATCH_LEVEL 20 | ||
| 14 | + #define V8_PATCH_LEVEL 22 | ||
| 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 | |
|---|---|---|---|
@@ -5294,6 +5294,8 @@ Node* EffectControlLinearizer::LowerLoadFieldByIndex(Node* node) { | |||
| 5294 | 5294 | ||
| 5295 | 5295 | auto if_double = __ MakeDeferredLabel(); | |
| 5296 | 5296 | auto done = __ MakeLabel(MachineRepresentation::kTagged); | |
| 5297 | + auto loaded_field = __ MakeLabel(MachineRepresentation::kTagged); | ||
| 5298 | + auto done_double = __ MakeLabel(MachineRepresentation::kFloat64); | ||
| 5297 | 5299 | ||
| 5298 | 5300 | // Check if field is a mutable double field. | |
| 5299 | 5301 | __ GotoIfNot(__ IntPtrEqual(__ WordAnd(index, one), zero), &if_double); | |
@@ -5310,8 +5312,8 @@ Node* EffectControlLinearizer::LowerLoadFieldByIndex(Node* node) { | |||
| 5310 | 5312 | Node* offset = | |
| 5311 | 5313 | __ IntAdd(__ WordShl(index, __ IntPtrConstant(kTaggedSizeLog2 - 1)), | |
| 5312 | 5314 | __ IntPtrConstant(JSObject::kHeaderSize - kHeapObjectTag)); | |
| 5313 | - Node* result = __ Load(MachineType::AnyTagged(), object, offset); | ||
| 5314 | - __ Goto(&done, result); | ||
| 5315 | + Node* field = __ Load(MachineType::AnyTagged(), object, offset); | ||
| 5316 | + __ Goto(&loaded_field, field); | ||
| 5315 | 5317 | } | |
| 5316 | 5318 | ||
| 5317 | 5319 | // The field is located in the properties backing store of {object}. | |
@@ -5325,18 +5327,15 @@ Node* EffectControlLinearizer::LowerLoadFieldByIndex(Node* node) { | |||
| 5325 | 5327 | __ IntPtrConstant(kTaggedSizeLog2 - 1)), | |
| 5326 | 5328 | __ IntPtrConstant((FixedArray::kHeaderSize - kTaggedSize) - | |
| 5327 | 5329 | kHeapObjectTag)); | |
| 5328 | - Node* result = __ Load(MachineType::AnyTagged(), properties, offset); | ||
| 5329 | - __ Goto(&done, result); | ||
| 5330 | + Node* field = __ Load(MachineType::AnyTagged(), properties, offset); | ||
| 5331 | + __ Goto(&loaded_field, field); | ||
| 5330 | 5332 | } | |
| 5331 | 5333 | } | |
| 5332 | 5334 | ||
| 5333 | 5335 | // The field is a Double field, either unboxed in the object on 64-bit | |
| 5334 | 5336 | // architectures, or a mutable HeapNumber. | |
| 5335 | 5337 | __ Bind(&if_double); | |
| 5336 | 5338 | { | |
| 5337 | - auto loaded_field = __ MakeLabel(MachineRepresentation::kTagged); | ||
| 5338 | - auto done_double = __ MakeLabel(MachineRepresentation::kFloat64); | ||
| 5339 | - | ||
| 5340 | 5339 | index = __ WordSar(index, one); | |
| 5341 | 5340 | ||
| 5342 | 5341 | // Check if field is in-object or out-of-object. | |
@@ -5364,27 +5363,27 @@ Node* EffectControlLinearizer::LowerLoadFieldByIndex(Node* node) { | |||
| 5364 | 5363 | Node* field = __ Load(MachineType::AnyTagged(), properties, offset); | |
| 5365 | 5364 | __ Goto(&loaded_field, field); | |
| 5366 | 5365 | } | |
| 5366 | + } | ||
| 5367 | 5367 | ||
| 5368 | - __ Bind(&loaded_field); | ||
| 5369 | - { | ||
| 5370 | - Node* field = loaded_field.PhiAt(0); | ||
| 5371 | - // We may have transitioned in-place away from double, so check that | ||
| 5372 | - // this is a HeapNumber -- otherwise the load is fine and we don't need | ||
| 5373 | - // to copy anything anyway. | ||
| 5374 | - __ GotoIf(ObjectIsSmi(field), &done, field); | ||
| 5375 | - Node* field_map = __ LoadField(AccessBuilder::ForMap(), field); | ||
| 5376 | - __ GotoIfNot(__ TaggedEqual(field_map, __ HeapNumberMapConstant()), &done, | ||
| 5377 | - field); | ||
| 5378 | - | ||
| 5379 | - Node* value = __ LoadField(AccessBuilder::ForHeapNumberValue(), field); | ||
| 5380 | - __ Goto(&done_double, value); | ||
| 5381 | - } | ||
| 5368 | + __ Bind(&loaded_field); | ||
| 5369 | + { | ||
| 5370 | + Node* field = loaded_field.PhiAt(0); | ||
| 5371 | + // We may have transitioned in-place away from double, so check that | ||
| 5372 | + // this is a HeapNumber -- otherwise the load is fine and we don't need | ||
| 5373 | + // to copy anything anyway. | ||
| 5374 | + __ GotoIf(ObjectIsSmi(field), &done, field); | ||
| 5375 | + Node* field_map = __ LoadField(AccessBuilder::ForMap(), field); | ||
| 5376 | + __ GotoIfNot(__ TaggedEqual(field_map, __ HeapNumberMapConstant()), &done, | ||
| 5377 | + field); | ||
| 5382 | 5378 | ||
| 5383 | - __ Bind(&done_double); | ||
| 5384 | - { | ||
| 5385 | - Node* result = AllocateHeapNumberWithValue(done_double.PhiAt(0)); | ||
| 5386 | - __ Goto(&done, result); | ||
| 5387 | - } | ||
| 5379 | + Node* value = __ LoadField(AccessBuilder::ForHeapNumberValue(), field); | ||
| 5380 | + __ Goto(&done_double, value); | ||
| 5381 | + } | ||
| 5382 | + | ||
| 5383 | + __ Bind(&done_double); | ||
| 5384 | + { | ||
| 5385 | + Node* result = AllocateHeapNumberWithValue(done_double.PhiAt(0)); | ||
| 5386 | + __ Goto(&done, result); | ||
| 5388 | 5387 | } | |
| 5389 | 5388 | ||
| 5390 | 5389 | __ Bind(&done); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -710,9 +710,8 @@ class IteratingArrayBuiltinReducerAssembler : public JSCallReducerAssembler { | |||
| 710 | 710 | MapInference* inference, const bool has_stability_dependency, | |
| 711 | 711 | ElementsKind kind, const SharedFunctionInfoRef& shared, | |
| 712 | 712 | const NativeContextRef& native_context, ArrayEverySomeVariant variant); | |
| 713 | - TNode<Object> ReduceArrayPrototypeAt(ZoneVector<ElementsKind> kinds, | ||
| 714 | - bool needs_fallback_builtin_call, | ||
| 715 | - Node* receiver_kind); | ||
| 713 | + TNode<Object> ReduceArrayPrototypeAt(ZoneVector<const MapRef*> kinds, | ||
| 714 | + bool needs_fallback_builtin_call); | ||
| 716 | 715 | TNode<Object> ReduceArrayPrototypeIndexOfIncludes( | |
| 717 | 716 | ElementsKind kind, ArrayIndexOfIncludesVariant variant); | |
| 718 | 717 | ||
@@ -1323,24 +1322,26 @@ TNode<String> JSCallReducerAssembler::ReduceStringPrototypeSlice() { | |||
| 1323 | 1322 | } | |
| 1324 | 1323 | ||
| 1325 | 1324 | TNode<Object> IteratingArrayBuiltinReducerAssembler::ReduceArrayPrototypeAt( | |
| 1326 | - ZoneVector<ElementsKind> kinds, bool needs_fallback_builtin_call, | ||
| 1327 | - Node* receiver_kind) { | ||
| 1325 | + ZoneVector<const MapRef*> maps, bool needs_fallback_builtin_call) { | ||
| 1328 | 1326 | TNode<JSArray> receiver = ReceiverInputAs<JSArray>(); | |
| 1329 | 1327 | TNode<Object> index = ArgumentOrZero(0); | |
| 1330 | 1328 | ||
| 1331 | 1329 | TNode<Number> index_num = CheckSmi(index); | |
| 1332 | 1330 | TNode<FixedArrayBase> elements = LoadElements(receiver); | |
| 1333 | 1331 | ||
| 1332 | + TNode<Map> receiver_map = | ||
| 1333 | + TNode<Map>::UncheckedCast(LoadField(AccessBuilder::ForMap(), receiver)); | ||
| 1334 | + | ||
| 1334 | 1335 | auto out = MakeLabel(MachineRepresentation::kTagged); | |
| 1335 | 1336 | ||
| 1336 | - for (ElementsKind kind : kinds) { | ||
| 1337 | + for (const MapRef* map : maps) { | ||
| 1338 | + DCHECK(map->supports_fast_array_iteration()); | ||
| 1337 | 1339 | auto correct_map_label = MakeLabel(), wrong_map_label = MakeLabel(); | |
| 1338 | - Branch(NumberEqual(TNode<Number>::UncheckedCast(receiver_kind), | ||
| 1339 | - NumberConstant(kind)), | ||
| 1340 | - &correct_map_label, &wrong_map_label); | ||
| 1340 | + TNode<Boolean> is_map_equal = ReferenceEqual(receiver_map, Constant(*map)); | ||
| 1341 | + Branch(is_map_equal, &correct_map_label, &wrong_map_label); | ||
| 1341 | 1342 | Bind(&correct_map_label); | |
| 1342 | 1343 | ||
| 1343 | - TNode<Number> length = LoadJSArrayLength(receiver, kind); | ||
| 1344 | + TNode<Number> length = LoadJSArrayLength(receiver, map->elements_kind()); | ||
| 1344 | 1345 | ||
| 1345 | 1346 | // If index is less than 0, then subtract from length. | |
| 1346 | 1347 | TNode<Boolean> cond = NumberLessThan(index_num, ZeroConstant()); | |
@@ -1359,15 +1360,16 @@ TNode<Object> IteratingArrayBuiltinReducerAssembler::ReduceArrayPrototypeAt( | |||
| 1359 | 1360 | ||
| 1360 | 1361 | // Retrieving element at index. | |
| 1361 | 1362 | TNode<Object> element = LoadElement<Object>( | |
| 1362 | - AccessBuilder::ForFixedArrayElement(kind), elements, real_index_num); | ||
| 1363 | - if (IsHoleyElementsKind(kind)) { | ||
| 1363 | + AccessBuilder::ForFixedArrayElement(map->elements_kind()), elements, | ||
| 1364 | + real_index_num); | ||
| 1365 | + if (IsHoleyElementsKind(map->elements_kind())) { | ||
| 1364 | 1366 | // This case is needed in particular for HOLEY_DOUBLE_ELEMENTS: raw | |
| 1365 | 1367 | // doubles are stored in the FixedDoubleArray, and need to be converted to | |
| 1366 | 1368 | // HeapNumber or to Smi so that this function can return an Object. The | |
| 1367 | 1369 | // automatic converstion performed by | |
| 1368 | 1370 | // RepresentationChanger::GetTaggedRepresentationFor does not handle | |
| 1369 | 1371 | // holes, so we convert manually a potential hole here. | |
| 1370 | - element = TryConvertHoleToUndefined(element, kind); | ||
| 1372 | + element = TryConvertHoleToUndefined(element, map->elements_kind()); | ||
| 1371 | 1373 | } | |
| 1372 | 1374 | Goto(&out, element); | |
| 1373 | 1375 | ||
@@ -5633,25 +5635,22 @@ Reduction JSCallReducer::ReduceArrayPrototypeAt(Node* node) { | |||
| 5633 | 5635 | MapInference inference(broker(), receiver, effect); | |
| 5634 | 5636 | if (!inference.HaveMaps()) return NoChange(); | |
| 5635 | 5637 | ||
| 5636 | - // Collecting kinds | ||
| 5637 | - ZoneVector<ElementsKind> kinds(broker()->zone()); | ||
| 5638 | + // Collecting maps, and checking if a fallback builtin call will be required | ||
| 5639 | + // (it is required if at least one map doesn't support fast array iteration). | ||
| 5640 | + ZoneVector<const MapRef*> maps(broker()->zone()); | ||
| 5638 | 5641 | bool needs_fallback_builtin_call = false; | |
| 5639 | 5642 | for (const MapRef& map : inference.GetMaps()) { | |
| 5640 | 5643 | if (map.supports_fast_array_iteration()) { | |
| 5641 | - ElementsKind kind = map.elements_kind(); | ||
| 5642 | - // Checking that |kind| isn't already in |kinds|. Using std::find should | ||
| 5643 | - // be fast enough since |kinds| can contain at most 4 items. | ||
| 5644 | - if (std::find(kinds.begin(), kinds.end(), kind) == kinds.end()) { | ||
| 5645 | - kinds.push_back(kind); | ||
| 5646 | - } | ||
| 5644 | + maps.push_back(&map); | ||
| 5647 | 5645 | } else { | |
| 5648 | 5646 | needs_fallback_builtin_call = true; | |
| 5649 | 5647 | } | |
| 5650 | 5648 | } | |
| 5649 | + | ||
| 5651 | 5650 | inference.RelyOnMapsPreferStability(dependencies(), jsgraph(), &effect, | |
| 5652 | 5651 | control, p.feedback()); | |
| 5653 | 5652 | ||
| 5654 | - if (kinds.empty()) { | ||
| 5653 | + if (maps.empty()) { | ||
| 5655 | 5654 | // No map in the feedback supports fast iteration. Keeping the builtin call. | |
| 5656 | 5655 | return NoChange(); | |
| 5657 | 5656 | } | |
@@ -5660,13 +5659,11 @@ Reduction JSCallReducer::ReduceArrayPrototypeAt(Node* node) { | |||
| 5660 | 5659 | return NoChange(); | |
| 5661 | 5660 | } | |
| 5662 | 5661 | ||
| 5663 | - Node* receiver_kind = LoadReceiverElementsKind(receiver, &effect, control); | ||
| 5664 | - | ||
| 5665 | 5662 | IteratingArrayBuiltinReducerAssembler a(this, node); | |
| 5666 | 5663 | a.InitializeEffectControl(effect, control); | |
| 5667 | 5664 | ||
| 5668 | - TNode<Object> subgraph = a.ReduceArrayPrototypeAt( | ||
| 5669 | - kinds, needs_fallback_builtin_call, receiver_kind); | ||
| 5665 | + TNode<Object> subgraph = | ||
| 5666 | + a.ReduceArrayPrototypeAt(maps, needs_fallback_builtin_call); | ||
| 5670 | 5667 | return ReplaceWithSubgraph(&a, subgraph); | |
| 5671 | 5668 | } | |
| 5672 | 5669 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments