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

Side by Side Diff: src/arm/stub-cache-arm.cc

Issue 14146005: Track representations of fields (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add test for tracking fields Created 7 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « src/arm/macro-assembler-arm.cc ('k') | src/bootstrapper.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 458
459 // Check that the map of the object hasn't changed. 459 // Check that the map of the object hasn't changed.
460 __ CheckMap(receiver_reg, scratch1, Handle<Map>(object->map()), miss_label, 460 __ CheckMap(receiver_reg, scratch1, Handle<Map>(object->map()), miss_label,
461 DO_SMI_CHECK, REQUIRE_EXACT_MAP); 461 DO_SMI_CHECK, REQUIRE_EXACT_MAP);
462 462
463 // Perform global security token check if needed. 463 // Perform global security token check if needed.
464 if (object->IsJSGlobalProxy()) { 464 if (object->IsJSGlobalProxy()) {
465 __ CheckAccessGlobalProxy(receiver_reg, scratch1, miss_label); 465 __ CheckAccessGlobalProxy(receiver_reg, scratch1, miss_label);
466 } 466 }
467 467
468 int descriptor = transition->LastAdded();
469 DescriptorArray* descriptors = transition->instance_descriptors();
470 PropertyDetails details = descriptors->GetDetails(descriptor);
471 Representation representation = details.representation();
472 ASSERT(!representation.IsNone());
473
474 // Ensure no transitions to deprecated maps are followed.
475 __ CheckMapDeprecated(transition, scratch1, miss_label);
476
477 if (FLAG_track_fields && representation.IsSmi()) {
478 __ JumpIfNotSmi(value_reg, miss_label);
479 } else if (FLAG_track_double_fields && representation.IsDouble()) {
480 Label do_store;
481 __ JumpIfSmi(value_reg, &do_store);
482 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex,
483 miss_label, DONT_DO_SMI_CHECK);
484 __ bind(&do_store);
485 }
486
468 // Check that we are allowed to write this. 487 // Check that we are allowed to write this.
469 if (object->GetPrototype()->IsJSObject()) { 488 if (object->GetPrototype()->IsJSObject()) {
470 JSObject* holder; 489 JSObject* holder;
471 // holder == object indicates that no property was found. 490 // holder == object indicates that no property was found.
472 if (lookup->holder() != *object) { 491 if (lookup->holder() != *object) {
473 holder = lookup->holder(); 492 holder = lookup->holder();
474 } else { 493 } else {
475 // Find the top object. 494 // Find the top object.
476 holder = *object; 495 holder = *object;
477 do { 496 do {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 // face of a transition we can use the old map here because the size of the 559 // face of a transition we can use the old map here because the size of the
541 // object and the number of in-object properties is not going to change. 560 // object and the number of in-object properties is not going to change.
542 index -= object->map()->inobject_properties(); 561 index -= object->map()->inobject_properties();
543 562
544 // TODO(verwaest): Share this code as a code stub. 563 // TODO(verwaest): Share this code as a code stub.
545 if (index < 0) { 564 if (index < 0) {
546 // Set the property straight into the object. 565 // Set the property straight into the object.
547 int offset = object->map()->instance_size() + (index * kPointerSize); 566 int offset = object->map()->instance_size() + (index * kPointerSize);
548 __ str(value_reg, FieldMemOperand(receiver_reg, offset)); 567 __ str(value_reg, FieldMemOperand(receiver_reg, offset));
549 568
550 // Skip updating write barrier if storing a smi. 569 if (!FLAG_track_fields || !representation.IsSmi()) {
551 __ JumpIfSmi(value_reg, &exit); 570 // Skip updating write barrier if storing a smi.
571 __ JumpIfSmi(value_reg, &exit);
552 572
553 // Update the write barrier for the array address. 573 // Update the write barrier for the array address.
554 // Pass the now unused name_reg as a scratch register. 574 // Pass the now unused name_reg as a scratch register.
555 __ mov(name_reg, value_reg); 575 __ mov(name_reg, value_reg);
556 __ RecordWriteField(receiver_reg, 576 __ RecordWriteField(receiver_reg,
557 offset, 577 offset,
558 name_reg, 578 name_reg,
559 scratch1, 579 scratch1,
560 kLRHasNotBeenSaved, 580 kLRHasNotBeenSaved,
561 kDontSaveFPRegs); 581 kDontSaveFPRegs);
582 }
562 } else { 583 } else {
563 // Write to the properties array. 584 // Write to the properties array.
564 int offset = index * kPointerSize + FixedArray::kHeaderSize; 585 int offset = index * kPointerSize + FixedArray::kHeaderSize;
565 // Get the properties array 586 // Get the properties array
566 __ ldr(scratch1, 587 __ ldr(scratch1,
567 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 588 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
568 __ str(value_reg, FieldMemOperand(scratch1, offset)); 589 __ str(value_reg, FieldMemOperand(scratch1, offset));
569 590
570 // Skip updating write barrier if storing a smi. 591 if (!FLAG_track_fields || !representation.IsSmi()) {
571 __ JumpIfSmi(value_reg, &exit); 592 // Skip updating write barrier if storing a smi.
593 __ JumpIfSmi(value_reg, &exit);
572 594
573 // Update the write barrier for the array address. 595 // Update the write barrier for the array address.
574 // Ok to clobber receiver_reg and name_reg, since we return. 596 // Ok to clobber receiver_reg and name_reg, since we return.
575 __ mov(name_reg, value_reg); 597 __ mov(name_reg, value_reg);
576 __ RecordWriteField(scratch1, 598 __ RecordWriteField(scratch1,
577 offset, 599 offset,
578 name_reg, 600 name_reg,
579 receiver_reg, 601 receiver_reg,
580 kLRHasNotBeenSaved, 602 kLRHasNotBeenSaved,
581 kDontSaveFPRegs); 603 kDontSaveFPRegs);
604 }
582 } 605 }
583 606
584 // Return the value (register r0). 607 // Return the value (register r0).
585 ASSERT(value_reg.is(r0)); 608 ASSERT(value_reg.is(r0));
586 __ bind(&exit); 609 __ bind(&exit);
587 __ Ret(); 610 __ Ret();
588 } 611 }
589 612
590 613
591 // Generate StoreField code, value is passed in r0 register. 614 // Generate StoreField code, value is passed in r0 register.
(...skipping 25 matching lines...) Expand all
617 // checks. 640 // checks.
618 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 641 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
619 642
620 int index = lookup->GetFieldIndex().field_index(); 643 int index = lookup->GetFieldIndex().field_index();
621 644
622 // Adjust for the number of properties stored in the object. Even in the 645 // Adjust for the number of properties stored in the object. Even in the
623 // face of a transition we can use the old map here because the size of the 646 // face of a transition we can use the old map here because the size of the
624 // object and the number of in-object properties is not going to change. 647 // object and the number of in-object properties is not going to change.
625 index -= object->map()->inobject_properties(); 648 index -= object->map()->inobject_properties();
626 649
650 Representation representation = lookup->representation();
651 ASSERT(!representation.IsNone());
652 if (FLAG_track_fields && representation.IsSmi()) {
653 __ JumpIfNotSmi(value_reg, miss_label);
654 } else if (FLAG_track_double_fields && representation.IsDouble()) {
655 Label do_store;
656 __ JumpIfSmi(value_reg, &do_store);
657 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex,
658 miss_label, DONT_DO_SMI_CHECK);
659 __ bind(&do_store);
660 }
661
627 // TODO(verwaest): Share this code as a code stub. 662 // TODO(verwaest): Share this code as a code stub.
628 if (index < 0) { 663 if (index < 0) {
629 // Set the property straight into the object. 664 // Set the property straight into the object.
630 int offset = object->map()->instance_size() + (index * kPointerSize); 665 int offset = object->map()->instance_size() + (index * kPointerSize);
631 __ str(value_reg, FieldMemOperand(receiver_reg, offset)); 666 __ str(value_reg, FieldMemOperand(receiver_reg, offset));
632 667
633 // Skip updating write barrier if storing a smi. 668 if (!FLAG_track_fields || !representation.IsSmi()) {
634 __ JumpIfSmi(value_reg, &exit); 669 // Skip updating write barrier if storing a smi.
670 __ JumpIfSmi(value_reg, &exit);
635 671
636 // Update the write barrier for the array address. 672 // Update the write barrier for the array address.
637 // Pass the now unused name_reg as a scratch register. 673 // Pass the now unused name_reg as a scratch register.
638 __ mov(name_reg, value_reg); 674 __ mov(name_reg, value_reg);
639 __ RecordWriteField(receiver_reg, 675 __ RecordWriteField(receiver_reg,
640 offset, 676 offset,
641 name_reg, 677 name_reg,
642 scratch1, 678 scratch1,
643 kLRHasNotBeenSaved, 679 kLRHasNotBeenSaved,
644 kDontSaveFPRegs); 680 kDontSaveFPRegs);
681 }
645 } else { 682 } else {
646 // Write to the properties array. 683 // Write to the properties array.
647 int offset = index * kPointerSize + FixedArray::kHeaderSize; 684 int offset = index * kPointerSize + FixedArray::kHeaderSize;
648 // Get the properties array 685 // Get the properties array
649 __ ldr(scratch1, 686 __ ldr(scratch1,
650 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 687 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
651 __ str(value_reg, FieldMemOperand(scratch1, offset)); 688 __ str(value_reg, FieldMemOperand(scratch1, offset));
652 689
653 // Skip updating write barrier if storing a smi. 690 if (!FLAG_track_fields || !representation.IsSmi()) {
654 __ JumpIfSmi(value_reg, &exit); 691 // Skip updating write barrier if storing a smi.
692 __ JumpIfSmi(value_reg, &exit);
655 693
656 // Update the write barrier for the array address. 694 // Update the write barrier for the array address.
657 // Ok to clobber receiver_reg and name_reg, since we return. 695 // Ok to clobber receiver_reg and name_reg, since we return.
658 __ mov(name_reg, value_reg); 696 __ mov(name_reg, value_reg);
659 __ RecordWriteField(scratch1, 697 __ RecordWriteField(scratch1,
660 offset, 698 offset,
661 name_reg, 699 name_reg,
662 receiver_reg, 700 receiver_reg,
663 kLRHasNotBeenSaved, 701 kLRHasNotBeenSaved,
664 kDontSaveFPRegs); 702 kDontSaveFPRegs);
703 }
665 } 704 }
666 705
667 // Return the value (register r0). 706 // Return the value (register r0).
668 ASSERT(value_reg.is(r0)); 707 ASSERT(value_reg.is(r0));
669 __ bind(&exit); 708 __ bind(&exit);
670 __ Ret(); 709 __ Ret();
671 } 710 }
672 711
673 712
674 void BaseStoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, 713 void BaseStoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
(...skipping 2228 matching lines...) Expand 10 before | Expand all | Expand 10 after
2903 Label miss; 2942 Label miss;
2904 2943
2905 if (check == PROPERTY) { 2944 if (check == PROPERTY) {
2906 GenerateNameCheck(name, this->name(), &miss); 2945 GenerateNameCheck(name, this->name(), &miss);
2907 } 2946 }
2908 2947
2909 __ JumpIfSmi(receiver(), &miss); 2948 __ JumpIfSmi(receiver(), &miss);
2910 Register map_reg = scratch1(); 2949 Register map_reg = scratch1();
2911 2950
2912 int receiver_count = receiver_maps->length(); 2951 int receiver_count = receiver_maps->length();
2952 int number_of_handled_maps = 0;
2913 __ ldr(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset)); 2953 __ ldr(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
2914 for (int current = 0; current < receiver_count; ++current) { 2954 for (int current = 0; current < receiver_count; ++current) {
2915 __ mov(ip, Operand(receiver_maps->at(current))); 2955 Handle<Map> map = receiver_maps->at(current);
2916 __ cmp(map_reg, ip); 2956 if (!map->is_deprecated()) {
2917 __ Jump(handlers->at(current), RelocInfo::CODE_TARGET, eq); 2957 number_of_handled_maps++;
2958 __ mov(ip, Operand(receiver_maps->at(current)));
2959 __ cmp(map_reg, ip);
2960 __ Jump(handlers->at(current), RelocInfo::CODE_TARGET, eq);
2961 }
2918 } 2962 }
2963 ASSERT(number_of_handled_maps != 0);
2919 2964
2920 __ bind(&miss); 2965 __ bind(&miss);
2921 TailCallBuiltin(masm(), MissBuiltin(kind())); 2966 TailCallBuiltin(masm(), MissBuiltin(kind()));
2922 2967
2923 // Return the generated code. 2968 // Return the generated code.
2924 InlineCacheState state = 2969 InlineCacheState state =
2925 receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC; 2970 number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC;
2926 return GetICCode(kind(), type, name, state); 2971 return GetICCode(kind(), type, name, state);
2927 } 2972 }
2928 2973
2929 2974
2930 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( 2975 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
2931 MapHandleList* receiver_maps, 2976 MapHandleList* receiver_maps,
2932 CodeHandleList* handler_stubs, 2977 CodeHandleList* handler_stubs,
2933 MapHandleList* transitioned_maps) { 2978 MapHandleList* transitioned_maps) {
2934 Label miss; 2979 Label miss;
2935 __ JumpIfSmi(receiver(), &miss); 2980 __ JumpIfSmi(receiver(), &miss);
(...skipping 748 matching lines...) Expand 10 before | Expand all | Expand 10 after
3684 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); 3729 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3685 } 3730 }
3686 } 3731 }
3687 3732
3688 3733
3689 #undef __ 3734 #undef __
3690 3735
3691 } } // namespace v8::internal 3736 } } // namespace v8::internal
3692 3737
3693 #endif // V8_TARGET_ARCH_ARM 3738 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/macro-assembler-arm.cc ('k') | src/bootstrapper.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698