| OLD | NEW | 
|---|
| 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 438 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 449 | 449 | 
| 450   // Check that the map of the object hasn't changed. | 450   // Check that the map of the object hasn't changed. | 
| 451   __ CheckMap(receiver_reg, scratch1, Handle<Map>(object->map()), miss_label, | 451   __ CheckMap(receiver_reg, scratch1, Handle<Map>(object->map()), miss_label, | 
| 452               DO_SMI_CHECK, REQUIRE_EXACT_MAP); | 452               DO_SMI_CHECK, REQUIRE_EXACT_MAP); | 
| 453 | 453 | 
| 454   // Perform global security token check if needed. | 454   // Perform global security token check if needed. | 
| 455   if (object->IsJSGlobalProxy()) { | 455   if (object->IsJSGlobalProxy()) { | 
| 456     __ CheckAccessGlobalProxy(receiver_reg, scratch1, miss_label); | 456     __ CheckAccessGlobalProxy(receiver_reg, scratch1, miss_label); | 
| 457   } | 457   } | 
| 458 | 458 | 
|  | 459   int descriptor = transition->LastAdded(); | 
|  | 460   DescriptorArray* descriptors = transition->instance_descriptors(); | 
|  | 461   PropertyDetails details = descriptors->GetDetails(descriptor); | 
|  | 462   Representation representation = details.representation(); | 
|  | 463   ASSERT(!representation.IsNone()); | 
|  | 464 | 
|  | 465   // Ensure no transitions to deprecated maps are followed. | 
|  | 466   __ CheckMapDeprecated(transition, scratch1, miss_label); | 
|  | 467 | 
|  | 468   if (FLAG_track_fields && representation.IsSmi()) { | 
|  | 469     __ JumpIfNotSmi(value_reg, miss_label); | 
|  | 470   } else if (FLAG_track_double_fields && representation.IsDouble()) { | 
|  | 471     Label do_store; | 
|  | 472     __ JumpIfSmi(value_reg, &do_store); | 
|  | 473     __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, | 
|  | 474                 miss_label, DONT_DO_SMI_CHECK); | 
|  | 475     __ bind(&do_store); | 
|  | 476   } | 
|  | 477 | 
| 459   // Check that we are allowed to write this. | 478   // Check that we are allowed to write this. | 
| 460   if (object->GetPrototype()->IsJSObject()) { | 479   if (object->GetPrototype()->IsJSObject()) { | 
| 461     JSObject* holder; | 480     JSObject* holder; | 
| 462     // holder == object indicates that no property was found. | 481     // holder == object indicates that no property was found. | 
| 463     if (lookup->holder() != *object) { | 482     if (lookup->holder() != *object) { | 
| 464       holder = lookup->holder(); | 483       holder = lookup->holder(); | 
| 465     } else { | 484     } else { | 
| 466       // Find the top object. | 485       // Find the top object. | 
| 467       holder = *object; | 486       holder = *object; | 
| 468       do { | 487       do { | 
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 530   // face of a transition we can use the old map here because the size of the | 549   // face of a transition we can use the old map here because the size of the | 
| 531   // object and the number of in-object properties is not going to change. | 550   // object and the number of in-object properties is not going to change. | 
| 532   index -= object->map()->inobject_properties(); | 551   index -= object->map()->inobject_properties(); | 
| 533 | 552 | 
| 534   // TODO(verwaest): Share this code as a code stub. | 553   // TODO(verwaest): Share this code as a code stub. | 
| 535   if (index < 0) { | 554   if (index < 0) { | 
| 536     // Set the property straight into the object. | 555     // Set the property straight into the object. | 
| 537     int offset = object->map()->instance_size() + (index * kPointerSize); | 556     int offset = object->map()->instance_size() + (index * kPointerSize); | 
| 538     __ sw(value_reg, FieldMemOperand(receiver_reg, offset)); | 557     __ sw(value_reg, FieldMemOperand(receiver_reg, offset)); | 
| 539 | 558 | 
| 540     // Skip updating write barrier if storing a smi. | 559     if (!FLAG_track_fields || !representation.IsSmi()) { | 
| 541     __ JumpIfSmi(value_reg, &exit); | 560       // Skip updating write barrier if storing a smi. | 
|  | 561       __ JumpIfSmi(value_reg, &exit); | 
| 542 | 562 | 
| 543     // Update the write barrier for the array address. | 563       // Update the write barrier for the array address. | 
| 544     // Pass the now unused name_reg as a scratch register. | 564       // Pass the now unused name_reg as a scratch register. | 
| 545     __ mov(name_reg, value_reg); | 565       __ mov(name_reg, value_reg); | 
| 546     __ RecordWriteField(receiver_reg, | 566       __ RecordWriteField(receiver_reg, | 
| 547                         offset, | 567                           offset, | 
| 548                         name_reg, | 568                           name_reg, | 
| 549                         scratch1, | 569                           scratch1, | 
| 550                         kRAHasNotBeenSaved, | 570                           kRAHasNotBeenSaved, | 
| 551                         kDontSaveFPRegs); | 571                           kDontSaveFPRegs); | 
|  | 572     } | 
| 552   } else { | 573   } else { | 
| 553     // Write to the properties array. | 574     // Write to the properties array. | 
| 554     int offset = index * kPointerSize + FixedArray::kHeaderSize; | 575     int offset = index * kPointerSize + FixedArray::kHeaderSize; | 
| 555     // Get the properties array | 576     // Get the properties array | 
| 556     __ lw(scratch1, | 577     __ lw(scratch1, | 
| 557           FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); | 578           FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); | 
| 558     __ sw(value_reg, FieldMemOperand(scratch1, offset)); | 579     __ sw(value_reg, FieldMemOperand(scratch1, offset)); | 
| 559 | 580 | 
| 560     // Skip updating write barrier if storing a smi. | 581     if (!FLAG_track_fields || !representation.IsSmi()) { | 
| 561     __ JumpIfSmi(value_reg, &exit); | 582       // Skip updating write barrier if storing a smi. | 
|  | 583       __ JumpIfSmi(value_reg, &exit); | 
| 562 | 584 | 
| 563     // Update the write barrier for the array address. | 585       // Update the write barrier for the array address. | 
| 564     // Ok to clobber receiver_reg and name_reg, since we return. | 586       // Ok to clobber receiver_reg and name_reg, since we return. | 
| 565     __ mov(name_reg, value_reg); | 587       __ mov(name_reg, value_reg); | 
| 566     __ RecordWriteField(scratch1, | 588       __ RecordWriteField(scratch1, | 
| 567                         offset, | 589                           offset, | 
| 568                         name_reg, | 590                           name_reg, | 
| 569                         receiver_reg, | 591                           receiver_reg, | 
| 570                         kRAHasNotBeenSaved, | 592                           kRAHasNotBeenSaved, | 
| 571                         kDontSaveFPRegs); | 593                           kDontSaveFPRegs); | 
|  | 594     } | 
| 572   } | 595   } | 
| 573 | 596 | 
| 574   // Return the value (register v0). | 597   // Return the value (register v0). | 
| 575   ASSERT(value_reg.is(a0)); | 598   ASSERT(value_reg.is(a0)); | 
| 576   __ bind(&exit); | 599   __ bind(&exit); | 
| 577   __ mov(v0, a0); | 600   __ mov(v0, a0); | 
| 578   __ Ret(); | 601   __ Ret(); | 
| 579 } | 602 } | 
| 580 | 603 | 
| 581 | 604 | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
| 608   // checks. | 631   // checks. | 
| 609   ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 632   ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 
| 610 | 633 | 
| 611   int index = lookup->GetFieldIndex().field_index(); | 634   int index = lookup->GetFieldIndex().field_index(); | 
| 612 | 635 | 
| 613   // Adjust for the number of properties stored in the object. Even in the | 636   // Adjust for the number of properties stored in the object. Even in the | 
| 614   // face of a transition we can use the old map here because the size of the | 637   // face of a transition we can use the old map here because the size of the | 
| 615   // object and the number of in-object properties is not going to change. | 638   // object and the number of in-object properties is not going to change. | 
| 616   index -= object->map()->inobject_properties(); | 639   index -= object->map()->inobject_properties(); | 
| 617 | 640 | 
|  | 641   Representation representation = lookup->representation(); | 
|  | 642   ASSERT(!representation.IsNone()); | 
|  | 643   if (FLAG_track_fields && representation.IsSmi()) { | 
|  | 644     __ JumpIfNotSmi(value_reg, miss_label); | 
|  | 645   } else if (FLAG_track_double_fields && representation.IsDouble()) { | 
|  | 646     Label do_store; | 
|  | 647     __ JumpIfSmi(value_reg, &do_store); | 
|  | 648     __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, | 
|  | 649                 miss_label, DONT_DO_SMI_CHECK); | 
|  | 650     __ bind(&do_store); | 
|  | 651   } | 
|  | 652 | 
| 618   // TODO(verwaest): Share this code as a code stub. | 653   // TODO(verwaest): Share this code as a code stub. | 
| 619   if (index < 0) { | 654   if (index < 0) { | 
| 620     // Set the property straight into the object. | 655     // Set the property straight into the object. | 
| 621     int offset = object->map()->instance_size() + (index * kPointerSize); | 656     int offset = object->map()->instance_size() + (index * kPointerSize); | 
| 622     __ sw(value_reg, FieldMemOperand(receiver_reg, offset)); | 657     __ sw(value_reg, FieldMemOperand(receiver_reg, offset)); | 
| 623 | 658 | 
| 624     // Skip updating write barrier if storing a smi. | 659     if (!FLAG_track_fields || !representation.IsSmi()) { | 
| 625     __ JumpIfSmi(value_reg, &exit); | 660       // Skip updating write barrier if storing a smi. | 
|  | 661       __ JumpIfSmi(value_reg, &exit); | 
| 626 | 662 | 
| 627     // Update the write barrier for the array address. | 663       // Update the write barrier for the array address. | 
| 628     // Pass the now unused name_reg as a scratch register. | 664       // Pass the now unused name_reg as a scratch register. | 
| 629     __ mov(name_reg, value_reg); | 665       __ mov(name_reg, value_reg); | 
| 630     __ RecordWriteField(receiver_reg, | 666       __ RecordWriteField(receiver_reg, | 
| 631                         offset, | 667                           offset, | 
| 632                         name_reg, | 668                           name_reg, | 
| 633                         scratch1, | 669                           scratch1, | 
| 634                         kRAHasNotBeenSaved, | 670                           kRAHasNotBeenSaved, | 
| 635                         kDontSaveFPRegs); | 671                           kDontSaveFPRegs); | 
|  | 672     } | 
| 636   } else { | 673   } else { | 
| 637     // Write to the properties array. | 674     // Write to the properties array. | 
| 638     int offset = index * kPointerSize + FixedArray::kHeaderSize; | 675     int offset = index * kPointerSize + FixedArray::kHeaderSize; | 
| 639     // Get the properties array. | 676     // Get the properties array. | 
| 640     __ lw(scratch1, | 677     __ lw(scratch1, | 
| 641           FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); | 678           FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); | 
| 642     __ sw(value_reg, FieldMemOperand(scratch1, offset)); | 679     __ sw(value_reg, FieldMemOperand(scratch1, offset)); | 
| 643 | 680 | 
| 644     // Skip updating write barrier if storing a smi. | 681     if (!FLAG_track_fields || !representation.IsSmi()) { | 
| 645     __ JumpIfSmi(value_reg, &exit); | 682       // Skip updating write barrier if storing a smi. | 
|  | 683       __ JumpIfSmi(value_reg, &exit); | 
| 646 | 684 | 
| 647     // Update the write barrier for the array address. | 685       // Update the write barrier for the array address. | 
| 648     // Ok to clobber receiver_reg and name_reg, since we return. | 686       // Ok to clobber receiver_reg and name_reg, since we return. | 
| 649     __ mov(name_reg, value_reg); | 687       __ mov(name_reg, value_reg); | 
| 650     __ RecordWriteField(scratch1, | 688       __ RecordWriteField(scratch1, | 
| 651                         offset, | 689                           offset, | 
| 652                         name_reg, | 690                           name_reg, | 
| 653                         receiver_reg, | 691                           receiver_reg, | 
| 654                         kRAHasNotBeenSaved, | 692                           kRAHasNotBeenSaved, | 
| 655                         kDontSaveFPRegs); | 693                           kDontSaveFPRegs); | 
|  | 694     } | 
| 656   } | 695   } | 
| 657 | 696 | 
| 658   // Return the value (register v0). | 697   // Return the value (register v0). | 
| 659   ASSERT(value_reg.is(a0)); | 698   ASSERT(value_reg.is(a0)); | 
| 660   __ bind(&exit); | 699   __ bind(&exit); | 
| 661   __ mov(v0, a0); | 700   __ mov(v0, a0); | 
| 662   __ Ret(); | 701   __ Ret(); | 
| 663 } | 702 } | 
| 664 | 703 | 
| 665 | 704 | 
| (...skipping 2262 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2928   Label miss; | 2967   Label miss; | 
| 2929 | 2968 | 
| 2930   if (check == PROPERTY) { | 2969   if (check == PROPERTY) { | 
| 2931     GenerateNameCheck(name, this->name(), &miss); | 2970     GenerateNameCheck(name, this->name(), &miss); | 
| 2932   } | 2971   } | 
| 2933 | 2972 | 
| 2934   __ JumpIfSmi(receiver(), &miss); | 2973   __ JumpIfSmi(receiver(), &miss); | 
| 2935   Register map_reg = scratch1(); | 2974   Register map_reg = scratch1(); | 
| 2936 | 2975 | 
| 2937   int receiver_count = receiver_maps->length(); | 2976   int receiver_count = receiver_maps->length(); | 
|  | 2977   int number_of_handled_maps = 0; | 
| 2938   __ lw(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset)); | 2978   __ lw(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset)); | 
| 2939   for (int current = 0; current < receiver_count; ++current) { | 2979   for (int current = 0; current < receiver_count; ++current) { | 
| 2940     __ Jump(handlers->at(current), RelocInfo::CODE_TARGET, | 2980     Handle<Map> map = receiver_maps->at(current); | 
| 2941         eq, map_reg, Operand(receiver_maps->at(current))); | 2981     if (!map->is_deprecated()) { | 
|  | 2982       number_of_handled_maps++; | 
|  | 2983       __ Jump(handlers->at(current), RelocInfo::CODE_TARGET, | 
|  | 2984           eq, map_reg, Operand(receiver_maps->at(current))); | 
|  | 2985     } | 
| 2942   } | 2986   } | 
|  | 2987   ASSERT(number_of_handled_maps != 0); | 
| 2943 | 2988 | 
| 2944   __ bind(&miss); | 2989   __ bind(&miss); | 
| 2945   TailCallBuiltin(masm(), MissBuiltin(kind())); | 2990   TailCallBuiltin(masm(), MissBuiltin(kind())); | 
| 2946 | 2991 | 
| 2947   // Return the generated code. | 2992   // Return the generated code. | 
| 2948   InlineCacheState state = | 2993   InlineCacheState state = | 
| 2949       receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC; | 2994       number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC; | 
| 2950   return GetICCode(kind(), type, name, state); | 2995   return GetICCode(kind(), type, name, state); | 
| 2951 } | 2996 } | 
| 2952 | 2997 | 
| 2953 | 2998 | 
| 2954 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( | 2999 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( | 
| 2955     MapHandleList* receiver_maps, | 3000     MapHandleList* receiver_maps, | 
| 2956     CodeHandleList* handler_stubs, | 3001     CodeHandleList* handler_stubs, | 
| 2957     MapHandleList* transitioned_maps) { | 3002     MapHandleList* transitioned_maps) { | 
| 2958   Label miss; | 3003   Label miss; | 
| 2959   __ JumpIfSmi(receiver(), &miss); | 3004   __ JumpIfSmi(receiver(), &miss); | 
| (...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3742     TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); | 3787     TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); | 
| 3743   } | 3788   } | 
| 3744 } | 3789 } | 
| 3745 | 3790 | 
| 3746 | 3791 | 
| 3747 #undef __ | 3792 #undef __ | 
| 3748 | 3793 | 
| 3749 } }  // namespace v8::internal | 3794 } }  // namespace v8::internal | 
| 3750 | 3795 | 
| 3751 #endif  // V8_TARGET_ARCH_MIPS | 3796 #endif  // V8_TARGET_ARCH_MIPS | 
| OLD | NEW | 
|---|