| 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 1754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1765 case Token::SHR: | 1765 case Token::SHR: |
| 1766 GenerateTypeTransitionWithSavedArgs(masm); | 1766 GenerateTypeTransitionWithSavedArgs(masm); |
| 1767 break; | 1767 break; |
| 1768 default: | 1768 default: |
| 1769 UNREACHABLE(); | 1769 UNREACHABLE(); |
| 1770 } | 1770 } |
| 1771 } | 1771 } |
| 1772 | 1772 |
| 1773 | 1773 |
| 1774 void TypeRecordingBinaryOpStub::GenerateStringStub(MacroAssembler* masm) { | 1774 void TypeRecordingBinaryOpStub::GenerateStringStub(MacroAssembler* masm) { |
| 1775 Label call_runtime; | |
| 1776 ASSERT(operands_type_ == TRBinaryOpIC::STRING); | 1775 ASSERT(operands_type_ == TRBinaryOpIC::STRING); |
| 1777 ASSERT(op_ == Token::ADD); | 1776 ASSERT(op_ == Token::ADD); |
| 1778 // If one of the arguments is a string, call the string add stub. | 1777 // Try to add arguments as strings, otherwise, transition to the generic |
| 1779 // Otherwise, transition to the generic TRBinaryOpIC type. | 1778 // TRBinaryOpIC type. |
| 1780 | 1779 GenerateAddStrings(masm); |
| 1781 // Registers containing left and right operands respectively. | |
| 1782 Register left = edx; | |
| 1783 Register right = eax; | |
| 1784 | |
| 1785 // Test if left operand is a string. | |
| 1786 NearLabel left_not_string; | |
| 1787 __ test(left, Immediate(kSmiTagMask)); | |
| 1788 __ j(zero, &left_not_string); | |
| 1789 __ CmpObjectType(left, FIRST_NONSTRING_TYPE, ecx); | |
| 1790 __ j(above_equal, &left_not_string); | |
| 1791 | |
| 1792 StringAddStub string_add_left_stub(NO_STRING_CHECK_LEFT_IN_STUB); | |
| 1793 GenerateRegisterArgsPush(masm); | |
| 1794 __ TailCallStub(&string_add_left_stub); | |
| 1795 | |
| 1796 // Left operand is not a string, test right. | |
| 1797 __ bind(&left_not_string); | |
| 1798 __ test(right, Immediate(kSmiTagMask)); | |
| 1799 __ j(zero, &call_runtime); | |
| 1800 __ CmpObjectType(right, FIRST_NONSTRING_TYPE, ecx); | |
| 1801 __ j(above_equal, &call_runtime); | |
| 1802 | |
| 1803 StringAddStub string_add_right_stub(NO_STRING_CHECK_RIGHT_IN_STUB); | |
| 1804 GenerateRegisterArgsPush(masm); | |
| 1805 __ TailCallStub(&string_add_right_stub); | |
| 1806 | |
| 1807 // Neither argument is a string. | |
| 1808 __ bind(&call_runtime); | |
| 1809 GenerateTypeTransition(masm); | 1780 GenerateTypeTransition(masm); |
| 1810 } | 1781 } |
| 1811 | 1782 |
| 1812 | 1783 |
| 1813 void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { | 1784 void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { |
| 1814 Label call_runtime; | 1785 Label call_runtime; |
| 1815 ASSERT(operands_type_ == TRBinaryOpIC::INT32); | 1786 ASSERT(operands_type_ == TRBinaryOpIC::INT32); |
| 1816 | 1787 |
| 1817 // Floating point case. | 1788 // Floating point case. |
| 1818 switch (op_) { | 1789 switch (op_) { |
| (...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2339 break; | 2310 break; |
| 2340 } | 2311 } |
| 2341 default: UNREACHABLE(); break; | 2312 default: UNREACHABLE(); break; |
| 2342 } | 2313 } |
| 2343 | 2314 |
| 2344 // If all else fails, use the runtime system to get the correct | 2315 // If all else fails, use the runtime system to get the correct |
| 2345 // result. | 2316 // result. |
| 2346 __ bind(&call_runtime); | 2317 __ bind(&call_runtime); |
| 2347 switch (op_) { | 2318 switch (op_) { |
| 2348 case Token::ADD: { | 2319 case Token::ADD: { |
| 2320 GenerateAddStrings(masm); |
| 2349 GenerateRegisterArgsPush(masm); | 2321 GenerateRegisterArgsPush(masm); |
| 2350 // Test for string arguments before calling runtime. | |
| 2351 // Registers containing left and right operands respectively. | |
| 2352 Register lhs, rhs; | |
| 2353 lhs = edx; | |
| 2354 rhs = eax; | |
| 2355 | |
| 2356 // Test if left operand is a string. | |
| 2357 NearLabel lhs_not_string; | |
| 2358 __ test(lhs, Immediate(kSmiTagMask)); | |
| 2359 __ j(zero, &lhs_not_string); | |
| 2360 __ CmpObjectType(lhs, FIRST_NONSTRING_TYPE, ecx); | |
| 2361 __ j(above_equal, &lhs_not_string); | |
| 2362 | |
| 2363 StringAddStub string_add_left_stub(NO_STRING_CHECK_LEFT_IN_STUB); | |
| 2364 __ TailCallStub(&string_add_left_stub); | |
| 2365 | |
| 2366 NearLabel call_add_runtime; | |
| 2367 // Left operand is not a string, test right. | |
| 2368 __ bind(&lhs_not_string); | |
| 2369 __ test(rhs, Immediate(kSmiTagMask)); | |
| 2370 __ j(zero, &call_add_runtime); | |
| 2371 __ CmpObjectType(rhs, FIRST_NONSTRING_TYPE, ecx); | |
| 2372 __ j(above_equal, &call_add_runtime); | |
| 2373 | |
| 2374 StringAddStub string_add_right_stub(NO_STRING_CHECK_RIGHT_IN_STUB); | |
| 2375 __ TailCallStub(&string_add_right_stub); | |
| 2376 | |
| 2377 // Neither argument is a string. | |
| 2378 __ bind(&call_add_runtime); | |
| 2379 __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION); | 2322 __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION); |
| 2380 break; | 2323 break; |
| 2381 } | 2324 } |
| 2382 case Token::SUB: | 2325 case Token::SUB: |
| 2383 GenerateRegisterArgsPush(masm); | 2326 GenerateRegisterArgsPush(masm); |
| 2384 __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION); | 2327 __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION); |
| 2385 break; | 2328 break; |
| 2386 case Token::MUL: | 2329 case Token::MUL: |
| 2387 GenerateRegisterArgsPush(masm); | 2330 GenerateRegisterArgsPush(masm); |
| 2388 __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION); | 2331 __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2411 break; | 2354 break; |
| 2412 case Token::SHR: | 2355 case Token::SHR: |
| 2413 __ InvokeBuiltin(Builtins::SHR, JUMP_FUNCTION); | 2356 __ InvokeBuiltin(Builtins::SHR, JUMP_FUNCTION); |
| 2414 break; | 2357 break; |
| 2415 default: | 2358 default: |
| 2416 UNREACHABLE(); | 2359 UNREACHABLE(); |
| 2417 } | 2360 } |
| 2418 } | 2361 } |
| 2419 | 2362 |
| 2420 | 2363 |
| 2364 void TypeRecordingBinaryOpStub::GenerateAddStrings(MacroAssembler* masm) { |
| 2365 NearLabel call_runtime; |
| 2366 |
| 2367 // Registers containing left and right operands respectively. |
| 2368 Register left = edx; |
| 2369 Register right = eax; |
| 2370 |
| 2371 // Test if left operand is a string. |
| 2372 NearLabel left_not_string; |
| 2373 __ test(left, Immediate(kSmiTagMask)); |
| 2374 __ j(zero, &left_not_string); |
| 2375 __ CmpObjectType(left, FIRST_NONSTRING_TYPE, ecx); |
| 2376 __ j(above_equal, &left_not_string); |
| 2377 |
| 2378 StringAddStub string_add_left_stub(NO_STRING_CHECK_LEFT_IN_STUB); |
| 2379 GenerateRegisterArgsPush(masm); |
| 2380 __ TailCallStub(&string_add_left_stub); |
| 2381 |
| 2382 // Left operand is not a string, test right. |
| 2383 __ bind(&left_not_string); |
| 2384 __ test(right, Immediate(kSmiTagMask)); |
| 2385 __ j(zero, &call_runtime); |
| 2386 __ CmpObjectType(right, FIRST_NONSTRING_TYPE, ecx); |
| 2387 __ j(above_equal, &call_runtime); |
| 2388 |
| 2389 StringAddStub string_add_right_stub(NO_STRING_CHECK_RIGHT_IN_STUB); |
| 2390 GenerateRegisterArgsPush(masm); |
| 2391 __ TailCallStub(&string_add_right_stub); |
| 2392 |
| 2393 // Neither argument is a string. |
| 2394 __ bind(&call_runtime); |
| 2395 } |
| 2396 |
| 2397 |
| 2421 void TypeRecordingBinaryOpStub::GenerateHeapResultAllocation( | 2398 void TypeRecordingBinaryOpStub::GenerateHeapResultAllocation( |
| 2422 MacroAssembler* masm, | 2399 MacroAssembler* masm, |
| 2423 Label* alloc_failure) { | 2400 Label* alloc_failure) { |
| 2424 Label skip_allocation; | 2401 Label skip_allocation; |
| 2425 OverwriteMode mode = mode_; | 2402 OverwriteMode mode = mode_; |
| 2426 switch (mode) { | 2403 switch (mode) { |
| 2427 case OVERWRITE_LEFT: { | 2404 case OVERWRITE_LEFT: { |
| 2428 // If the argument in edx is already an object, we skip the | 2405 // If the argument in edx is already an object, we skip the |
| 2429 // allocation of a heap number. | 2406 // allocation of a heap number. |
| 2430 __ test(edx, Immediate(kSmiTagMask)); | 2407 __ test(edx, Immediate(kSmiTagMask)); |
| (...skipping 4074 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6505 // Do a tail call to the rewritten stub. | 6482 // Do a tail call to the rewritten stub. |
| 6506 __ jmp(Operand(edi)); | 6483 __ jmp(Operand(edi)); |
| 6507 } | 6484 } |
| 6508 | 6485 |
| 6509 | 6486 |
| 6510 #undef __ | 6487 #undef __ |
| 6511 | 6488 |
| 6512 } } // namespace v8::internal | 6489 } } // namespace v8::internal |
| 6513 | 6490 |
| 6514 #endif // V8_TARGET_ARCH_IA32 | 6491 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |