| OLD | NEW |
| 1 // Copyright 2010 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 |
| 11 // with the distribution. | 11 // with the distribution. |
| (...skipping 1757 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1769 case Token::SHR: | 1769 case Token::SHR: |
| 1770 GenerateTypeTransitionWithSavedArgs(masm); | 1770 GenerateTypeTransitionWithSavedArgs(masm); |
| 1771 break; | 1771 break; |
| 1772 default: | 1772 default: |
| 1773 UNREACHABLE(); | 1773 UNREACHABLE(); |
| 1774 } | 1774 } |
| 1775 } | 1775 } |
| 1776 | 1776 |
| 1777 | 1777 |
| 1778 void TypeRecordingBinaryOpStub::GenerateStringStub(MacroAssembler* masm) { | 1778 void TypeRecordingBinaryOpStub::GenerateStringStub(MacroAssembler* masm) { |
| 1779 Label call_runtime; | |
| 1780 ASSERT(operands_type_ == TRBinaryOpIC::STRING); | 1779 ASSERT(operands_type_ == TRBinaryOpIC::STRING); |
| 1781 ASSERT(op_ == Token::ADD); | 1780 ASSERT(op_ == Token::ADD); |
| 1782 // If one of the arguments is a string, call the string add stub. | 1781 // Try to add arguments as strings, otherwise, transition to the generic |
| 1783 // Otherwise, transition to the generic TRBinaryOpIC type. | 1782 // TRBinaryOpIC type. |
| 1784 | 1783 GenerateAddStrings(masm); |
| 1785 // Registers containing left and right operands respectively. | |
| 1786 Register left = edx; | |
| 1787 Register right = eax; | |
| 1788 | |
| 1789 // Test if left operand is a string. | |
| 1790 NearLabel left_not_string; | |
| 1791 __ test(left, Immediate(kSmiTagMask)); | |
| 1792 __ j(zero, &left_not_string); | |
| 1793 __ CmpObjectType(left, FIRST_NONSTRING_TYPE, ecx); | |
| 1794 __ j(above_equal, &left_not_string); | |
| 1795 | |
| 1796 StringAddStub string_add_left_stub(NO_STRING_CHECK_LEFT_IN_STUB); | |
| 1797 GenerateRegisterArgsPush(masm); | |
| 1798 __ TailCallStub(&string_add_left_stub); | |
| 1799 | |
| 1800 // Left operand is not a string, test right. | |
| 1801 __ bind(&left_not_string); | |
| 1802 __ test(right, Immediate(kSmiTagMask)); | |
| 1803 __ j(zero, &call_runtime); | |
| 1804 __ CmpObjectType(right, FIRST_NONSTRING_TYPE, ecx); | |
| 1805 __ j(above_equal, &call_runtime); | |
| 1806 | |
| 1807 StringAddStub string_add_right_stub(NO_STRING_CHECK_RIGHT_IN_STUB); | |
| 1808 GenerateRegisterArgsPush(masm); | |
| 1809 __ TailCallStub(&string_add_right_stub); | |
| 1810 | |
| 1811 // Neither argument is a string. | |
| 1812 __ bind(&call_runtime); | |
| 1813 GenerateTypeTransition(masm); | 1784 GenerateTypeTransition(masm); |
| 1814 } | 1785 } |
| 1815 | 1786 |
| 1816 | 1787 |
| 1817 void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { | 1788 void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { |
| 1818 Label call_runtime; | 1789 Label call_runtime; |
| 1819 ASSERT(operands_type_ == TRBinaryOpIC::INT32); | 1790 ASSERT(operands_type_ == TRBinaryOpIC::INT32); |
| 1820 | 1791 |
| 1821 // Floating point case. | 1792 // Floating point case. |
| 1822 switch (op_) { | 1793 switch (op_) { |
| (...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2343 break; | 2314 break; |
| 2344 } | 2315 } |
| 2345 default: UNREACHABLE(); break; | 2316 default: UNREACHABLE(); break; |
| 2346 } | 2317 } |
| 2347 | 2318 |
| 2348 // If all else fails, use the runtime system to get the correct | 2319 // If all else fails, use the runtime system to get the correct |
| 2349 // result. | 2320 // result. |
| 2350 __ bind(&call_runtime); | 2321 __ bind(&call_runtime); |
| 2351 switch (op_) { | 2322 switch (op_) { |
| 2352 case Token::ADD: { | 2323 case Token::ADD: { |
| 2324 GenerateAddStrings(masm); |
| 2353 GenerateRegisterArgsPush(masm); | 2325 GenerateRegisterArgsPush(masm); |
| 2354 // Test for string arguments before calling runtime. | |
| 2355 // Registers containing left and right operands respectively. | |
| 2356 Register lhs, rhs; | |
| 2357 lhs = edx; | |
| 2358 rhs = eax; | |
| 2359 | |
| 2360 // Test if left operand is a string. | |
| 2361 NearLabel lhs_not_string; | |
| 2362 __ test(lhs, Immediate(kSmiTagMask)); | |
| 2363 __ j(zero, &lhs_not_string); | |
| 2364 __ CmpObjectType(lhs, FIRST_NONSTRING_TYPE, ecx); | |
| 2365 __ j(above_equal, &lhs_not_string); | |
| 2366 | |
| 2367 StringAddStub string_add_left_stub(NO_STRING_CHECK_LEFT_IN_STUB); | |
| 2368 __ TailCallStub(&string_add_left_stub); | |
| 2369 | |
| 2370 NearLabel call_add_runtime; | |
| 2371 // Left operand is not a string, test right. | |
| 2372 __ bind(&lhs_not_string); | |
| 2373 __ test(rhs, Immediate(kSmiTagMask)); | |
| 2374 __ j(zero, &call_add_runtime); | |
| 2375 __ CmpObjectType(rhs, FIRST_NONSTRING_TYPE, ecx); | |
| 2376 __ j(above_equal, &call_add_runtime); | |
| 2377 | |
| 2378 StringAddStub string_add_right_stub(NO_STRING_CHECK_RIGHT_IN_STUB); | |
| 2379 __ TailCallStub(&string_add_right_stub); | |
| 2380 | |
| 2381 // Neither argument is a string. | |
| 2382 __ bind(&call_add_runtime); | |
| 2383 __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION); | 2326 __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION); |
| 2384 break; | 2327 break; |
| 2385 } | 2328 } |
| 2386 case Token::SUB: | 2329 case Token::SUB: |
| 2387 GenerateRegisterArgsPush(masm); | 2330 GenerateRegisterArgsPush(masm); |
| 2388 __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION); | 2331 __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION); |
| 2389 break; | 2332 break; |
| 2390 case Token::MUL: | 2333 case Token::MUL: |
| 2391 GenerateRegisterArgsPush(masm); | 2334 GenerateRegisterArgsPush(masm); |
| 2392 __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION); | 2335 __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2415 break; | 2358 break; |
| 2416 case Token::SHR: | 2359 case Token::SHR: |
| 2417 __ InvokeBuiltin(Builtins::SHR, JUMP_FUNCTION); | 2360 __ InvokeBuiltin(Builtins::SHR, JUMP_FUNCTION); |
| 2418 break; | 2361 break; |
| 2419 default: | 2362 default: |
| 2420 UNREACHABLE(); | 2363 UNREACHABLE(); |
| 2421 } | 2364 } |
| 2422 } | 2365 } |
| 2423 | 2366 |
| 2424 | 2367 |
| 2368 void TypeRecordingBinaryOpStub::GenerateAddStrings(MacroAssembler* masm) { |
| 2369 NearLabel call_runtime; |
| 2370 |
| 2371 // Registers containing left and right operands respectively. |
| 2372 Register left = edx; |
| 2373 Register right = eax; |
| 2374 |
| 2375 // Test if left operand is a string. |
| 2376 NearLabel left_not_string; |
| 2377 __ test(left, Immediate(kSmiTagMask)); |
| 2378 __ j(zero, &left_not_string); |
| 2379 __ CmpObjectType(left, FIRST_NONSTRING_TYPE, ecx); |
| 2380 __ j(above_equal, &left_not_string); |
| 2381 |
| 2382 StringAddStub string_add_left_stub(NO_STRING_CHECK_LEFT_IN_STUB); |
| 2383 GenerateRegisterArgsPush(masm); |
| 2384 __ TailCallStub(&string_add_left_stub); |
| 2385 |
| 2386 // Left operand is not a string, test right. |
| 2387 __ bind(&left_not_string); |
| 2388 __ test(right, Immediate(kSmiTagMask)); |
| 2389 __ j(zero, &call_runtime); |
| 2390 __ CmpObjectType(right, FIRST_NONSTRING_TYPE, ecx); |
| 2391 __ j(above_equal, &call_runtime); |
| 2392 |
| 2393 StringAddStub string_add_right_stub(NO_STRING_CHECK_RIGHT_IN_STUB); |
| 2394 GenerateRegisterArgsPush(masm); |
| 2395 __ TailCallStub(&string_add_right_stub); |
| 2396 |
| 2397 // Neither argument is a string. |
| 2398 __ bind(&call_runtime); |
| 2399 } |
| 2400 |
| 2401 |
| 2425 void TypeRecordingBinaryOpStub::GenerateHeapResultAllocation( | 2402 void TypeRecordingBinaryOpStub::GenerateHeapResultAllocation( |
| 2426 MacroAssembler* masm, | 2403 MacroAssembler* masm, |
| 2427 Label* alloc_failure) { | 2404 Label* alloc_failure) { |
| 2428 Label skip_allocation; | 2405 Label skip_allocation; |
| 2429 OverwriteMode mode = mode_; | 2406 OverwriteMode mode = mode_; |
| 2430 switch (mode) { | 2407 switch (mode) { |
| 2431 case OVERWRITE_LEFT: { | 2408 case OVERWRITE_LEFT: { |
| 2432 // If the argument in edx is already an object, we skip the | 2409 // If the argument in edx is already an object, we skip the |
| 2433 // allocation of a heap number. | 2410 // allocation of a heap number. |
| 2434 __ test(edx, Immediate(kSmiTagMask)); | 2411 __ test(edx, Immediate(kSmiTagMask)); |
| (...skipping 2226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4661 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); | 4638 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); |
| 4662 __ ret(0); | 4639 __ ret(0); |
| 4663 } | 4640 } |
| 4664 | 4641 |
| 4665 | 4642 |
| 4666 void CEntryStub::GenerateCore(MacroAssembler* masm, | 4643 void CEntryStub::GenerateCore(MacroAssembler* masm, |
| 4667 Label* throw_normal_exception, | 4644 Label* throw_normal_exception, |
| 4668 Label* throw_termination_exception, | 4645 Label* throw_termination_exception, |
| 4669 Label* throw_out_of_memory_exception, | 4646 Label* throw_out_of_memory_exception, |
| 4670 bool do_gc, | 4647 bool do_gc, |
| 4671 bool always_allocate_scope, | 4648 bool always_allocate_scope) { |
| 4672 int /* alignment_skew */) { | |
| 4673 // eax: result parameter for PerformGC, if any | 4649 // eax: result parameter for PerformGC, if any |
| 4674 // ebx: pointer to C function (C callee-saved) | 4650 // ebx: pointer to C function (C callee-saved) |
| 4675 // ebp: frame pointer (restored after C call) | 4651 // ebp: frame pointer (restored after C call) |
| 4676 // esp: stack pointer (restored after C call) | 4652 // esp: stack pointer (restored after C call) |
| 4677 // edi: number of arguments including receiver (C callee-saved) | 4653 // edi: number of arguments including receiver (C callee-saved) |
| 4678 // esi: pointer to the first argument (C callee-saved) | 4654 // esi: pointer to the first argument (C callee-saved) |
| 4679 | 4655 |
| 4680 // Result returned in eax, or eax+edx if result_size_ is 2. | 4656 // Result returned in eax, or eax+edx if result_size_ is 2. |
| 4681 | 4657 |
| 4682 // Check stack alignment. | 4658 // Check stack alignment. |
| (...skipping 1839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6522 // Do a tail call to the rewritten stub. | 6498 // Do a tail call to the rewritten stub. |
| 6523 __ jmp(Operand(edi)); | 6499 __ jmp(Operand(edi)); |
| 6524 } | 6500 } |
| 6525 | 6501 |
| 6526 | 6502 |
| 6527 #undef __ | 6503 #undef __ |
| 6528 | 6504 |
| 6529 } } // namespace v8::internal | 6505 } } // namespace v8::internal |
| 6530 | 6506 |
| 6531 #endif // V8_TARGET_ARCH_IA32 | 6507 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |