OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 Loading... |
458 __ test(hash, Immediate(String::kContainsCachedArrayIndexMask)); | 458 __ test(hash, Immediate(String::kContainsCachedArrayIndexMask)); |
459 __ j(zero, index_string); | 459 __ j(zero, index_string); |
460 | 460 |
461 // Is the string a symbol? | 461 // Is the string a symbol? |
462 ASSERT(kSymbolTag != 0); | 462 ASSERT(kSymbolTag != 0); |
463 __ test_b(FieldOperand(map, Map::kInstanceTypeOffset), kIsSymbolMask); | 463 __ test_b(FieldOperand(map, Map::kInstanceTypeOffset), kIsSymbolMask); |
464 __ j(zero, not_symbol); | 464 __ j(zero, not_symbol); |
465 } | 465 } |
466 | 466 |
467 | 467 |
468 static Operand GenerateMappedArgumentsLookup(MacroAssembler* masm, | |
469 Register object, | |
470 Register key, | |
471 Register scratch1, | |
472 Register scratch2, | |
473 Label* unmapped_case, | |
474 Label* slow_case) { | |
475 Heap* heap = masm->isolate()->heap(); | |
476 Factory* factory = masm->isolate()->factory(); | |
477 | |
478 // Check that the receiver isn't a smi. | |
479 __ JumpIfSmi(object, slow_case); | |
480 | |
481 // Check that the key is a positive smi. | |
482 __ test(key, Immediate(0x8000001)); | |
483 __ j(not_zero, slow_case); | |
484 | |
485 // Load the elements into scratch1 and check its map. | |
486 Handle<Map> arguments_map(heap->non_strict_arguments_elements_map()); | |
487 __ mov(scratch1, FieldOperand(object, JSObject::kElementsOffset)); | |
488 __ CheckMap(scratch1, arguments_map, slow_case, DONT_DO_SMI_CHECK); | |
489 | |
490 // Check if element is in the range of mapped arguments. If not, jump | |
491 // to the unmapped lookup with the parameter map in scratch1. | |
492 __ mov(scratch2, FieldOperand(scratch1, FixedArray::kLengthOffset)); | |
493 __ sub(Operand(scratch2), Immediate(Smi::FromInt(2))); | |
494 __ cmp(key, Operand(scratch2)); | |
495 __ j(greater_equal, unmapped_case); | |
496 | |
497 // Load element index and check whether it is the hole. | |
498 const int kHeaderSize = FixedArray::kHeaderSize + 2 * kPointerSize; | |
499 __ mov(scratch2, FieldOperand(scratch1, | |
500 key, | |
501 times_half_pointer_size, | |
502 kHeaderSize)); | |
503 __ cmp(scratch2, factory->the_hole_value()); | |
504 __ j(equal, unmapped_case); | |
505 | |
506 // Load value from context and return it. We can reuse scratch1 because | |
507 // we do not jump to the unmapped lookup (which requires the parameter | |
508 // map in scratch1). | |
509 const int kContextOffset = FixedArray::kHeaderSize; | |
510 __ mov(scratch1, FieldOperand(scratch1, kContextOffset)); | |
511 return FieldOperand(scratch1, | |
512 scratch2, | |
513 times_half_pointer_size, | |
514 Context::kHeaderSize); | |
515 } | |
516 | |
517 | |
518 static Operand GenerateUnmappedArgumentsLookup(MacroAssembler* masm, | |
519 Register key, | |
520 Register parameter_map, | |
521 Register scratch, | |
522 Label* slow_case) { | |
523 // Element is in arguments backing store, which is referenced by the | |
524 // second element of the parameter_map. | |
525 const int kBackingStoreOffset = FixedArray::kHeaderSize + kPointerSize; | |
526 Register backing_store = parameter_map; | |
527 __ mov(backing_store, FieldOperand(parameter_map, kBackingStoreOffset)); | |
528 __ mov(scratch, FieldOperand(backing_store, FixedArray::kLengthOffset)); | |
529 __ cmp(key, Operand(scratch)); | |
530 __ j(greater_equal, slow_case); | |
531 return FieldOperand(backing_store, | |
532 key, | |
533 times_half_pointer_size, | |
534 FixedArray::kHeaderSize); | |
535 } | |
536 | |
537 | |
538 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { | 468 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { |
539 // ----------- S t a t e ------------- | 469 // ----------- S t a t e ------------- |
540 // -- eax : key | 470 // -- eax : key |
541 // -- edx : receiver | 471 // -- edx : receiver |
542 // -- esp[0] : return address | 472 // -- esp[0] : return address |
543 // ----------------------------------- | 473 // ----------------------------------- |
544 Label slow, check_string, index_smi, index_string, property_array_property; | 474 Label slow, check_string, index_smi, index_string, property_array_property; |
545 Label probe_dictionary, check_number_dictionary; | 475 Label probe_dictionary, check_number_dictionary; |
546 | 476 |
547 // Check that the key is a smi. | 477 // Check that the key is a smi. |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
762 ExternalReference ref = | 692 ExternalReference ref = |
763 ExternalReference(IC_Utility(kKeyedLoadPropertyWithInterceptor), | 693 ExternalReference(IC_Utility(kKeyedLoadPropertyWithInterceptor), |
764 masm->isolate()); | 694 masm->isolate()); |
765 __ TailCallExternalReference(ref, 2, 1); | 695 __ TailCallExternalReference(ref, 2, 1); |
766 | 696 |
767 __ bind(&slow); | 697 __ bind(&slow); |
768 GenerateMiss(masm, false); | 698 GenerateMiss(masm, false); |
769 } | 699 } |
770 | 700 |
771 | 701 |
772 void KeyedLoadIC::GenerateNonStrictArguments(MacroAssembler* masm) { | |
773 // ----------- S t a t e ------------- | |
774 // -- eax : key | |
775 // -- edx : receiver | |
776 // -- esp[0] : return address | |
777 // ----------------------------------- | |
778 Label slow, notin; | |
779 Factory* factory = masm->isolate()->factory(); | |
780 Operand mapped_location = | |
781 GenerateMappedArgumentsLookup(masm, edx, eax, ebx, ecx, ¬in, &slow); | |
782 __ mov(eax, mapped_location); | |
783 __ Ret(); | |
784 __ bind(¬in); | |
785 // The unmapped lookup expects that the parameter map is in ebx. | |
786 Operand unmapped_location = | |
787 GenerateUnmappedArgumentsLookup(masm, eax, ebx, ecx, &slow); | |
788 __ cmp(unmapped_location, factory->the_hole_value()); | |
789 __ j(equal, &slow); | |
790 __ mov(eax, unmapped_location); | |
791 __ Ret(); | |
792 __ bind(&slow); | |
793 GenerateMiss(masm, false); | |
794 } | |
795 | |
796 | |
797 void KeyedStoreIC::GenerateNonStrictArguments(MacroAssembler* masm) { | |
798 // ----------- S t a t e ------------- | |
799 // -- eax : value | |
800 // -- ecx : key | |
801 // -- edx : receiver | |
802 // -- esp[0] : return address | |
803 // ----------------------------------- | |
804 Label slow, notin; | |
805 Operand mapped_location = | |
806 GenerateMappedArgumentsLookup(masm, edx, ecx, ebx, edi, ¬in, &slow); | |
807 __ mov(mapped_location, eax); | |
808 __ Ret(); | |
809 __ bind(¬in); | |
810 // The unmapped lookup expects that the parameter map is in ebx. | |
811 Operand unmapped_location = | |
812 GenerateUnmappedArgumentsLookup(masm, ecx, ebx, edi, &slow); | |
813 __ mov(unmapped_location, eax); | |
814 __ Ret(); | |
815 __ bind(&slow); | |
816 GenerateMiss(masm, false); | |
817 } | |
818 | |
819 | |
820 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, | 702 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, |
821 StrictModeFlag strict_mode) { | 703 StrictModeFlag strict_mode) { |
822 // ----------- S t a t e ------------- | 704 // ----------- S t a t e ------------- |
823 // -- eax : value | 705 // -- eax : value |
824 // -- ecx : key | 706 // -- ecx : key |
825 // -- edx : receiver | 707 // -- edx : receiver |
826 // -- esp[0] : return address | 708 // -- esp[0] : return address |
827 // ----------------------------------- | 709 // ----------------------------------- |
828 Label slow, fast, array, extra; | 710 Label slow, fast, array, extra; |
829 | 711 |
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1257 __ IncrementCounter(counters->keyed_call_generic_slow(), 1); | 1139 __ IncrementCounter(counters->keyed_call_generic_slow(), 1); |
1258 GenerateMiss(masm, argc); | 1140 GenerateMiss(masm, argc); |
1259 | 1141 |
1260 __ bind(&index_string); | 1142 __ bind(&index_string); |
1261 __ IndexFromHash(ebx, ecx); | 1143 __ IndexFromHash(ebx, ecx); |
1262 // Now jump to the place where smi keys are handled. | 1144 // Now jump to the place where smi keys are handled. |
1263 __ jmp(&index_smi); | 1145 __ jmp(&index_smi); |
1264 } | 1146 } |
1265 | 1147 |
1266 | 1148 |
1267 void KeyedCallIC::GenerateNonStrictArguments(MacroAssembler* masm, | |
1268 int argc) { | |
1269 // ----------- S t a t e ------------- | |
1270 // -- ecx : name | |
1271 // -- esp[0] : return address | |
1272 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | |
1273 // -- ... | |
1274 // -- esp[(argc + 1) * 4] : receiver | |
1275 // ----------------------------------- | |
1276 Label slow, notin; | |
1277 Factory* factory = masm->isolate()->factory(); | |
1278 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | |
1279 Operand mapped_location = | |
1280 GenerateMappedArgumentsLookup(masm, edx, ecx, ebx, eax, ¬in, &slow); | |
1281 __ mov(edi, mapped_location); | |
1282 GenerateFunctionTailCall(masm, argc, &slow); | |
1283 __ bind(¬in); | |
1284 // The unmapped lookup expects that the parameter map is in ebx. | |
1285 Operand unmapped_location = | |
1286 GenerateUnmappedArgumentsLookup(masm, ecx, ebx, eax, &slow); | |
1287 __ cmp(unmapped_location, factory->the_hole_value()); | |
1288 __ j(equal, &slow); | |
1289 __ mov(edi, unmapped_location); | |
1290 GenerateFunctionTailCall(masm, argc, &slow); | |
1291 __ bind(&slow); | |
1292 GenerateMiss(masm, argc); | |
1293 } | |
1294 | |
1295 | |
1296 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) { | 1149 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) { |
1297 // ----------- S t a t e ------------- | 1150 // ----------- S t a t e ------------- |
1298 // -- ecx : name | 1151 // -- ecx : name |
1299 // -- esp[0] : return address | 1152 // -- esp[0] : return address |
1300 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1153 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1301 // -- ... | 1154 // -- ... |
1302 // -- esp[(argc + 1) * 4] : receiver | 1155 // -- esp[(argc + 1) * 4] : receiver |
1303 // ----------------------------------- | 1156 // ----------------------------------- |
1304 | 1157 |
1305 // Check if the name is a string. | 1158 // Check if the name is a string. |
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1737 Condition cc = *jmp_address == Assembler::kJncShortOpcode | 1590 Condition cc = *jmp_address == Assembler::kJncShortOpcode |
1738 ? not_zero | 1591 ? not_zero |
1739 : zero; | 1592 : zero; |
1740 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1593 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
1741 } | 1594 } |
1742 | 1595 |
1743 | 1596 |
1744 } } // namespace v8::internal | 1597 } } // namespace v8::internal |
1745 | 1598 |
1746 #endif // V8_TARGET_ARCH_IA32 | 1599 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |