Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Side by Side Diff: src/compiler/js-native-context-specialization.cc

Issue 1424523002: [turbofan] Fix and enable property stores. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix invalid type. Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/js-native-context-specialization.h" 5 #include "src/compiler/js-native-context-specialization.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/compilation-dependencies.h" 8 #include "src/compilation-dependencies.h"
9 #include "src/compiler/access-builder.h" 9 #include "src/compiler/access-builder.h"
10 #include "src/compiler/js-graph.h" 10 #include "src/compiler/js-graph.h"
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 !map->is_access_check_needed(); 305 !map->is_access_check_needed();
306 } 306 }
307 307
308 } // namespace 308 } // namespace
309 309
310 310
311 bool JSNativeContextSpecialization::ComputePropertyAccessInfo( 311 bool JSNativeContextSpecialization::ComputePropertyAccessInfo(
312 Handle<Map> map, Handle<Name> name, PropertyAccessMode access_mode, 312 Handle<Map> map, Handle<Name> name, PropertyAccessMode access_mode,
313 PropertyAccessInfo* access_info) { 313 PropertyAccessInfo* access_info) {
314 MaybeHandle<JSObject> holder; 314 MaybeHandle<JSObject> holder;
315 Type* receiver_type = Type::Class(map, graph()->zone()); 315 Handle<Map> receiver_map = map;
316 Type* receiver_type = Type::Class(receiver_map, graph()->zone());
316 while (CanInlinePropertyAccess(map)) { 317 while (CanInlinePropertyAccess(map)) {
317 // Check for special JSObject field accessors. 318 // Check for special JSObject field accessors.
318 int offset; 319 int offset;
319 if (Accessors::IsJSObjectFieldAccessor(map, name, &offset)) { 320 if (Accessors::IsJSObjectFieldAccessor(map, name, &offset)) {
320 // Don't bother optimizing stores to special JSObject field accessors. 321 // Don't bother optimizing stores to special JSObject field accessors.
321 if (access_mode == kStore) { 322 if (access_mode == kStore) {
322 break; 323 break;
323 } 324 }
324 FieldIndex field_index = FieldIndex::ForInObjectOffset(offset); 325 FieldIndex field_index = FieldIndex::ForInObjectOffset(offset);
325 Type* field_type = Type::Tagged(); 326 Type* field_type = Type::Tagged();
(...skipping 23 matching lines...) Expand all
349 } 350 }
350 *access_info = PropertyAccessInfo::DataField(receiver_type, field_index, 351 *access_info = PropertyAccessInfo::DataField(receiver_type, field_index,
351 field_type, holder); 352 field_type, holder);
352 return true; 353 return true;
353 } 354 }
354 355
355 // Lookup the named property on the {map}. 356 // Lookup the named property on the {map}.
356 Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate()); 357 Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate());
357 int const number = descriptors->SearchWithCache(*name, *map); 358 int const number = descriptors->SearchWithCache(*name, *map);
358 if (number != DescriptorArray::kNotFound) { 359 if (number != DescriptorArray::kNotFound) {
360 if (access_mode == kStore && !map.is_identical_to(receiver_map)) {
361 return false;
362 }
359 PropertyDetails const details = descriptors->GetDetails(number); 363 PropertyDetails const details = descriptors->GetDetails(number);
360 if (details.type() == DATA_CONSTANT) { 364 if (details.type() == DATA_CONSTANT) {
361 *access_info = PropertyAccessInfo::DataConstant( 365 *access_info = PropertyAccessInfo::DataConstant(
362 receiver_type, handle(descriptors->GetValue(number), isolate()), 366 receiver_type, handle(descriptors->GetValue(number), isolate()),
363 holder); 367 holder);
364 return true; 368 return true;
365 } else if (details.type() == DATA) { 369 } else if (details.type() == DATA) {
366 // Don't bother optimizing stores to read-only properties. 370 // Don't bother optimizing stores to read-only properties.
367 if (access_mode == kStore) { 371 if (access_mode == kStore && details.IsReadOnly()) {
368 break; 372 break;
369 } 373 }
370 int index = descriptors->GetFieldIndex(number); 374 int index = descriptors->GetFieldIndex(number);
371 Representation field_representation = details.representation(); 375 Representation field_representation = details.representation();
372 FieldIndex field_index = FieldIndex::ForPropertyIndex( 376 FieldIndex field_index = FieldIndex::ForPropertyIndex(
373 *map, index, field_representation.IsDouble()); 377 *map, index, field_representation.IsDouble());
374 Type* field_type = Type::Any(); 378 Type* field_type = Type::Tagged();
375 if (field_representation.IsSmi()) { 379 if (field_representation.IsSmi()) {
376 field_type = Type::Intersect(Type::SignedSmall(), 380 field_type = Type::Intersect(Type::SignedSmall(),
377 Type::TaggedSigned(), graph()->zone()); 381 Type::TaggedSigned(), graph()->zone());
378 } else if (field_representation.IsDouble()) { 382 } else if (field_representation.IsDouble()) {
379 if (access_mode == kStore) { 383 if (access_mode == kStore) {
380 // TODO(bmeurer): Add support for storing to double fields. 384 // TODO(bmeurer): Add support for storing to double fields.
381 break; 385 break;
382 } 386 }
383 field_type = Type::Intersect(Type::Number(), Type::UntaggedFloat64(), 387 field_type = Type::Intersect(Type::Number(), Type::UntaggedFloat64(),
384 graph()->zone()); 388 graph()->zone());
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 } 451 }
448 return false; 452 return false;
449 } 453 }
450 454
451 455
452 bool JSNativeContextSpecialization::ComputePropertyAccessInfos( 456 bool JSNativeContextSpecialization::ComputePropertyAccessInfos(
453 MapHandleList const& maps, Handle<Name> name, 457 MapHandleList const& maps, Handle<Name> name,
454 PropertyAccessMode access_mode, 458 PropertyAccessMode access_mode,
455 ZoneVector<PropertyAccessInfo>* access_infos) { 459 ZoneVector<PropertyAccessInfo>* access_infos) {
456 for (Handle<Map> map : maps) { 460 for (Handle<Map> map : maps) {
457 PropertyAccessInfo access_info; 461 if (Map::TryUpdate(map).ToHandle(&map)) {
458 if (!ComputePropertyAccessInfo(map, name, access_mode, &access_info)) { 462 PropertyAccessInfo access_info;
459 return false; 463 if (!ComputePropertyAccessInfo(map, name, access_mode, &access_info)) {
464 return false;
465 }
466 access_infos->push_back(access_info);
460 } 467 }
461 access_infos->push_back(access_info);
462 } 468 }
463 return true; 469 return true;
464 } 470 }
465 471
466 472
467 Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) { 473 Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) {
468 DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode()); 474 DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode());
469 NamedAccess const& p = NamedAccessOf(node->op()); 475 NamedAccess const& p = NamedAccessOf(node->op());
470 Handle<Name> name = p.name(); 476 Handle<Name> name = p.name();
471 Node* receiver = NodeProperties::GetValueInput(node, 0); 477 Node* receiver = NodeProperties::GetValueInput(node, 0);
472 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); 478 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
473 Node* effect = NodeProperties::GetEffectInput(node); 479 Node* effect = NodeProperties::GetEffectInput(node);
474 Node* control = NodeProperties::GetControlInput(node); 480 Node* control = NodeProperties::GetControlInput(node);
475 481
476 // Not much we can do if deoptimization support is disabled. 482 // Not much we can do if deoptimization support is disabled.
477 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); 483 if (!(flags() & kDeoptimizationEnabled)) return NoChange();
478 484
479 // Extract receiver maps from the LOAD_IC using the LoadICNexus. 485 // Extract receiver maps from the LOAD_IC using the LoadICNexus.
480 MapHandleList receiver_maps; 486 MapHandleList receiver_maps;
481 if (!p.feedback().IsValid()) return NoChange(); 487 if (!p.feedback().IsValid()) return NoChange();
482 LoadICNexus nexus(p.feedback().vector(), p.feedback().slot()); 488 LoadICNexus nexus(p.feedback().vector(), p.feedback().slot());
483 if (nexus.ExtractMaps(&receiver_maps) == 0) return NoChange(); 489 if (nexus.ExtractMaps(&receiver_maps) == 0) return NoChange();
484 DCHECK_LT(0, receiver_maps.length()); 490 DCHECK_LT(0, receiver_maps.length());
485 491
486 // Compute property access infos for the receiver maps. 492 // Compute property access infos for the receiver maps.
487 ZoneVector<PropertyAccessInfo> access_infos(zone()); 493 ZoneVector<PropertyAccessInfo> access_infos(zone());
488 if (!ComputePropertyAccessInfos(receiver_maps, name, kLoad, &access_infos)) { 494 if (!ComputePropertyAccessInfos(receiver_maps, name, kLoad, &access_infos)) {
489 return NoChange(); 495 return NoChange();
490 } 496 }
491 DCHECK(!access_infos.empty()); 497
498 // Nothing to do if we have no non-deprecated maps.
499 if (access_infos.empty()) return NoChange();
492 500
493 // The final states for every polymorphic branch. We join them with 501 // The final states for every polymorphic branch. We join them with
494 // Merge+Phi+EffectPhi at the bottom. 502 // Merge+Phi+EffectPhi at the bottom.
495 ZoneVector<Node*> values(zone()); 503 ZoneVector<Node*> values(zone());
496 ZoneVector<Node*> effects(zone()); 504 ZoneVector<Node*> effects(zone());
497 ZoneVector<Node*> controls(zone()); 505 ZoneVector<Node*> controls(zone());
498 506
499 // The list of "exiting" controls, which currently go to a single deoptimize. 507 // The list of "exiting" controls, which currently go to a single deoptimize.
500 // TODO(bmeurer): Consider using an IC as fallback. 508 // TODO(bmeurer): Consider using an IC as fallback.
501 Node* const exit_effect = effect; 509 Node* const exit_effect = effect;
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 this_control = 773 this_control =
766 (this_control_count == 1) 774 (this_control_count == 1)
767 ? this_controls.front() 775 ? this_controls.front()
768 : graph()->NewNode(common()->Merge(this_control_count), 776 : graph()->NewNode(common()->Merge(this_control_count),
769 this_control_count, &this_controls.front()); 777 this_control_count, &this_controls.front());
770 } 778 }
771 779
772 // Determine actual holder and perform prototype chain checks. 780 // Determine actual holder and perform prototype chain checks.
773 Handle<JSObject> holder; 781 Handle<JSObject> holder;
774 if (access_info.holder().ToHandle(&holder)) { 782 if (access_info.holder().ToHandle(&holder)) {
775 this_receiver = jsgraph()->Constant(holder);
776 for (auto i = access_info.receiver_type()->Classes(); !i.Done(); 783 for (auto i = access_info.receiver_type()->Classes(); !i.Done();
777 i.Advance()) { 784 i.Advance()) {
778 Handle<Map> map = i.Current(); 785 Handle<Map> map = i.Current();
779 PrototypeIterator j(map); 786 PrototypeIterator j(map);
780 while (true) { 787 while (true) {
781 // Check that the {prototype} still has the same map. For stable 788 // Check that the {prototype} still has the same map. For stable
782 // maps, we can add a stability dependency on the prototype map; 789 // maps, we can add a stability dependency on the prototype map;
783 // for everything else we need to perform a map check at runtime. 790 // for everything else we need to perform a map check at runtime.
784 Handle<JSReceiver> prototype = 791 Handle<JSReceiver> prototype =
785 PrototypeIterator::GetCurrent<JSReceiver>(j); 792 PrototypeIterator::GetCurrent<JSReceiver>(j);
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
972 } 979 }
973 980
974 981
975 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { 982 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const {
976 return jsgraph()->simplified(); 983 return jsgraph()->simplified();
977 } 984 }
978 985
979 } // namespace compiler 986 } // namespace compiler
980 } // namespace internal 987 } // namespace internal
981 } // namespace v8 988 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698