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 |
468 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { | 538 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { |
469 // ----------- S t a t e ------------- | 539 // ----------- S t a t e ------------- |
470 // -- eax : key | 540 // -- eax : key |
471 // -- edx : receiver | 541 // -- edx : receiver |
472 // -- esp[0] : return address | 542 // -- esp[0] : return address |
473 // ----------------------------------- | 543 // ----------------------------------- |
474 Label slow, check_string, index_smi, index_string, property_array_property; | 544 Label slow, check_string, index_smi, index_string, property_array_property; |
475 Label probe_dictionary, check_number_dictionary; | 545 Label probe_dictionary, check_number_dictionary; |
476 | 546 |
477 // Check that the key is a smi. | 547 // Check that the key is a smi. |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
692 ExternalReference ref = | 762 ExternalReference ref = |
693 ExternalReference(IC_Utility(kKeyedLoadPropertyWithInterceptor), | 763 ExternalReference(IC_Utility(kKeyedLoadPropertyWithInterceptor), |
694 masm->isolate()); | 764 masm->isolate()); |
695 __ TailCallExternalReference(ref, 2, 1); | 765 __ TailCallExternalReference(ref, 2, 1); |
696 | 766 |
697 __ bind(&slow); | 767 __ bind(&slow); |
698 GenerateMiss(masm, false); | 768 GenerateMiss(masm, false); |
699 } | 769 } |
700 | 770 |
701 | 771 |
| 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 |
702 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, | 820 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, |
703 StrictModeFlag strict_mode) { | 821 StrictModeFlag strict_mode) { |
704 // ----------- S t a t e ------------- | 822 // ----------- S t a t e ------------- |
705 // -- eax : value | 823 // -- eax : value |
706 // -- ecx : key | 824 // -- ecx : key |
707 // -- edx : receiver | 825 // -- edx : receiver |
708 // -- esp[0] : return address | 826 // -- esp[0] : return address |
709 // ----------------------------------- | 827 // ----------------------------------- |
710 Label slow, fast, array, extra; | 828 Label slow, fast, array, extra; |
711 | 829 |
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1139 __ IncrementCounter(counters->keyed_call_generic_slow(), 1); | 1257 __ IncrementCounter(counters->keyed_call_generic_slow(), 1); |
1140 GenerateMiss(masm, argc); | 1258 GenerateMiss(masm, argc); |
1141 | 1259 |
1142 __ bind(&index_string); | 1260 __ bind(&index_string); |
1143 __ IndexFromHash(ebx, ecx); | 1261 __ IndexFromHash(ebx, ecx); |
1144 // Now jump to the place where smi keys are handled. | 1262 // Now jump to the place where smi keys are handled. |
1145 __ jmp(&index_smi); | 1263 __ jmp(&index_smi); |
1146 } | 1264 } |
1147 | 1265 |
1148 | 1266 |
| 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 |
1149 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) { | 1296 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) { |
1150 // ----------- S t a t e ------------- | 1297 // ----------- S t a t e ------------- |
1151 // -- ecx : name | 1298 // -- ecx : name |
1152 // -- esp[0] : return address | 1299 // -- esp[0] : return address |
1153 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1300 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1154 // -- ... | 1301 // -- ... |
1155 // -- esp[(argc + 1) * 4] : receiver | 1302 // -- esp[(argc + 1) * 4] : receiver |
1156 // ----------------------------------- | 1303 // ----------------------------------- |
1157 | 1304 |
1158 // Check if the name is a string. | 1305 // Check if the name is a string. |
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1590 Condition cc = *jmp_address == Assembler::kJncShortOpcode | 1737 Condition cc = *jmp_address == Assembler::kJncShortOpcode |
1591 ? not_zero | 1738 ? not_zero |
1592 : zero; | 1739 : zero; |
1593 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1740 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
1594 } | 1741 } |
1595 | 1742 |
1596 | 1743 |
1597 } } // namespace v8::internal | 1744 } } // namespace v8::internal |
1598 | 1745 |
1599 #endif // V8_TARGET_ARCH_IA32 | 1746 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |