| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 851 GlobalObject* global, | 851 GlobalObject* global, |
| 852 String* name, | 852 String* name, |
| 853 Register scratch, | 853 Register scratch, |
| 854 Label* miss) { | 854 Label* miss) { |
| 855 Object* probe; | 855 Object* probe; |
| 856 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); | 856 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); |
| 857 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 857 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
| 858 } | 858 } |
| 859 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); | 859 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); |
| 860 ASSERT(cell->value()->IsTheHole()); | 860 ASSERT(cell->value()->IsTheHole()); |
| 861 __ mov(scratch, Immediate(Handle<Object>(cell))); | 861 if (Serializer::enabled()) { |
| 862 __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), | 862 __ mov(scratch, Immediate(Handle<Object>(cell))); |
| 863 Immediate(FACTORY->the_hole_value())); | 863 __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), |
| 864 Immediate(FACTORY->the_hole_value())); |
| 865 } else { |
| 866 __ cmp(Operand::Cell(Handle<JSGlobalPropertyCell>(cell)), |
| 867 Immediate(FACTORY->the_hole_value())); |
| 868 } |
| 864 __ j(not_equal, miss, not_taken); | 869 __ j(not_equal, miss, not_taken); |
| 865 return cell; | 870 return cell; |
| 866 } | 871 } |
| 867 | 872 |
| 868 | 873 |
| 869 // Calls GenerateCheckPropertyCell for each global object in the prototype chain | 874 // Calls GenerateCheckPropertyCell for each global object in the prototype chain |
| 870 // from object to (but not including) holder. | 875 // from object to (but not including) holder. |
| 871 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCells( | 876 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCells( |
| 872 MacroAssembler* masm, | 877 MacroAssembler* masm, |
| 873 JSObject* object, | 878 JSObject* object, |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1322 | 1327 |
| 1323 // Check that the maps haven't changed. | 1328 // Check that the maps haven't changed. |
| 1324 CheckPrototypes(object, edx, holder, ebx, eax, edi, name, miss); | 1329 CheckPrototypes(object, edx, holder, ebx, eax, edi, name, miss); |
| 1325 } | 1330 } |
| 1326 | 1331 |
| 1327 | 1332 |
| 1328 void CallStubCompiler::GenerateLoadFunctionFromCell(JSGlobalPropertyCell* cell, | 1333 void CallStubCompiler::GenerateLoadFunctionFromCell(JSGlobalPropertyCell* cell, |
| 1329 JSFunction* function, | 1334 JSFunction* function, |
| 1330 Label* miss) { | 1335 Label* miss) { |
| 1331 // Get the value from the cell. | 1336 // Get the value from the cell. |
| 1332 __ mov(edi, Immediate(Handle<JSGlobalPropertyCell>(cell))); | 1337 if (Serializer::enabled()) { |
| 1333 __ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset)); | 1338 __ mov(edi, Immediate(Handle<JSGlobalPropertyCell>(cell))); |
| 1339 __ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset)); |
| 1340 } else { |
| 1341 __ mov(edi, Operand::Cell(Handle<JSGlobalPropertyCell>(cell))); |
| 1342 } |
| 1334 | 1343 |
| 1335 // Check that the cell contains the same function. | 1344 // Check that the cell contains the same function. |
| 1336 if (HEAP->InNewSpace(function)) { | 1345 if (HEAP->InNewSpace(function)) { |
| 1337 // We can't embed a pointer to a function in new space so we have | 1346 // We can't embed a pointer to a function in new space so we have |
| 1338 // to verify that the shared function info is unchanged. This has | 1347 // to verify that the shared function info is unchanged. This has |
| 1339 // the nice side effect that multiple closures based on the same | 1348 // the nice side effect that multiple closures based on the same |
| 1340 // function can all use this call IC. Before we load through the | 1349 // function can all use this call IC. Before we load through the |
| 1341 // function, we have to verify that it still is a function. | 1350 // function, we have to verify that it still is a function. |
| 1342 __ test(edi, Immediate(kSmiTagMask)); | 1351 __ test(edi, Immediate(kSmiTagMask)); |
| 1343 __ j(zero, miss, not_taken); | 1352 __ j(zero, miss, not_taken); |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1706 index, | 1715 index, |
| 1707 scratch, | 1716 scratch, |
| 1708 result, | 1717 result, |
| 1709 &miss, // When not a string. | 1718 &miss, // When not a string. |
| 1710 &miss, // When not a number. | 1719 &miss, // When not a number. |
| 1711 &index_out_of_range, | 1720 &index_out_of_range, |
| 1712 STRING_INDEX_IS_NUMBER); | 1721 STRING_INDEX_IS_NUMBER); |
| 1713 char_code_at_generator.GenerateFast(masm()); | 1722 char_code_at_generator.GenerateFast(masm()); |
| 1714 __ ret((argc + 1) * kPointerSize); | 1723 __ ret((argc + 1) * kPointerSize); |
| 1715 | 1724 |
| 1716 ICRuntimeCallHelper call_helper; | 1725 StubRuntimeCallHelper call_helper; |
| 1717 char_code_at_generator.GenerateSlow(masm(), call_helper); | 1726 char_code_at_generator.GenerateSlow(masm(), call_helper); |
| 1718 | 1727 |
| 1719 __ bind(&index_out_of_range); | 1728 __ bind(&index_out_of_range); |
| 1720 __ Set(eax, Immediate(FACTORY->nan_value())); | 1729 __ Set(eax, Immediate(FACTORY->nan_value())); |
| 1721 __ ret((argc + 1) * kPointerSize); | 1730 __ ret((argc + 1) * kPointerSize); |
| 1722 | 1731 |
| 1723 __ bind(&miss); | 1732 __ bind(&miss); |
| 1724 Object* obj; | 1733 Object* obj; |
| 1725 { MaybeObject* maybe_obj = GenerateMissBranch(); | 1734 { MaybeObject* maybe_obj = GenerateMissBranch(); |
| 1726 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1735 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1781 scratch1, | 1790 scratch1, |
| 1782 scratch2, | 1791 scratch2, |
| 1783 result, | 1792 result, |
| 1784 &miss, // When not a string. | 1793 &miss, // When not a string. |
| 1785 &miss, // When not a number. | 1794 &miss, // When not a number. |
| 1786 &index_out_of_range, | 1795 &index_out_of_range, |
| 1787 STRING_INDEX_IS_NUMBER); | 1796 STRING_INDEX_IS_NUMBER); |
| 1788 char_at_generator.GenerateFast(masm()); | 1797 char_at_generator.GenerateFast(masm()); |
| 1789 __ ret((argc + 1) * kPointerSize); | 1798 __ ret((argc + 1) * kPointerSize); |
| 1790 | 1799 |
| 1791 ICRuntimeCallHelper call_helper; | 1800 StubRuntimeCallHelper call_helper; |
| 1792 char_at_generator.GenerateSlow(masm(), call_helper); | 1801 char_at_generator.GenerateSlow(masm(), call_helper); |
| 1793 | 1802 |
| 1794 __ bind(&index_out_of_range); | 1803 __ bind(&index_out_of_range); |
| 1795 __ Set(eax, Immediate(FACTORY->empty_string())); | 1804 __ Set(eax, Immediate(FACTORY->empty_string())); |
| 1796 __ ret((argc + 1) * kPointerSize); | 1805 __ ret((argc + 1) * kPointerSize); |
| 1797 | 1806 |
| 1798 __ bind(&miss); | 1807 __ bind(&miss); |
| 1799 Object* obj; | 1808 Object* obj; |
| 1800 { MaybeObject* maybe_obj = GenerateMissBranch(); | 1809 { MaybeObject* maybe_obj = GenerateMissBranch(); |
| 1801 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1810 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1854 __ test(code, Immediate(kSmiTagMask)); | 1863 __ test(code, Immediate(kSmiTagMask)); |
| 1855 __ j(not_zero, &slow); | 1864 __ j(not_zero, &slow); |
| 1856 | 1865 |
| 1857 // Convert the smi code to uint16. | 1866 // Convert the smi code to uint16. |
| 1858 __ and_(code, Immediate(Smi::FromInt(0xffff))); | 1867 __ and_(code, Immediate(Smi::FromInt(0xffff))); |
| 1859 | 1868 |
| 1860 StringCharFromCodeGenerator char_from_code_generator(code, eax); | 1869 StringCharFromCodeGenerator char_from_code_generator(code, eax); |
| 1861 char_from_code_generator.GenerateFast(masm()); | 1870 char_from_code_generator.GenerateFast(masm()); |
| 1862 __ ret(2 * kPointerSize); | 1871 __ ret(2 * kPointerSize); |
| 1863 | 1872 |
| 1864 ICRuntimeCallHelper call_helper; | 1873 StubRuntimeCallHelper call_helper; |
| 1865 char_from_code_generator.GenerateSlow(masm(), call_helper); | 1874 char_from_code_generator.GenerateSlow(masm(), call_helper); |
| 1866 | 1875 |
| 1867 // Tail call the full function. We do not have to patch the receiver | 1876 // Tail call the full function. We do not have to patch the receiver |
| 1868 // because the function makes no use of it. | 1877 // because the function makes no use of it. |
| 1869 __ bind(&slow); | 1878 __ bind(&slow); |
| 1870 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); | 1879 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); |
| 1871 | 1880 |
| 1872 __ bind(&miss); | 1881 __ bind(&miss); |
| 1873 // ecx: function name. | 1882 // ecx: function name. |
| 1874 Object* obj; | 1883 Object* obj; |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2396 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 2405 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
| 2397 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 2406 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
| 2398 } | 2407 } |
| 2399 | 2408 |
| 2400 // Setup the context (function already in edi). | 2409 // Setup the context (function already in edi). |
| 2401 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 2410 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
| 2402 | 2411 |
| 2403 // Jump to the cached code (tail call). | 2412 // Jump to the cached code (tail call). |
| 2404 __ IncrementCounter(COUNTERS->call_global_inline(), 1); | 2413 __ IncrementCounter(COUNTERS->call_global_inline(), 1); |
| 2405 ASSERT(function->is_compiled()); | 2414 ASSERT(function->is_compiled()); |
| 2406 Handle<Code> code(function->code()); | |
| 2407 ParameterCount expected(function->shared()->formal_parameter_count()); | 2415 ParameterCount expected(function->shared()->formal_parameter_count()); |
| 2408 __ InvokeCode(code, expected, arguments(), | 2416 if (V8::UseCrankshaft()) { |
| 2409 RelocInfo::CODE_TARGET, JUMP_FUNCTION); | 2417 // TODO(kasperl): For now, we always call indirectly through the |
| 2418 // code field in the function to allow recompilation to take effect |
| 2419 // without changing any of the call sites. |
| 2420 __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), |
| 2421 expected, arguments(), JUMP_FUNCTION); |
| 2422 } else { |
| 2423 Handle<Code> code(function->code()); |
| 2424 __ InvokeCode(code, expected, arguments(), |
| 2425 RelocInfo::CODE_TARGET, JUMP_FUNCTION); |
| 2426 } |
| 2410 | 2427 |
| 2411 // Handle call cache miss. | 2428 // Handle call cache miss. |
| 2412 __ bind(&miss); | 2429 __ bind(&miss); |
| 2413 __ IncrementCounter(COUNTERS->call_global_inline_miss(), 1); | 2430 __ IncrementCounter(COUNTERS->call_global_inline_miss(), 1); |
| 2414 Object* obj; | 2431 Object* obj; |
| 2415 { MaybeObject* maybe_obj = GenerateMissBranch(); | 2432 { MaybeObject* maybe_obj = GenerateMissBranch(); |
| 2416 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2433 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2417 } | 2434 } |
| 2418 | 2435 |
| 2419 // Return the generated code. | 2436 // Return the generated code. |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2565 // -- esp[0] : return address | 2582 // -- esp[0] : return address |
| 2566 // ----------------------------------- | 2583 // ----------------------------------- |
| 2567 Label miss; | 2584 Label miss; |
| 2568 | 2585 |
| 2569 // Check that the map of the global has not changed. | 2586 // Check that the map of the global has not changed. |
| 2570 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), | 2587 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), |
| 2571 Immediate(Handle<Map>(object->map()))); | 2588 Immediate(Handle<Map>(object->map()))); |
| 2572 __ j(not_equal, &miss, not_taken); | 2589 __ j(not_equal, &miss, not_taken); |
| 2573 | 2590 |
| 2574 // Store the value in the cell. | 2591 // Store the value in the cell. |
| 2575 __ mov(ecx, Immediate(Handle<JSGlobalPropertyCell>(cell))); | 2592 if (Serializer::enabled()) { |
| 2576 __ mov(FieldOperand(ecx, JSGlobalPropertyCell::kValueOffset), eax); | 2593 __ mov(ecx, Immediate(Handle<JSGlobalPropertyCell>(cell))); |
| 2594 __ mov(FieldOperand(ecx, JSGlobalPropertyCell::kValueOffset), eax); |
| 2595 } else { |
| 2596 __ mov(Operand::Cell(Handle<JSGlobalPropertyCell>(cell)), eax); |
| 2597 } |
| 2577 | 2598 |
| 2578 // Return the value (register eax). | 2599 // Return the value (register eax). |
| 2579 __ IncrementCounter(COUNTERS->named_store_global_inline(), 1); | 2600 __ IncrementCounter(COUNTERS->named_store_global_inline(), 1); |
| 2580 __ ret(0); | 2601 __ ret(0); |
| 2581 | 2602 |
| 2582 // Handle store cache miss. | 2603 // Handle store cache miss. |
| 2583 __ bind(&miss); | 2604 __ bind(&miss); |
| 2584 __ IncrementCounter(COUNTERS->named_store_global_inline_miss(), 1); | 2605 __ IncrementCounter(COUNTERS->named_store_global_inline_miss(), 1); |
| 2585 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 2606 Handle<Code> ic(Isolate::Current()->builtins()->builtin( |
| 2586 Builtins::StoreIC_Miss)); | 2607 Builtins::StoreIC_Miss)); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2622 __ DecrementCounter(COUNTERS->keyed_store_field(), 1); | 2643 __ DecrementCounter(COUNTERS->keyed_store_field(), 1); |
| 2623 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 2644 Handle<Code> ic(Isolate::Current()->builtins()->builtin( |
| 2624 Builtins::KeyedStoreIC_Miss)); | 2645 Builtins::KeyedStoreIC_Miss)); |
| 2625 __ jmp(ic, RelocInfo::CODE_TARGET); | 2646 __ jmp(ic, RelocInfo::CODE_TARGET); |
| 2626 | 2647 |
| 2627 // Return the generated code. | 2648 // Return the generated code. |
| 2628 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 2649 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); |
| 2629 } | 2650 } |
| 2630 | 2651 |
| 2631 | 2652 |
| 2653 MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized( |
| 2654 JSObject* receiver) { |
| 2655 // ----------- S t a t e ------------- |
| 2656 // -- eax : value |
| 2657 // -- ecx : key |
| 2658 // -- edx : receiver |
| 2659 // -- esp[0] : return address |
| 2660 // ----------------------------------- |
| 2661 Label miss; |
| 2662 |
| 2663 // Check that the receiver isn't a smi. |
| 2664 __ test(edx, Immediate(kSmiTagMask)); |
| 2665 __ j(zero, &miss, not_taken); |
| 2666 |
| 2667 // Check that the map matches. |
| 2668 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), |
| 2669 Immediate(Handle<Map>(receiver->map()))); |
| 2670 __ j(not_equal, &miss, not_taken); |
| 2671 |
| 2672 // Check that the key is a smi. |
| 2673 __ test(ecx, Immediate(kSmiTagMask)); |
| 2674 __ j(not_zero, &miss, not_taken); |
| 2675 |
| 2676 // Get the elements array and make sure it is a fast element array, not 'cow'. |
| 2677 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); |
| 2678 __ cmp(FieldOperand(edi, HeapObject::kMapOffset), |
| 2679 Immediate(FACTORY->fixed_array_map())); |
| 2680 __ j(not_equal, &miss, not_taken); |
| 2681 |
| 2682 // Check that the key is within bounds. |
| 2683 if (receiver->IsJSArray()) { |
| 2684 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis. |
| 2685 __ j(above_equal, &miss, not_taken); |
| 2686 } else { |
| 2687 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // Compare smis. |
| 2688 __ j(above_equal, &miss, not_taken); |
| 2689 } |
| 2690 |
| 2691 // Do the store and update the write barrier. Make sure to preserve |
| 2692 // the value in register eax. |
| 2693 __ mov(edx, Operand(eax)); |
| 2694 __ mov(FieldOperand(edi, ecx, times_2, FixedArray::kHeaderSize), eax); |
| 2695 __ RecordWrite(edi, 0, edx, ecx); |
| 2696 |
| 2697 // Done. |
| 2698 __ ret(0); |
| 2699 |
| 2700 // Handle store cache miss. |
| 2701 __ bind(&miss); |
| 2702 Handle<Code> ic( |
| 2703 Isolate::Current()->builtins()->builtin(Builtins::KeyedStoreIC_Miss)); |
| 2704 __ jmp(ic, RelocInfo::CODE_TARGET); |
| 2705 |
| 2706 // Return the generated code. |
| 2707 return GetCode(NORMAL, NULL); |
| 2708 } |
| 2709 |
| 2710 |
| 2632 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, | 2711 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, |
| 2633 JSObject* object, | 2712 JSObject* object, |
| 2634 JSObject* last) { | 2713 JSObject* last) { |
| 2635 // ----------- S t a t e ------------- | 2714 // ----------- S t a t e ------------- |
| 2636 // -- eax : receiver | 2715 // -- eax : receiver |
| 2637 // -- ecx : name | 2716 // -- ecx : name |
| 2638 // -- esp[0] : return address | 2717 // -- esp[0] : return address |
| 2639 // ----------------------------------- | 2718 // ----------------------------------- |
| 2640 Label miss; | 2719 Label miss; |
| 2641 | 2720 |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2795 // the receiver cannot be a smi. | 2874 // the receiver cannot be a smi. |
| 2796 if (object != holder) { | 2875 if (object != holder) { |
| 2797 __ test(eax, Immediate(kSmiTagMask)); | 2876 __ test(eax, Immediate(kSmiTagMask)); |
| 2798 __ j(zero, &miss, not_taken); | 2877 __ j(zero, &miss, not_taken); |
| 2799 } | 2878 } |
| 2800 | 2879 |
| 2801 // Check that the maps haven't changed. | 2880 // Check that the maps haven't changed. |
| 2802 CheckPrototypes(object, eax, holder, ebx, edx, edi, name, &miss); | 2881 CheckPrototypes(object, eax, holder, ebx, edx, edi, name, &miss); |
| 2803 | 2882 |
| 2804 // Get the value from the cell. | 2883 // Get the value from the cell. |
| 2805 __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell))); | 2884 if (Serializer::enabled()) { |
| 2806 __ mov(ebx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset)); | 2885 __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell))); |
| 2886 __ mov(ebx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset)); |
| 2887 } else { |
| 2888 __ mov(ebx, Operand::Cell(Handle<JSGlobalPropertyCell>(cell))); |
| 2889 } |
| 2807 | 2890 |
| 2808 // Check for deleted property if property can actually be deleted. | 2891 // Check for deleted property if property can actually be deleted. |
| 2809 if (!is_dont_delete) { | 2892 if (!is_dont_delete) { |
| 2810 __ cmp(ebx, FACTORY->the_hole_value()); | 2893 __ cmp(ebx, FACTORY->the_hole_value()); |
| 2811 __ j(equal, &miss, not_taken); | 2894 __ j(equal, &miss, not_taken); |
| 2812 } else if (FLAG_debug_code) { | 2895 } else if (FLAG_debug_code) { |
| 2813 __ cmp(ebx, FACTORY->the_hole_value()); | 2896 __ cmp(ebx, FACTORY->the_hole_value()); |
| 2814 __ Check(not_equal, "DontDelete cells can't contain the hole"); | 2897 __ Check(not_equal, "DontDelete cells can't contain the hole"); |
| 2815 } | 2898 } |
| 2816 | 2899 |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3021 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss); | 3104 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss); |
| 3022 __ bind(&miss); | 3105 __ bind(&miss); |
| 3023 __ DecrementCounter(COUNTERS->keyed_load_function_prototype(), 1); | 3106 __ DecrementCounter(COUNTERS->keyed_load_function_prototype(), 1); |
| 3024 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3107 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 3025 | 3108 |
| 3026 // Return the generated code. | 3109 // Return the generated code. |
| 3027 return GetCode(CALLBACKS, name); | 3110 return GetCode(CALLBACKS, name); |
| 3028 } | 3111 } |
| 3029 | 3112 |
| 3030 | 3113 |
| 3114 MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) { |
| 3115 // ----------- S t a t e ------------- |
| 3116 // -- eax : key |
| 3117 // -- edx : receiver |
| 3118 // -- esp[0] : return address |
| 3119 // ----------------------------------- |
| 3120 Label miss; |
| 3121 |
| 3122 // Check that the receiver isn't a smi. |
| 3123 __ test(edx, Immediate(kSmiTagMask)); |
| 3124 __ j(zero, &miss, not_taken); |
| 3125 |
| 3126 // Check that the map matches. |
| 3127 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), |
| 3128 Immediate(Handle<Map>(receiver->map()))); |
| 3129 __ j(not_equal, &miss, not_taken); |
| 3130 |
| 3131 // Check that the key is a smi. |
| 3132 __ test(eax, Immediate(kSmiTagMask)); |
| 3133 __ j(not_zero, &miss, not_taken); |
| 3134 |
| 3135 // Get the elements array. |
| 3136 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); |
| 3137 __ AssertFastElements(ecx); |
| 3138 |
| 3139 // Check that the key is within bounds. |
| 3140 __ cmp(eax, FieldOperand(ecx, FixedArray::kLengthOffset)); |
| 3141 __ j(above_equal, &miss, not_taken); |
| 3142 |
| 3143 // Load the result and make sure it's not the hole. |
| 3144 __ mov(ebx, Operand(ecx, eax, times_2, |
| 3145 FixedArray::kHeaderSize - kHeapObjectTag)); |
| 3146 __ cmp(ebx, FACTORY->the_hole_value()); |
| 3147 __ j(equal, &miss, not_taken); |
| 3148 __ mov(eax, ebx); |
| 3149 __ ret(0); |
| 3150 |
| 3151 __ bind(&miss); |
| 3152 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 3153 |
| 3154 // Return the generated code. |
| 3155 return GetCode(NORMAL, NULL); |
| 3156 } |
| 3157 |
| 3158 |
| 3031 // Specialized stub for constructing objects from functions which only have only | 3159 // Specialized stub for constructing objects from functions which only have only |
| 3032 // simple assignments of the form this.x = ...; in their body. | 3160 // simple assignments of the form this.x = ...; in their body. |
| 3033 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { | 3161 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { |
| 3034 // ----------- S t a t e ------------- | 3162 // ----------- S t a t e ------------- |
| 3035 // -- eax : argc | 3163 // -- eax : argc |
| 3036 // -- edi : constructor | 3164 // -- edi : constructor |
| 3037 // -- esp[0] : return address | 3165 // -- esp[0] : return address |
| 3038 // -- esp[4] : last argument | 3166 // -- esp[4] : last argument |
| 3039 // ----------------------------------- | 3167 // ----------------------------------- |
| 3040 Label generic_stub_call; | 3168 Label generic_stub_call; |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3165 // Return the generated code. | 3293 // Return the generated code. |
| 3166 return GetCode(); | 3294 return GetCode(); |
| 3167 } | 3295 } |
| 3168 | 3296 |
| 3169 | 3297 |
| 3170 #undef __ | 3298 #undef __ |
| 3171 | 3299 |
| 3172 } } // namespace v8::internal | 3300 } } // namespace v8::internal |
| 3173 | 3301 |
| 3174 #endif // V8_TARGET_ARCH_IA32 | 3302 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |