| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent adb4043 commit 8716146
9 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,7 +11,7 @@ | |||
| 11 | 11 | #define V8_MAJOR_VERSION 14 | |
| 12 | 12 | #define V8_MINOR_VERSION 3 | |
| 13 | 13 | #define V8_BUILD_NUMBER 127 | |
| 14 | - #define V8_PATCH_LEVEL 12 | ||
| 14 | + #define V8_PATCH_LEVEL 14 | ||
| 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 | |
|---|---|---|---|
@@ -4,6 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | 5 | #include "src/compiler/access-builder.h" | |
| 6 | 6 | ||
| 7 | + #include "src/codegen/machine-type.h" | ||
| 8 | + #include "src/compiler/property-access-builder.h" | ||
| 7 | 9 | #include "src/compiler/type-cache.h" | |
| 8 | 10 | #include "src/handles/handles-inl.h" | |
| 9 | 11 | #include "src/objects/arguments.h" | |
@@ -1097,12 +1099,16 @@ FieldAccess AccessBuilder::ForFeedbackVectorSlot(int index) { | |||
| 1097 | 1099 | } | |
| 1098 | 1100 | ||
| 1099 | 1101 | // static | |
| 1100 | - FieldAccess AccessBuilder::ForPropertyArraySlot(int index) { | ||
| 1102 | + FieldAccess AccessBuilder::ForPropertyArraySlot(int index, | ||
| 1103 | + Representation representation) { | ||
| 1101 | 1104 | int offset = PropertyArray::OffsetOfElementAt(index); | |
| 1102 | - FieldAccess access = {kTaggedBase, offset, | ||
| 1103 | - Handle<Name>(), OptionalMapRef(), | ||
| 1104 | - Type::Any(), MachineType::AnyTagged(), | ||
| 1105 | - kFullWriteBarrier, "PropertyArraySlot"}; | ||
| 1105 | + MachineType machine_type = | ||
| 1106 | + representation.IsHeapObject() || representation.IsDouble() | ||
| 1107 | + ? MachineType::TaggedPointer() | ||
| 1108 | + : MachineType::AnyTagged(); | ||
| 1109 | + FieldAccess access = { | ||
| 1110 | + kTaggedBase, offset, Handle<Name>(), OptionalMapRef(), | ||
| 1111 | + Type::Any(), machine_type, kFullWriteBarrier, "PropertyArraySlot"}; | ||
| 1106 | 1112 | return access; | |
| 1107 | 1113 | } | |
| 1108 | 1114 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,6 +11,7 @@ | |||
| 11 | 11 | #include "src/compiler/write-barrier-kind.h" | |
| 12 | 12 | #include "src/objects/elements-kind.h" | |
| 13 | 13 | #include "src/objects/js-objects.h" | |
| 14 | + #include "src/objects/property-details.h" | ||
| 14 | 15 | ||
| 15 | 16 | namespace v8 { | |
| 16 | 17 | namespace internal { | |
@@ -323,7 +324,8 @@ class V8_EXPORT_PRIVATE AccessBuilder final | |||
| 323 | 324 | static FieldAccess ForFeedbackVectorSlot(int index); | |
| 324 | 325 | ||
| 325 | 326 | // Provides access to PropertyArray slots. | |
| 326 | - static FieldAccess ForPropertyArraySlot(int index); | ||
| 327 | + static FieldAccess ForPropertyArraySlot(int index, | ||
| 328 | + Representation representation); | ||
| 327 | 329 | ||
| 328 | 330 | // Provides access to ScopeInfo flags. | |
| 329 | 331 | static FieldAccess ForScopeInfoFlags(); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -38,6 +38,7 @@ | |||
| 38 | 38 | #include "src/objects/elements-kind.h" | |
| 39 | 39 | #include "src/objects/feedback-vector.h" | |
| 40 | 40 | #include "src/objects/heap-number.h" | |
| 41 | + #include "src/objects/property-details.h" | ||
| 41 | 42 | #include "src/objects/string.h" | |
| 42 | 43 | ||
| 43 | 44 | namespace v8 { | |
@@ -4235,25 +4236,59 @@ Node* JSNativeContextSpecialization::BuildExtendPropertiesBackingStore( | |||
| 4235 | 4236 | // for intermediate states of chains of property additions. That makes | |
| 4236 | 4237 | // it unclear what the best approach is here. | |
| 4237 | 4238 | DCHECK_EQ(map.UnusedPropertyFields(), 0); | |
| 4238 | - int length = map.NextFreePropertyIndex() - map.GetInObjectProperties(); | ||
| 4239 | + int in_object_length = map.GetInObjectProperties(); | ||
| 4240 | + int length = map.NextFreePropertyIndex() - in_object_length; | ||
| 4239 | 4241 | // Under normal circumstances, NextFreePropertyIndex() will always be larger | |
| 4240 | 4242 | // than GetInObjectProperties(). However, an attacker able to corrupt heap | |
| 4241 | 4243 | // memory can break this invariant, in which case we'll get confused here, | |
| 4242 | 4244 | // potentially causing a sandbox violation. This CHECK defends against that. | |
| 4243 | 4245 | SBXCHECK_GE(length, 0); | |
| 4244 | 4246 | int new_length = length + JSObject::kFieldsAdded; | |
| 4247 | + | ||
| 4248 | + // Find the descriptor index corresponding to the first out-of-object | ||
| 4249 | + // property. | ||
| 4250 | + DescriptorArrayRef descs = map.instance_descriptors(broker()); | ||
| 4251 | + InternalIndex first_out_of_object_descriptor(in_object_length); | ||
| 4252 | + InternalIndex number_of_descriptors(descs.object()->number_of_descriptors()); | ||
| 4253 | + for (InternalIndex i(in_object_length); i < number_of_descriptors; ++i) { | ||
| 4254 | + PropertyDetails details = descs.GetPropertyDetails(i); | ||
| 4255 | + // Skip over non-field properties. | ||
| 4256 | + if (details.location() != PropertyLocation::kField) { | ||
| 4257 | + continue; | ||
| 4258 | + } | ||
| 4259 | + // Skip over in-object fields. | ||
| 4260 | + // TODO(leszeks): We could make this smarter, like a binary search. | ||
| 4261 | + if (details.field_index() < in_object_length) { | ||
| 4262 | + continue; | ||
| 4263 | + } | ||
| 4264 | + first_out_of_object_descriptor = i; | ||
| 4265 | + break; | ||
| 4266 | + } | ||
| 4267 | + | ||
| 4245 | 4268 | // Collect the field values from the {properties}. | |
| 4246 | - ZoneVector<Node*> values(zone()); | ||
| 4269 | + ZoneVector<std::pair<Node*, Representation>> values(zone()); | ||
| 4247 | 4270 | values.reserve(new_length); | |
| 4248 | - for (int i = 0; i < length; ++i) { | ||
| 4271 | + | ||
| 4272 | + // Walk the property descriptors alongside the property values, to make | ||
| 4273 | + // sure to get and store them with the right machine type. | ||
| 4274 | + InternalIndex descriptor = first_out_of_object_descriptor; | ||
| 4275 | + for (int i = 0; i < length; ++i, ++descriptor) { | ||
| 4276 | + PropertyDetails details = descs.GetPropertyDetails(descriptor); | ||
| 4277 | + while (details.location() != PropertyLocation::kField) { | ||
| 4278 | + ++descriptor; | ||
| 4279 | + details = descs.GetPropertyDetails(descriptor); | ||
| 4280 | + } | ||
| 4281 | + DCHECK_EQ(i, details.field_index() - in_object_length); | ||
| 4249 | 4282 | Node* value = effect = graph()->NewNode( | |
| 4250 | - simplified()->LoadField(AccessBuilder::ForFixedArraySlot(i)), | ||
| 4283 | + simplified()->LoadField( | ||
| 4284 | + AccessBuilder::ForPropertyArraySlot(i, details.representation())), | ||
| 4251 | 4285 | properties, effect, control); | |
| 4252 | - values.push_back(value); | ||
| 4286 | + values.push_back({value, details.representation()}); | ||
| 4253 | 4287 | } | |
| 4254 | 4288 | // Initialize the new fields to undefined. | |
| 4255 | 4289 | for (int i = 0; i < JSObject::kFieldsAdded; ++i) { | |
| 4256 | - values.push_back(jsgraph()->UndefinedConstant()); | ||
| 4290 | + values.push_back( | ||
| 4291 | + {jsgraph()->UndefinedConstant(), Representation::Tagged()}); | ||
| 4257 | 4292 | } | |
| 4258 | 4293 | ||
| 4259 | 4294 | // Compute new length and hash. | |
@@ -4291,7 +4326,8 @@ Node* JSNativeContextSpecialization::BuildExtendPropertiesBackingStore( | |||
| 4291 | 4326 | a.Store(AccessBuilder::ForMap(), jsgraph()->PropertyArrayMapConstant()); | |
| 4292 | 4327 | a.Store(AccessBuilder::ForPropertyArrayLengthAndHash(), new_length_and_hash); | |
| 4293 | 4328 | for (int i = 0; i < new_length; ++i) { | |
| 4294 | - a.Store(AccessBuilder::ForFixedArraySlot(i), values[i]); | ||
| 4329 | + a.Store(AccessBuilder::ForPropertyArraySlot(i, values[i].second), | ||
| 4330 | + values[i].first); | ||
| 4295 | 4331 | } | |
| 4296 | 4332 | return a.Finish(); | |
| 4297 | 4333 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -14,6 +14,7 @@ | |||
| 14 | 14 | #include "src/compiler/turboshaft/representations.h" | |
| 15 | 15 | #include "src/deoptimizer/deoptimize-reason.h" | |
| 16 | 16 | #include "src/objects/contexts.h" | |
| 17 | + #include "src/objects/descriptor-array-inl.h" | ||
| 17 | 18 | #include "src/objects/instance-type-inl.h" | |
| 18 | 19 | ||
| 19 | 20 | namespace v8::internal::compiler::turboshaft { | |
@@ -325,8 +326,32 @@ class TurbolevEarlyLoweringReducer : public Next { | |||
| 325 | 326 | } | |
| 326 | 327 | ||
| 327 | 328 | V<PropertyArray> ExtendPropertiesBackingStore( | |
| 328 | - V<PropertyArray> old_property_array, V<JSObject> object, int old_length, | ||
| 329 | + V<PropertyArray> old_property_array, V<JSObject> object, | ||
| 330 | + const compiler::MapRef& old_map, int old_length, | ||
| 329 | 331 | V<FrameState> frame_state, const FeedbackSource& feedback) { | |
| 332 | + int in_object_length = old_map.GetInObjectProperties(); | ||
| 333 | + | ||
| 334 | + // Find the descriptor index corresponding to the first out-of-object | ||
| 335 | + // property. | ||
| 336 | + DescriptorArrayRef descs = old_map.instance_descriptors(broker_); | ||
| 337 | + InternalIndex first_out_of_object_descriptor(in_object_length); | ||
| 338 | + InternalIndex number_of_descriptors( | ||
| 339 | + descs.object()->number_of_descriptors()); | ||
| 340 | + for (InternalIndex i(in_object_length); i < number_of_descriptors; ++i) { | ||
| 341 | + PropertyDetails details = descs.GetPropertyDetails(i); | ||
| 342 | + // Skip over non-field properties. | ||
| 343 | + if (details.location() != PropertyLocation::kField) { | ||
| 344 | + continue; | ||
| 345 | + } | ||
| 346 | + // Skip over in-object fields. | ||
| 347 | + // TODO(leszeks): We could make this smarter, like a binary search. | ||
| 348 | + if (details.field_index() < in_object_length) { | ||
| 349 | + continue; | ||
| 350 | + } | ||
| 351 | + first_out_of_object_descriptor = i; | ||
| 352 | + break; | ||
| 353 | + } | ||
| 354 | + | ||
| 330 | 355 | // Allocate new PropertyArray. | |
| 331 | 356 | int new_length = old_length + JSObject::kFieldsAdded; | |
| 332 | 357 | Uninitialized<PropertyArray> new_property_array = | |
@@ -337,18 +362,28 @@ class TurbolevEarlyLoweringReducer : public Next { | |||
| 337 | 362 | __ HeapConstant(factory_->property_array_map())); | |
| 338 | 363 | ||
| 339 | 364 | // Copy existing properties over. | |
| 340 | - for (int i = 0; i < old_length; i++) { | ||
| 365 | + InternalIndex descriptor = first_out_of_object_descriptor; | ||
| 366 | + for (int i = 0; i < old_length; ++i, ++descriptor) { | ||
| 367 | + PropertyDetails details = descs.GetPropertyDetails(descriptor); | ||
| 368 | + while (details.location() != PropertyLocation::kField) { | ||
| 369 | + ++descriptor; | ||
| 370 | + details = descs.GetPropertyDetails(descriptor); | ||
| 371 | + } | ||
| 372 | + DCHECK_EQ(i, details.field_index() - in_object_length); | ||
| 373 | + Representation r = details.representation(); | ||
| 374 | + | ||
| 341 | 375 | V<Object> old_value = __ template LoadField<Object>( | |
| 342 | - old_property_array, AccessBuilder::ForPropertyArraySlot(i)); | ||
| 376 | + old_property_array, AccessBuilder::ForPropertyArraySlot(i, r)); | ||
| 343 | 377 | __ InitializeField(new_property_array, | |
| 344 | - AccessBuilder::ForPropertyArraySlot(i), old_value); | ||
| 378 | + AccessBuilder::ForPropertyArraySlot(i, r), old_value); | ||
| 345 | 379 | } | |
| 346 | 380 | ||
| 347 | 381 | // Initialize new properties to undefined. | |
| 348 | 382 | V<Undefined> undefined = __ HeapConstant(factory_->undefined_value()); | |
| 349 | 383 | for (int i = 0; i < JSObject::kFieldsAdded; ++i) { | |
| 350 | 384 | __ InitializeField(new_property_array, | |
| 351 | - AccessBuilder::ForPropertyArraySlot(old_length + i), | ||
| 385 | + AccessBuilder::ForPropertyArraySlot( | ||
| 386 | + old_length + i, Representation::Tagged()), | ||
| 352 | 387 | undefined); | |
| 353 | 388 | } | |
| 354 | 389 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2752,10 +2752,11 @@ class GraphBuildingNodeProcessor { | |||
| 2752 | 2752 | maglev::ProcessResult Process(maglev::ExtendPropertiesBackingStore* node, | |
| 2753 | 2753 | const maglev::ProcessingState& state) { | |
| 2754 | 2754 | GET_FRAME_STATE_MAYBE_ABORT(frame_state, node->eager_deopt_info()); | |
| 2755 | - SetMap(node, __ ExtendPropertiesBackingStore( | ||
| 2756 | - Map(node->property_array_input()), | ||
| 2757 | - Map(node->object_input()), node->old_length(), frame_state, | ||
| 2758 | - node->eager_deopt_info()->feedback_to_update())); | ||
| 2755 | + SetMap(node, | ||
| 2756 | + __ ExtendPropertiesBackingStore( | ||
| 2757 | + Map(node->property_array_input()), Map(node->object_input()), | ||
| 2758 | + node->old_map(), node->old_length(), frame_state, | ||
| 2759 | + node->eager_deopt_info()->feedback_to_update())); | ||
| 2759 | 2760 | return maglev::ProcessResult::kContinue; | |
| 2760 | 2761 | } | |
| 2761 | 2762 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2517,7 +2517,9 @@ IGNITION_HANDLER(SwitchOnSmiNoFeedback, InterpreterAssembler) { | |||
| 2517 | 2517 | GotoIf(IntPtrGreaterThanOrEqual(case_value, table_length), &fall_through); | |
| 2518 | 2518 | ||
| 2519 | 2519 | TNode<WordT> entry = IntPtrAdd(table_start, case_value); | |
| 2520 | - TNode<IntPtrT> relative_jump = LoadAndUntagConstantPoolEntry(entry); | ||
| 2520 | + TNode<Object> constant_entry = LoadConstantPoolEntry(entry); | ||
| 2521 | + CSA_SBXCHECK(this, TaggedIsSmi(constant_entry)); | ||
| 2522 | + TNode<IntPtrT> relative_jump = SmiUntag(CAST(constant_entry)); | ||
| 2521 | 2523 | Jump(relative_jump); | |
| 2522 | 2524 | ||
| 2523 | 2525 | BIND(&fall_through); | |
@@ -3437,7 +3439,9 @@ IGNITION_HANDLER(SwitchOnGeneratorState, InterpreterAssembler) { | |||
| 3437 | 3439 | USE(table_length); // SBXCHECK is a DCHECK when the sandbox is disabled. | |
| 3438 | 3440 | ||
| 3439 | 3441 | TNode<WordT> entry = IntPtrAdd(table_start, case_value); | |
| 3440 | - TNode<IntPtrT> relative_jump = LoadAndUntagConstantPoolEntry(entry); | ||
| 3442 | + TNode<Object> constant_entry = LoadConstantPoolEntry(entry); | ||
| 3443 | + CSA_SBXCHECK(this, TaggedIsSmi(constant_entry)); | ||
| 3444 | + TNode<IntPtrT> relative_jump = SmiUntag(CAST(constant_entry)); | ||
| 3441 | 3445 | Jump(relative_jump); | |
| 3442 | 3446 | ||
| 3443 | 3447 | BIND(&fallthrough); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5225,7 +5225,7 @@ ReduceResult MaglevGraphBuilder::BuildExtendPropertiesBackingStore( | |||
| 5225 | 5225 | // potentially causing a sandbox violation. This CHECK defends against that. | |
| 5226 | 5226 | SBXCHECK_GE(length, 0); | |
| 5227 | 5227 | return AddNewNode<ExtendPropertiesBackingStore>({property_array, receiver}, | |
| 5228 | - length); | ||
| 5228 | + map, length); | ||
| 5229 | 5229 | } | |
| 5230 | 5230 | ||
| 5231 | 5231 | MaybeReduceResult MaglevGraphBuilder::TryBuildStoreField( | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -9441,8 +9441,10 @@ class ExtendPropertiesBackingStore | |||
| 9441 | 9441 | using Base = FixedInputValueNodeT<2, ExtendPropertiesBackingStore>; | |
| 9442 | 9442 | ||
| 9443 | 9443 | public: | |
| 9444 | - explicit ExtendPropertiesBackingStore(uint64_t bitfield, int old_length) | ||
| 9445 | - : Base(bitfield), old_length_(old_length) {} | ||
| 9444 | + explicit ExtendPropertiesBackingStore(uint64_t bitfield, | ||
| 9445 | + const compiler::MapRef& old_map, | ||
| 9446 | + int old_length) | ||
| 9447 | + : Base(bitfield), old_map_(old_map), old_length_(old_length) {} | ||
| 9446 | 9448 | ||
| 9447 | 9449 | static constexpr OpProperties kProperties = | |
| 9448 | 9450 | OpProperties::CanAllocate() | OpProperties::CanRead() | | |
@@ -9462,9 +9464,11 @@ class ExtendPropertiesBackingStore | |||
| 9462 | 9464 | void GenerateCode(MaglevAssembler*, const ProcessingState&); | |
| 9463 | 9465 | void PrintParams(std::ostream&) const; | |
| 9464 | 9466 | ||
| 9467 | + const compiler::MapRef& old_map() const { return old_map_; } | ||
| 9465 | 9468 | int old_length() const { return old_length_; } | |
| 9466 | 9469 | ||
| 9467 | 9470 | private: | |
| 9471 | + const compiler::MapRef old_map_; | ||
| 9468 | 9472 | const int old_length_; | |
| 9469 | 9473 | }; | |
| 9470 | 9474 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments