| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 1244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1255 CEntryStub stub(1, kSaveFPRegs); | 1255 CEntryStub stub(1, kSaveFPRegs); |
| 1256 CallStub(&stub); | 1256 CallStub(&stub); |
| 1257 } | 1257 } |
| 1258 | 1258 |
| 1259 | 1259 |
| 1260 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { | 1260 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { |
| 1261 return ref0.address() - ref1.address(); | 1261 return ref0.address() - ref1.address(); |
| 1262 } | 1262 } |
| 1263 | 1263 |
| 1264 | 1264 |
| 1265 void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function, | 1265 void MacroAssembler::CallApiFunctionAndReturn( |
| 1266 Address function_address, | 1266 ExternalReference function, |
| 1267 ExternalReference thunk_ref, | 1267 Address function_address, |
| 1268 Register thunk_last_arg, | 1268 ExternalReference thunk_ref, |
| 1269 int stack_space, | 1269 Register thunk_last_arg, |
| 1270 int spill_offset, | 1270 int stack_space, |
| 1271 int return_value_offset_from_fp) { | 1271 int spill_offset, |
| 1272 MemOperand return_value_operand, |
| 1273 MemOperand* context_restore_operand) { |
| 1272 ASM_LOCATION("CallApiFunctionAndReturn"); | 1274 ASM_LOCATION("CallApiFunctionAndReturn"); |
| 1273 ExternalReference next_address = | 1275 ExternalReference next_address = |
| 1274 ExternalReference::handle_scope_next_address(isolate()); | 1276 ExternalReference::handle_scope_next_address(isolate()); |
| 1275 const int kNextOffset = 0; | 1277 const int kNextOffset = 0; |
| 1276 const int kLimitOffset = AddressOffset( | 1278 const int kLimitOffset = AddressOffset( |
| 1277 ExternalReference::handle_scope_limit_address(isolate()), | 1279 ExternalReference::handle_scope_limit_address(isolate()), |
| 1278 next_address); | 1280 next_address); |
| 1279 const int kLevelOffset = AddressOffset( | 1281 const int kLevelOffset = AddressOffset( |
| 1280 ExternalReference::handle_scope_level_address(isolate()), | 1282 ExternalReference::handle_scope_level_address(isolate()), |
| 1281 next_address); | 1283 next_address); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1339 | 1341 |
| 1340 if (FLAG_log_timer_events) { | 1342 if (FLAG_log_timer_events) { |
| 1341 FrameScope frame(this, StackFrame::MANUAL); | 1343 FrameScope frame(this, StackFrame::MANUAL); |
| 1342 PushSafepointRegisters(); | 1344 PushSafepointRegisters(); |
| 1343 Mov(x0, Operand(ExternalReference::isolate_address(isolate()))); | 1345 Mov(x0, Operand(ExternalReference::isolate_address(isolate()))); |
| 1344 CallCFunction(ExternalReference::log_leave_external_function(isolate()), 1); | 1346 CallCFunction(ExternalReference::log_leave_external_function(isolate()), 1); |
| 1345 PopSafepointRegisters(); | 1347 PopSafepointRegisters(); |
| 1346 } | 1348 } |
| 1347 | 1349 |
| 1348 Label promote_scheduled_exception; | 1350 Label promote_scheduled_exception; |
| 1351 Label exception_handled; |
| 1349 Label delete_allocated_handles; | 1352 Label delete_allocated_handles; |
| 1350 Label leave_exit_frame; | 1353 Label leave_exit_frame; |
| 1351 Label result_is_not_null; | 1354 Label result_is_not_null; |
| 1352 Label return_value_loaded; | 1355 Label return_value_loaded; |
| 1353 | 1356 |
| 1354 // load value from ReturnValue | 1357 // load value from ReturnValue |
| 1355 Ldr(x0, MemOperand(fp, return_value_offset_from_fp * kPointerSize)); | 1358 Ldr(x0, return_value_operand); |
| 1356 Bind(&return_value_loaded); | 1359 Bind(&return_value_loaded); |
| 1357 // No more valid handles (the result handle was the last one). Restore | 1360 // No more valid handles (the result handle was the last one). Restore |
| 1358 // previous handle scope. | 1361 // previous handle scope. |
| 1359 Str(next_address_reg, MemOperand(handle_scope_base, kNextOffset)); | 1362 Str(next_address_reg, MemOperand(handle_scope_base, kNextOffset)); |
| 1360 if (emit_debug_code()) { | 1363 if (emit_debug_code()) { |
| 1361 Ldr(w1, MemOperand(handle_scope_base, kLevelOffset)); | 1364 Ldr(w1, MemOperand(handle_scope_base, kLevelOffset)); |
| 1362 Cmp(w1, level_reg); | 1365 Cmp(w1, level_reg); |
| 1363 Check(eq, kUnexpectedLevelAfterReturnFromApiCall); | 1366 Check(eq, kUnexpectedLevelAfterReturnFromApiCall); |
| 1364 } | 1367 } |
| 1365 Sub(level_reg, level_reg, 1); | 1368 Sub(level_reg, level_reg, 1); |
| 1366 Str(level_reg, MemOperand(handle_scope_base, kLevelOffset)); | 1369 Str(level_reg, MemOperand(handle_scope_base, kLevelOffset)); |
| 1367 Ldr(x1, MemOperand(handle_scope_base, kLimitOffset)); | 1370 Ldr(x1, MemOperand(handle_scope_base, kLimitOffset)); |
| 1368 Cmp(limit_reg, x1); | 1371 Cmp(limit_reg, x1); |
| 1369 B(ne, &delete_allocated_handles); | 1372 B(ne, &delete_allocated_handles); |
| 1370 | 1373 |
| 1371 Bind(&leave_exit_frame); | 1374 Bind(&leave_exit_frame); |
| 1372 // Restore callee-saved registers. | 1375 // Restore callee-saved registers. |
| 1373 Peek(x19, (spill_offset + 0) * kXRegSizeInBytes); | 1376 Peek(x19, (spill_offset + 0) * kXRegSizeInBytes); |
| 1374 Peek(x20, (spill_offset + 1) * kXRegSizeInBytes); | 1377 Peek(x20, (spill_offset + 1) * kXRegSizeInBytes); |
| 1375 Peek(x21, (spill_offset + 2) * kXRegSizeInBytes); | 1378 Peek(x21, (spill_offset + 2) * kXRegSizeInBytes); |
| 1376 Peek(x22, (spill_offset + 3) * kXRegSizeInBytes); | 1379 Peek(x22, (spill_offset + 3) * kXRegSizeInBytes); |
| 1377 | 1380 |
| 1378 // Check if the function scheduled an exception. | 1381 // Check if the function scheduled an exception. |
| 1379 Mov(x5, Operand(ExternalReference::scheduled_exception_address(isolate()))); | 1382 Mov(x5, Operand(ExternalReference::scheduled_exception_address(isolate()))); |
| 1380 Ldr(x5, MemOperand(x5)); | 1383 Ldr(x5, MemOperand(x5)); |
| 1381 JumpIfNotRoot(x5, Heap::kTheHoleValueRootIndex, &promote_scheduled_exception); | 1384 JumpIfNotRoot(x5, Heap::kTheHoleValueRootIndex, &promote_scheduled_exception); |
| 1385 Bind(&exception_handled); |
| 1382 | 1386 |
| 1383 LeaveExitFrame(false, x1); | 1387 bool restore_context = context_restore_operand != NULL; |
| 1388 if (restore_context) { |
| 1389 Ldr(cp, *context_restore_operand); |
| 1390 } |
| 1391 |
| 1392 LeaveExitFrame(false, x1, !restore_context); |
| 1384 Drop(stack_space); | 1393 Drop(stack_space); |
| 1385 Ret(); | 1394 Ret(); |
| 1386 | 1395 |
| 1387 Bind(&promote_scheduled_exception); | 1396 Bind(&promote_scheduled_exception); |
| 1388 TailCallExternalReference( | 1397 { |
| 1389 ExternalReference(Runtime::kPromoteScheduledException, isolate()), | 1398 FrameScope frame(this, StackFrame::INTERNAL); |
| 1390 0, | 1399 CallExternalReference( |
| 1391 1); | 1400 ExternalReference(Runtime::kPromoteScheduledException, isolate()), 0); |
| 1401 } |
| 1402 B(&exception_handled); |
| 1392 | 1403 |
| 1393 // HandleScope limit has changed. Delete allocated extensions. | 1404 // HandleScope limit has changed. Delete allocated extensions. |
| 1394 Bind(&delete_allocated_handles); | 1405 Bind(&delete_allocated_handles); |
| 1395 Str(limit_reg, MemOperand(handle_scope_base, kLimitOffset)); | 1406 Str(limit_reg, MemOperand(handle_scope_base, kLimitOffset)); |
| 1396 // Save the return value in a callee-save register. | 1407 // Save the return value in a callee-save register. |
| 1397 Register saved_result = x19; | 1408 Register saved_result = x19; |
| 1398 Mov(saved_result, x0); | 1409 Mov(saved_result, x0); |
| 1399 Mov(x0, Operand(ExternalReference::isolate_address(isolate()))); | 1410 Mov(x0, Operand(ExternalReference::isolate_address(isolate()))); |
| 1400 CallCFunction( | 1411 CallCFunction( |
| 1401 ExternalReference::delete_handle_scope_extensions(isolate()), 1); | 1412 ExternalReference::delete_handle_scope_extensions(isolate()), 1); |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1788 void MacroAssembler::JumpIfNotHeapNumber(Register object, | 1799 void MacroAssembler::JumpIfNotHeapNumber(Register object, |
| 1789 Label* on_not_heap_number, | 1800 Label* on_not_heap_number, |
| 1790 Register heap_number_map) { | 1801 Register heap_number_map) { |
| 1791 JumpForHeapNumber(object, | 1802 JumpForHeapNumber(object, |
| 1792 heap_number_map, | 1803 heap_number_map, |
| 1793 NULL, | 1804 NULL, |
| 1794 on_not_heap_number); | 1805 on_not_heap_number); |
| 1795 } | 1806 } |
| 1796 | 1807 |
| 1797 | 1808 |
| 1809 void MacroAssembler::LookupNumberStringCache(Register object, |
| 1810 Register result, |
| 1811 Register scratch1, |
| 1812 Register scratch2, |
| 1813 Register scratch3, |
| 1814 Label* not_found) { |
| 1815 ASSERT(!AreAliased(object, result, scratch1, scratch2, scratch3)); |
| 1816 |
| 1817 // Use of registers. Register result is used as a temporary. |
| 1818 Register number_string_cache = result; |
| 1819 Register mask = scratch3; |
| 1820 |
| 1821 // Load the number string cache. |
| 1822 LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); |
| 1823 |
| 1824 // Make the hash mask from the length of the number string cache. It |
| 1825 // contains two elements (number and string) for each cache entry. |
| 1826 Ldrsw(mask, UntagSmiFieldMemOperand(number_string_cache, |
| 1827 FixedArray::kLengthOffset)); |
| 1828 Asr(mask, mask, 1); // Divide length by two. |
| 1829 Sub(mask, mask, 1); // Make mask. |
| 1830 |
| 1831 // Calculate the entry in the number string cache. The hash value in the |
| 1832 // number string cache for smis is just the smi value, and the hash for |
| 1833 // doubles is the xor of the upper and lower words. See |
| 1834 // Heap::GetNumberStringCache. |
| 1835 Label is_smi; |
| 1836 Label load_result_from_cache; |
| 1837 |
| 1838 JumpIfSmi(object, &is_smi); |
| 1839 CheckMap(object, scratch1, Heap::kHeapNumberMapRootIndex, not_found, |
| 1840 DONT_DO_SMI_CHECK); |
| 1841 |
| 1842 STATIC_ASSERT(kDoubleSize == (kWRegSizeInBytes * 2)); |
| 1843 Add(scratch1, object, HeapNumber::kValueOffset - kHeapObjectTag); |
| 1844 Ldp(scratch1.W(), scratch2.W(), MemOperand(scratch1)); |
| 1845 Eor(scratch1, scratch1, scratch2); |
| 1846 And(scratch1, scratch1, mask); |
| 1847 |
| 1848 // Calculate address of entry in string cache: each entry consists of two |
| 1849 // pointer sized fields. |
| 1850 Add(scratch1, number_string_cache, |
| 1851 Operand(scratch1, LSL, kPointerSizeLog2 + 1)); |
| 1852 |
| 1853 Register probe = mask; |
| 1854 Ldr(probe, FieldMemOperand(scratch1, FixedArray::kHeaderSize)); |
| 1855 JumpIfSmi(probe, not_found); |
| 1856 Ldr(d0, FieldMemOperand(object, HeapNumber::kValueOffset)); |
| 1857 Ldr(d1, FieldMemOperand(probe, HeapNumber::kValueOffset)); |
| 1858 Fcmp(d0, d1); |
| 1859 B(ne, not_found); |
| 1860 B(&load_result_from_cache); |
| 1861 |
| 1862 Bind(&is_smi); |
| 1863 Register scratch = scratch1; |
| 1864 And(scratch, mask, Operand::UntagSmi(object)); |
| 1865 // Calculate address of entry in string cache: each entry consists |
| 1866 // of two pointer sized fields. |
| 1867 Add(scratch, number_string_cache, |
| 1868 Operand(scratch, LSL, kPointerSizeLog2 + 1)); |
| 1869 |
| 1870 // Check if the entry is the smi we are looking for. |
| 1871 Ldr(probe, FieldMemOperand(scratch, FixedArray::kHeaderSize)); |
| 1872 Cmp(object, probe); |
| 1873 B(ne, not_found); |
| 1874 |
| 1875 // Get the result from the cache. |
| 1876 Bind(&load_result_from_cache); |
| 1877 Ldr(result, FieldMemOperand(scratch, FixedArray::kHeaderSize + kPointerSize)); |
| 1878 IncrementCounter(isolate()->counters()->number_to_string_native(), 1, |
| 1879 scratch1, scratch2); |
| 1880 } |
| 1881 |
| 1882 |
| 1798 void MacroAssembler::TryConvertDoubleToInt(Register as_int, | 1883 void MacroAssembler::TryConvertDoubleToInt(Register as_int, |
| 1799 FPRegister value, | 1884 FPRegister value, |
| 1800 FPRegister scratch_d, | 1885 FPRegister scratch_d, |
| 1801 Label* on_successful_conversion, | 1886 Label* on_successful_conversion, |
| 1802 Label* on_failed_conversion) { | 1887 Label* on_failed_conversion) { |
| 1803 // Convert to an int and back again, then compare with the original value. | 1888 // Convert to an int and back again, then compare with the original value. |
| 1804 Fcvtzs(as_int, value); | 1889 Fcvtzs(as_int, value); |
| 1805 Scvtf(scratch_d, as_int); | 1890 Scvtf(scratch_d, as_int); |
| 1806 Fcmp(value, scratch_d); | 1891 Fcmp(value, scratch_d); |
| 1807 | 1892 |
| (...skipping 798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2606 // the memory address immediately below the pointer stored in SPOffset. | 2691 // the memory address immediately below the pointer stored in SPOffset. |
| 2607 // It is not safe to derive much else from SPOffset, because the size of the | 2692 // It is not safe to derive much else from SPOffset, because the size of the |
| 2608 // padding can vary. | 2693 // padding can vary. |
| 2609 Add(scratch, csp, kXRegSizeInBytes); | 2694 Add(scratch, csp, kXRegSizeInBytes); |
| 2610 Str(scratch, MemOperand(fp, ExitFrameConstants::kSPOffset)); | 2695 Str(scratch, MemOperand(fp, ExitFrameConstants::kSPOffset)); |
| 2611 } | 2696 } |
| 2612 | 2697 |
| 2613 | 2698 |
| 2614 // Leave the current exit frame. | 2699 // Leave the current exit frame. |
| 2615 void MacroAssembler::LeaveExitFrame(bool restore_doubles, | 2700 void MacroAssembler::LeaveExitFrame(bool restore_doubles, |
| 2616 const Register& scratch) { | 2701 const Register& scratch, |
| 2702 bool restore_context) { |
| 2617 ASSERT(csp.Is(StackPointer())); | 2703 ASSERT(csp.Is(StackPointer())); |
| 2618 | 2704 |
| 2619 if (restore_doubles) { | 2705 if (restore_doubles) { |
| 2620 ExitFrameRestoreFPRegs(); | 2706 ExitFrameRestoreFPRegs(); |
| 2621 } | 2707 } |
| 2622 | 2708 |
| 2623 // Restore the context pointer from the top frame. | 2709 // Restore the context pointer from the top frame. |
| 2624 Mov(scratch, Operand(ExternalReference(Isolate::kContextAddress, | 2710 if (restore_context) { |
| 2625 isolate()))); | 2711 Mov(scratch, Operand(ExternalReference(Isolate::kContextAddress, |
| 2626 Ldr(cp, MemOperand(scratch)); | 2712 isolate()))); |
| 2713 Ldr(cp, MemOperand(scratch)); |
| 2714 } |
| 2715 |
| 2627 if (emit_debug_code()) { | 2716 if (emit_debug_code()) { |
| 2628 // Also emit debug code to clear the cp in the top frame. | 2717 // Also emit debug code to clear the cp in the top frame. |
| 2718 Mov(scratch, Operand(ExternalReference(Isolate::kContextAddress, |
| 2719 isolate()))); |
| 2629 Str(xzr, MemOperand(scratch)); | 2720 Str(xzr, MemOperand(scratch)); |
| 2630 } | 2721 } |
| 2631 // Clear the frame pointer from the top frame. | 2722 // Clear the frame pointer from the top frame. |
| 2632 Mov(scratch, Operand(ExternalReference(Isolate::kCEntryFPAddress, | 2723 Mov(scratch, Operand(ExternalReference(Isolate::kCEntryFPAddress, |
| 2633 isolate()))); | 2724 isolate()))); |
| 2634 Str(xzr, MemOperand(scratch)); | 2725 Str(xzr, MemOperand(scratch)); |
| 2635 | 2726 |
| 2636 // Pop the exit frame. | 2727 // Pop the exit frame. |
| 2637 // fp[8]: CallerPC (lr) | 2728 // fp[8]: CallerPC (lr) |
| 2638 // fp -> fp[0]: CallerFP (old fp) | 2729 // fp -> fp[0]: CallerFP (old fp) |
| (...skipping 1971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4610 } | 4701 } |
| 4611 } | 4702 } |
| 4612 | 4703 |
| 4613 | 4704 |
| 4614 #undef __ | 4705 #undef __ |
| 4615 | 4706 |
| 4616 | 4707 |
| 4617 } } // namespace v8::internal | 4708 } } // namespace v8::internal |
| 4618 | 4709 |
| 4619 #endif // V8_TARGET_ARCH_A64 | 4710 #endif // V8_TARGET_ARCH_A64 |
| OLD | NEW |