Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(950)

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 208073003: IA32: Rename MacroAssembler::Set() and MacroAssembler::SafeSet() to Move() and SafeMove(). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/builtins-ia32.cc ('k') | src/ia32/debug-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 1524 matching lines...) Expand 10 before | Expand all | Expand 10 after
1535 // Check (number_of_captures + 1) * 2 <= offsets vector size 1535 // Check (number_of_captures + 1) * 2 <= offsets vector size
1536 // Or number_of_captures * 2 <= offsets vector size - 2 1536 // Or number_of_captures * 2 <= offsets vector size - 2
1537 // Multiplying by 2 comes for free since edx is smi-tagged. 1537 // Multiplying by 2 comes for free since edx is smi-tagged.
1538 STATIC_ASSERT(kSmiTag == 0); 1538 STATIC_ASSERT(kSmiTag == 0);
1539 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1); 1539 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1);
1540 STATIC_ASSERT(Isolate::kJSRegexpStaticOffsetsVectorSize >= 2); 1540 STATIC_ASSERT(Isolate::kJSRegexpStaticOffsetsVectorSize >= 2);
1541 __ cmp(edx, Isolate::kJSRegexpStaticOffsetsVectorSize - 2); 1541 __ cmp(edx, Isolate::kJSRegexpStaticOffsetsVectorSize - 2);
1542 __ j(above, &runtime); 1542 __ j(above, &runtime);
1543 1543
1544 // Reset offset for possibly sliced string. 1544 // Reset offset for possibly sliced string.
1545 __ Set(edi, Immediate(0)); 1545 __ Move(edi, Immediate(0));
1546 __ mov(eax, Operand(esp, kSubjectOffset)); 1546 __ mov(eax, Operand(esp, kSubjectOffset));
1547 __ JumpIfSmi(eax, &runtime); 1547 __ JumpIfSmi(eax, &runtime);
1548 __ mov(edx, eax); // Make a copy of the original subject string. 1548 __ mov(edx, eax); // Make a copy of the original subject string.
1549 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 1549 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
1550 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); 1550 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
1551 1551
1552 // eax: subject string 1552 // eax: subject string
1553 // edx: subject string 1553 // edx: subject string
1554 // ebx: subject string instance type 1554 // ebx: subject string instance type
1555 // ecx: RegExp data (FixedArray) 1555 // ecx: RegExp data (FixedArray)
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1629 // (6) One byte sequential. Load regexp code for one byte. 1629 // (6) One byte sequential. Load regexp code for one byte.
1630 __ bind(&seq_one_byte_string); 1630 __ bind(&seq_one_byte_string);
1631 // Load previous index and check range before edx is overwritten. We have 1631 // Load previous index and check range before edx is overwritten. We have
1632 // to use edx instead of eax here because it might have been only made to 1632 // to use edx instead of eax here because it might have been only made to
1633 // look like a sequential string when it actually is an external string. 1633 // look like a sequential string when it actually is an external string.
1634 __ mov(ebx, Operand(esp, kPreviousIndexOffset)); 1634 __ mov(ebx, Operand(esp, kPreviousIndexOffset));
1635 __ JumpIfNotSmi(ebx, &runtime); 1635 __ JumpIfNotSmi(ebx, &runtime);
1636 __ cmp(ebx, FieldOperand(edx, String::kLengthOffset)); 1636 __ cmp(ebx, FieldOperand(edx, String::kLengthOffset));
1637 __ j(above_equal, &runtime); 1637 __ j(above_equal, &runtime);
1638 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataAsciiCodeOffset)); 1638 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataAsciiCodeOffset));
1639 __ Set(ecx, Immediate(1)); // Type is one byte. 1639 __ Move(ecx, Immediate(1)); // Type is one byte.
1640 1640
1641 // (E) Carry on. String handling is done. 1641 // (E) Carry on. String handling is done.
1642 __ bind(&check_code); 1642 __ bind(&check_code);
1643 // edx: irregexp code 1643 // edx: irregexp code
1644 // Check that the irregexp code has been generated for the actual string 1644 // Check that the irregexp code has been generated for the actual string
1645 // encoding. If it has, the field contains a code object otherwise it contains 1645 // encoding. If it has, the field contains a code object otherwise it contains
1646 // a smi (code flushing support). 1646 // a smi (code flushing support).
1647 __ JumpIfSmi(edx, &runtime); 1647 __ JumpIfSmi(edx, &runtime);
1648 1648
1649 // eax: subject string 1649 // eax: subject string
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
1897 // (9) Two byte sequential. Load regexp code for one byte. Go to (E). 1897 // (9) Two byte sequential. Load regexp code for one byte. Go to (E).
1898 __ bind(&seq_two_byte_string); 1898 __ bind(&seq_two_byte_string);
1899 // Load previous index and check range before edx is overwritten. We have 1899 // Load previous index and check range before edx is overwritten. We have
1900 // to use edx instead of eax here because it might have been only made to 1900 // to use edx instead of eax here because it might have been only made to
1901 // look like a sequential string when it actually is an external string. 1901 // look like a sequential string when it actually is an external string.
1902 __ mov(ebx, Operand(esp, kPreviousIndexOffset)); 1902 __ mov(ebx, Operand(esp, kPreviousIndexOffset));
1903 __ JumpIfNotSmi(ebx, &runtime); 1903 __ JumpIfNotSmi(ebx, &runtime);
1904 __ cmp(ebx, FieldOperand(edx, String::kLengthOffset)); 1904 __ cmp(ebx, FieldOperand(edx, String::kLengthOffset));
1905 __ j(above_equal, &runtime); 1905 __ j(above_equal, &runtime);
1906 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataUC16CodeOffset)); 1906 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataUC16CodeOffset));
1907 __ Set(ecx, Immediate(0)); // Type is two byte. 1907 __ Move(ecx, Immediate(0)); // Type is two byte.
1908 __ jmp(&check_code); // Go to (E). 1908 __ jmp(&check_code); // Go to (E).
1909 1909
1910 // (10) Not a string or a short external string? If yes, bail out to runtime. 1910 // (10) Not a string or a short external string? If yes, bail out to runtime.
1911 __ bind(&not_long_external); 1911 __ bind(&not_long_external);
1912 // Catch non-string subject or short external string. 1912 // Catch non-string subject or short external string.
1913 STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0); 1913 STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0);
1914 __ test(ebx, Immediate(kIsNotStringMask | kShortExternalStringTag)); 1914 __ test(ebx, Immediate(kIsNotStringMask | kShortExternalStringTag));
1915 __ j(not_zero, &runtime); 1915 __ j(not_zero, &runtime);
1916 1916
1917 // (11) Sliced string. Replace subject with parent. Go to (5a). 1917 // (11) Sliced string. Replace subject with parent. Go to (5a).
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1994 Label not_identical; 1994 Label not_identical;
1995 __ cmp(eax, edx); 1995 __ cmp(eax, edx);
1996 __ j(not_equal, &not_identical); 1996 __ j(not_equal, &not_identical);
1997 1997
1998 if (cc != equal) { 1998 if (cc != equal) {
1999 // Check for undefined. undefined OP undefined is false even though 1999 // Check for undefined. undefined OP undefined is false even though
2000 // undefined == undefined. 2000 // undefined == undefined.
2001 Label check_for_nan; 2001 Label check_for_nan;
2002 __ cmp(edx, masm->isolate()->factory()->undefined_value()); 2002 __ cmp(edx, masm->isolate()->factory()->undefined_value());
2003 __ j(not_equal, &check_for_nan, Label::kNear); 2003 __ j(not_equal, &check_for_nan, Label::kNear);
2004 __ Set(eax, Immediate(Smi::FromInt(NegativeComparisonResult(cc)))); 2004 __ Move(eax, Immediate(Smi::FromInt(NegativeComparisonResult(cc))));
2005 __ ret(0); 2005 __ ret(0);
2006 __ bind(&check_for_nan); 2006 __ bind(&check_for_nan);
2007 } 2007 }
2008 2008
2009 // Test for NaN. Compare heap numbers in a general way, 2009 // Test for NaN. Compare heap numbers in a general way,
2010 // to hanlde NaNs correctly. 2010 // to hanlde NaNs correctly.
2011 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), 2011 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
2012 Immediate(masm->isolate()->factory()->heap_number_map())); 2012 Immediate(masm->isolate()->factory()->heap_number_map()));
2013 __ j(equal, &generic_heap_number_comparison, Label::kNear); 2013 __ j(equal, &generic_heap_number_comparison, Label::kNear);
2014 if (cc != equal) { 2014 if (cc != equal) {
2015 // Call runtime on identical JSObjects. Otherwise return equal. 2015 // Call runtime on identical JSObjects. Otherwise return equal.
2016 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); 2016 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
2017 __ j(above_equal, &not_identical); 2017 __ j(above_equal, &not_identical);
2018 } 2018 }
2019 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); 2019 __ Move(eax, Immediate(Smi::FromInt(EQUAL)));
2020 __ ret(0); 2020 __ ret(0);
2021 2021
2022 2022
2023 __ bind(&not_identical); 2023 __ bind(&not_identical);
2024 } 2024 }
2025 2025
2026 // Strict equality can quickly decide whether objects are equal. 2026 // Strict equality can quickly decide whether objects are equal.
2027 // Non-strict object equality is slower, so it is handled later in the stub. 2027 // Non-strict object equality is slower, so it is handled later in the stub.
2028 if (cc == equal && strict()) { 2028 if (cc == equal && strict()) {
2029 Label slow; // Fallthrough label. 2029 Label slow; // Fallthrough label.
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
2123 __ FCmp(); 2123 __ FCmp();
2124 2124
2125 // Don't base result on EFLAGS when a NaN is involved. 2125 // Don't base result on EFLAGS when a NaN is involved.
2126 __ j(parity_even, &unordered, Label::kNear); 2126 __ j(parity_even, &unordered, Label::kNear);
2127 2127
2128 Label below_label, above_label; 2128 Label below_label, above_label;
2129 // Return a result of -1, 0, or 1, based on EFLAGS. 2129 // Return a result of -1, 0, or 1, based on EFLAGS.
2130 __ j(below, &below_label, Label::kNear); 2130 __ j(below, &below_label, Label::kNear);
2131 __ j(above, &above_label, Label::kNear); 2131 __ j(above, &above_label, Label::kNear);
2132 2132
2133 __ Set(eax, Immediate(0)); 2133 __ Move(eax, Immediate(0));
2134 __ ret(0); 2134 __ ret(0);
2135 2135
2136 __ bind(&below_label); 2136 __ bind(&below_label);
2137 __ mov(eax, Immediate(Smi::FromInt(-1))); 2137 __ mov(eax, Immediate(Smi::FromInt(-1)));
2138 __ ret(0); 2138 __ ret(0);
2139 2139
2140 __ bind(&above_label); 2140 __ bind(&above_label);
2141 __ mov(eax, Immediate(Smi::FromInt(1))); 2141 __ mov(eax, Immediate(Smi::FromInt(1)));
2142 __ ret(0); 2142 __ ret(0);
2143 } 2143 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2215 // they are equal if and only if both are undetectable. 2215 // they are equal if and only if both are undetectable.
2216 // The and of the undetectable flags is 1 if and only if they are equal. 2216 // The and of the undetectable flags is 1 if and only if they are equal.
2217 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 2217 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
2218 1 << Map::kIsUndetectable); 2218 1 << Map::kIsUndetectable);
2219 __ j(zero, &return_unequal, Label::kNear); 2219 __ j(zero, &return_unequal, Label::kNear);
2220 __ test_b(FieldOperand(ebx, Map::kBitFieldOffset), 2220 __ test_b(FieldOperand(ebx, Map::kBitFieldOffset),
2221 1 << Map::kIsUndetectable); 2221 1 << Map::kIsUndetectable);
2222 __ j(zero, &return_unequal, Label::kNear); 2222 __ j(zero, &return_unequal, Label::kNear);
2223 // The objects are both undetectable, so they both compare as the value 2223 // The objects are both undetectable, so they both compare as the value
2224 // undefined, and are equal. 2224 // undefined, and are equal.
2225 __ Set(eax, Immediate(EQUAL)); 2225 __ Move(eax, Immediate(EQUAL));
2226 __ bind(&return_unequal); 2226 __ bind(&return_unequal);
2227 // Return non-equal by returning the non-zero object pointer in eax, 2227 // Return non-equal by returning the non-zero object pointer in eax,
2228 // or return equal if we fell through to here. 2228 // or return equal if we fell through to here.
2229 __ ret(0); // rax, rdx were pushed 2229 __ ret(0); // rax, rdx were pushed
2230 __ bind(&not_both_objects); 2230 __ bind(&not_both_objects);
2231 } 2231 }
2232 2232
2233 // Push arguments below the return address. 2233 // Push arguments below the return address.
2234 __ pop(ecx); 2234 __ pop(ecx);
2235 __ push(edx); 2235 __ push(edx);
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
2431 __ mov(FieldOperand(ebx, edx, times_half_pointer_size, 2431 __ mov(FieldOperand(ebx, edx, times_half_pointer_size,
2432 FixedArray::kHeaderSize), 2432 FixedArray::kHeaderSize),
2433 Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate))); 2433 Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate)));
2434 } 2434 }
2435 // Check for function proxy. 2435 // Check for function proxy.
2436 __ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE); 2436 __ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE);
2437 __ j(not_equal, &non_function); 2437 __ j(not_equal, &non_function);
2438 __ pop(ecx); 2438 __ pop(ecx);
2439 __ push(edi); // put proxy as additional argument under return address 2439 __ push(edi); // put proxy as additional argument under return address
2440 __ push(ecx); 2440 __ push(ecx);
2441 __ Set(eax, Immediate(argc_ + 1)); 2441 __ Move(eax, Immediate(argc_ + 1));
2442 __ Set(ebx, Immediate(0)); 2442 __ Move(ebx, Immediate(0));
2443 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY); 2443 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY);
2444 { 2444 {
2445 Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline(); 2445 Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline();
2446 __ jmp(adaptor, RelocInfo::CODE_TARGET); 2446 __ jmp(adaptor, RelocInfo::CODE_TARGET);
2447 } 2447 }
2448 2448
2449 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead 2449 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
2450 // of the original receiver from the call site). 2450 // of the original receiver from the call site).
2451 __ bind(&non_function); 2451 __ bind(&non_function);
2452 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edi); 2452 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edi);
2453 __ Set(eax, Immediate(argc_)); 2453 __ Move(eax, Immediate(argc_));
2454 __ Set(ebx, Immediate(0)); 2454 __ Move(ebx, Immediate(0));
2455 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); 2455 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
2456 Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline(); 2456 Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline();
2457 __ jmp(adaptor, RelocInfo::CODE_TARGET); 2457 __ jmp(adaptor, RelocInfo::CODE_TARGET);
2458 } 2458 }
2459 2459
2460 if (CallAsMethod()) { 2460 if (CallAsMethod()) {
2461 __ bind(&wrap); 2461 __ bind(&wrap);
2462 // Wrap the receiver and patch it back onto the stack. 2462 // Wrap the receiver and patch it back onto the stack.
2463 { FrameScope frame_scope(masm, StackFrame::INTERNAL); 2463 { FrameScope frame_scope(masm, StackFrame::INTERNAL);
2464 __ push(edi); 2464 __ push(edi);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2526 __ bind(&slow); 2526 __ bind(&slow);
2527 __ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE); 2527 __ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE);
2528 __ j(not_equal, &non_function_call); 2528 __ j(not_equal, &non_function_call);
2529 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR); 2529 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
2530 __ jmp(&do_call); 2530 __ jmp(&do_call);
2531 2531
2532 __ bind(&non_function_call); 2532 __ bind(&non_function_call);
2533 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); 2533 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
2534 __ bind(&do_call); 2534 __ bind(&do_call);
2535 // Set expected number of arguments to zero (not changing eax). 2535 // Set expected number of arguments to zero (not changing eax).
2536 __ Set(ebx, Immediate(0)); 2536 __ Move(ebx, Immediate(0));
2537 Handle<Code> arguments_adaptor = 2537 Handle<Code> arguments_adaptor =
2538 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); 2538 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
2539 __ jmp(arguments_adaptor, RelocInfo::CODE_TARGET); 2539 __ jmp(arguments_adaptor, RelocInfo::CODE_TARGET);
2540 } 2540 }
2541 2541
2542 2542
2543 bool CEntryStub::NeedsImmovableCode() { 2543 bool CEntryStub::NeedsImmovableCode() {
2544 return false; 2544 return false;
2545 } 2545 }
2546 2546
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
3017 // Get return address and delta to inlined map check. 3017 // Get return address and delta to inlined map check.
3018 __ mov(eax, factory->true_value()); 3018 __ mov(eax, factory->true_value());
3019 __ mov(scratch, Operand(esp, 0 * kPointerSize)); 3019 __ mov(scratch, Operand(esp, 0 * kPointerSize));
3020 __ sub(scratch, Operand(esp, 1 * kPointerSize)); 3020 __ sub(scratch, Operand(esp, 1 * kPointerSize));
3021 if (FLAG_debug_code) { 3021 if (FLAG_debug_code) {
3022 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte); 3022 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte);
3023 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheMov); 3023 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheMov);
3024 } 3024 }
3025 __ mov(Operand(scratch, kDeltaToMovImmediate), eax); 3025 __ mov(Operand(scratch, kDeltaToMovImmediate), eax);
3026 if (!ReturnTrueFalseObject()) { 3026 if (!ReturnTrueFalseObject()) {
3027 __ Set(eax, Immediate(0)); 3027 __ Move(eax, Immediate(0));
3028 } 3028 }
3029 } 3029 }
3030 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); 3030 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize);
3031 3031
3032 __ bind(&is_not_instance); 3032 __ bind(&is_not_instance);
3033 if (!HasCallSiteInlineCheck()) { 3033 if (!HasCallSiteInlineCheck()) {
3034 __ mov(eax, Immediate(Smi::FromInt(1))); 3034 __ mov(eax, Immediate(Smi::FromInt(1)));
3035 __ StoreRoot(eax, scratch, Heap::kInstanceofCacheAnswerRootIndex); 3035 __ StoreRoot(eax, scratch, Heap::kInstanceofCacheAnswerRootIndex);
3036 } else { 3036 } else {
3037 // Get return address and delta to inlined map check. 3037 // Get return address and delta to inlined map check.
3038 __ mov(eax, factory->false_value()); 3038 __ mov(eax, factory->false_value());
3039 __ mov(scratch, Operand(esp, 0 * kPointerSize)); 3039 __ mov(scratch, Operand(esp, 0 * kPointerSize));
3040 __ sub(scratch, Operand(esp, 1 * kPointerSize)); 3040 __ sub(scratch, Operand(esp, 1 * kPointerSize));
3041 if (FLAG_debug_code) { 3041 if (FLAG_debug_code) {
3042 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte); 3042 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte);
3043 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheMov); 3043 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheMov);
3044 } 3044 }
3045 __ mov(Operand(scratch, kDeltaToMovImmediate), eax); 3045 __ mov(Operand(scratch, kDeltaToMovImmediate), eax);
3046 if (!ReturnTrueFalseObject()) { 3046 if (!ReturnTrueFalseObject()) {
3047 __ Set(eax, Immediate(Smi::FromInt(1))); 3047 __ Move(eax, Immediate(Smi::FromInt(1)));
3048 } 3048 }
3049 } 3049 }
3050 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); 3050 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize);
3051 3051
3052 Label object_not_null, object_not_null_or_smi; 3052 Label object_not_null, object_not_null_or_smi;
3053 __ bind(&not_js_object); 3053 __ bind(&not_js_object);
3054 // Before null, smi and string value checks, check that the rhs is a function 3054 // Before null, smi and string value checks, check that the rhs is a function
3055 // as for a non-function rhs an exception needs to be thrown. 3055 // as for a non-function rhs an exception needs to be thrown.
3056 __ JumpIfSmi(function, &slow, Label::kNear); 3056 __ JumpIfSmi(function, &slow, Label::kNear);
3057 __ CmpObjectType(function, JS_FUNCTION_TYPE, scratch); 3057 __ CmpObjectType(function, JS_FUNCTION_TYPE, scratch);
3058 __ j(not_equal, &slow, Label::kNear); 3058 __ j(not_equal, &slow, Label::kNear);
3059 3059
3060 // Null is not instance of anything. 3060 // Null is not instance of anything.
3061 __ cmp(object, factory->null_value()); 3061 __ cmp(object, factory->null_value());
3062 __ j(not_equal, &object_not_null, Label::kNear); 3062 __ j(not_equal, &object_not_null, Label::kNear);
3063 __ Set(eax, Immediate(Smi::FromInt(1))); 3063 __ Move(eax, Immediate(Smi::FromInt(1)));
3064 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); 3064 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize);
3065 3065
3066 __ bind(&object_not_null); 3066 __ bind(&object_not_null);
3067 // Smi values is not instance of anything. 3067 // Smi values is not instance of anything.
3068 __ JumpIfNotSmi(object, &object_not_null_or_smi, Label::kNear); 3068 __ JumpIfNotSmi(object, &object_not_null_or_smi, Label::kNear);
3069 __ Set(eax, Immediate(Smi::FromInt(1))); 3069 __ Move(eax, Immediate(Smi::FromInt(1)));
3070 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); 3070 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize);
3071 3071
3072 __ bind(&object_not_null_or_smi); 3072 __ bind(&object_not_null_or_smi);
3073 // String values is not instance of anything. 3073 // String values is not instance of anything.
3074 Condition is_string = masm->IsObjectStringType(object, scratch, scratch); 3074 Condition is_string = masm->IsObjectStringType(object, scratch, scratch);
3075 __ j(NegateCondition(is_string), &slow, Label::kNear); 3075 __ j(NegateCondition(is_string), &slow, Label::kNear);
3076 __ Set(eax, Immediate(Smi::FromInt(1))); 3076 __ Move(eax, Immediate(Smi::FromInt(1)));
3077 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); 3077 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize);
3078 3078
3079 // Slow-case: Go through the JavaScript implementation. 3079 // Slow-case: Go through the JavaScript implementation.
3080 __ bind(&slow); 3080 __ bind(&slow);
3081 if (!ReturnTrueFalseObject()) { 3081 if (!ReturnTrueFalseObject()) {
3082 // Tail call the builtin which returns 0 or 1. 3082 // Tail call the builtin which returns 0 or 1.
3083 if (HasArgsInRegisters()) { 3083 if (HasArgsInRegisters()) {
3084 // Push arguments below return address. 3084 // Push arguments below return address.
3085 __ pop(scratch); 3085 __ pop(scratch);
3086 __ push(object); 3086 __ push(object);
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
3214 // Fast case of Heap::LookupSingleCharacterStringFromCode. 3214 // Fast case of Heap::LookupSingleCharacterStringFromCode.
3215 STATIC_ASSERT(kSmiTag == 0); 3215 STATIC_ASSERT(kSmiTag == 0);
3216 STATIC_ASSERT(kSmiShiftSize == 0); 3216 STATIC_ASSERT(kSmiShiftSize == 0);
3217 ASSERT(IsPowerOf2(String::kMaxOneByteCharCode + 1)); 3217 ASSERT(IsPowerOf2(String::kMaxOneByteCharCode + 1));
3218 __ test(code_, 3218 __ test(code_,
3219 Immediate(kSmiTagMask | 3219 Immediate(kSmiTagMask |
3220 ((~String::kMaxOneByteCharCode) << kSmiTagSize))); 3220 ((~String::kMaxOneByteCharCode) << kSmiTagSize)));
3221 __ j(not_zero, &slow_case_); 3221 __ j(not_zero, &slow_case_);
3222 3222
3223 Factory* factory = masm->isolate()->factory(); 3223 Factory* factory = masm->isolate()->factory();
3224 __ Set(result_, Immediate(factory->single_character_string_cache())); 3224 __ Move(result_, Immediate(factory->single_character_string_cache()));
3225 STATIC_ASSERT(kSmiTag == 0); 3225 STATIC_ASSERT(kSmiTag == 0);
3226 STATIC_ASSERT(kSmiTagSize == 1); 3226 STATIC_ASSERT(kSmiTagSize == 1);
3227 STATIC_ASSERT(kSmiShiftSize == 0); 3227 STATIC_ASSERT(kSmiShiftSize == 0);
3228 // At this point code register contains smi tagged ASCII char code. 3228 // At this point code register contains smi tagged ASCII char code.
3229 __ mov(result_, FieldOperand(result_, 3229 __ mov(result_, FieldOperand(result_,
3230 code_, times_half_pointer_size, 3230 code_, times_half_pointer_size,
3231 FixedArray::kHeaderSize)); 3231 FixedArray::kHeaderSize));
3232 __ cmp(result_, factory->undefined_value()); 3232 __ cmp(result_, factory->undefined_value());
3233 __ j(equal, &slow_case_); 3233 __ j(equal, &slow_case_);
3234 __ bind(&exit_); 3234 __ bind(&exit_);
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
3613 Register scratch1, 3613 Register scratch1,
3614 Register scratch2) { 3614 Register scratch2) {
3615 Register length = scratch1; 3615 Register length = scratch1;
3616 3616
3617 // Compare lengths. 3617 // Compare lengths.
3618 Label strings_not_equal, check_zero_length; 3618 Label strings_not_equal, check_zero_length;
3619 __ mov(length, FieldOperand(left, String::kLengthOffset)); 3619 __ mov(length, FieldOperand(left, String::kLengthOffset));
3620 __ cmp(length, FieldOperand(right, String::kLengthOffset)); 3620 __ cmp(length, FieldOperand(right, String::kLengthOffset));
3621 __ j(equal, &check_zero_length, Label::kNear); 3621 __ j(equal, &check_zero_length, Label::kNear);
3622 __ bind(&strings_not_equal); 3622 __ bind(&strings_not_equal);
3623 __ Set(eax, Immediate(Smi::FromInt(NOT_EQUAL))); 3623 __ Move(eax, Immediate(Smi::FromInt(NOT_EQUAL)));
3624 __ ret(0); 3624 __ ret(0);
3625 3625
3626 // Check if the length is zero. 3626 // Check if the length is zero.
3627 Label compare_chars; 3627 Label compare_chars;
3628 __ bind(&check_zero_length); 3628 __ bind(&check_zero_length);
3629 STATIC_ASSERT(kSmiTag == 0); 3629 STATIC_ASSERT(kSmiTag == 0);
3630 __ test(length, length); 3630 __ test(length, length);
3631 __ j(not_zero, &compare_chars, Label::kNear); 3631 __ j(not_zero, &compare_chars, Label::kNear);
3632 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); 3632 __ Move(eax, Immediate(Smi::FromInt(EQUAL)));
3633 __ ret(0); 3633 __ ret(0);
3634 3634
3635 // Compare characters. 3635 // Compare characters.
3636 __ bind(&compare_chars); 3636 __ bind(&compare_chars);
3637 GenerateAsciiCharsCompareLoop(masm, left, right, length, scratch2, 3637 GenerateAsciiCharsCompareLoop(masm, left, right, length, scratch2,
3638 &strings_not_equal, Label::kNear); 3638 &strings_not_equal, Label::kNear);
3639 3639
3640 // Characters are equal. 3640 // Characters are equal.
3641 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); 3641 __ Move(eax, Immediate(Smi::FromInt(EQUAL)));
3642 __ ret(0); 3642 __ ret(0);
3643 } 3643 }
3644 3644
3645 3645
3646 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm, 3646 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
3647 Register left, 3647 Register left,
3648 Register right, 3648 Register right,
3649 Register scratch1, 3649 Register scratch1,
3650 Register scratch2, 3650 Register scratch2,
3651 Register scratch3) { 3651 Register scratch3) {
(...skipping 27 matching lines...) Expand all
3679 3679
3680 // Compare lengths - strings up to min-length are equal. 3680 // Compare lengths - strings up to min-length are equal.
3681 __ bind(&compare_lengths); 3681 __ bind(&compare_lengths);
3682 __ test(length_delta, length_delta); 3682 __ test(length_delta, length_delta);
3683 Label length_not_equal; 3683 Label length_not_equal;
3684 __ j(not_zero, &length_not_equal, Label::kNear); 3684 __ j(not_zero, &length_not_equal, Label::kNear);
3685 3685
3686 // Result is EQUAL. 3686 // Result is EQUAL.
3687 STATIC_ASSERT(EQUAL == 0); 3687 STATIC_ASSERT(EQUAL == 0);
3688 STATIC_ASSERT(kSmiTag == 0); 3688 STATIC_ASSERT(kSmiTag == 0);
3689 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); 3689 __ Move(eax, Immediate(Smi::FromInt(EQUAL)));
3690 __ ret(0); 3690 __ ret(0);
3691 3691
3692 Label result_greater; 3692 Label result_greater;
3693 Label result_less; 3693 Label result_less;
3694 __ bind(&length_not_equal); 3694 __ bind(&length_not_equal);
3695 __ j(greater, &result_greater, Label::kNear); 3695 __ j(greater, &result_greater, Label::kNear);
3696 __ jmp(&result_less, Label::kNear); 3696 __ jmp(&result_less, Label::kNear);
3697 __ bind(&result_not_equal); 3697 __ bind(&result_not_equal);
3698 __ j(above, &result_greater, Label::kNear); 3698 __ j(above, &result_greater, Label::kNear);
3699 __ bind(&result_less); 3699 __ bind(&result_less);
3700 3700
3701 // Result is LESS. 3701 // Result is LESS.
3702 __ Set(eax, Immediate(Smi::FromInt(LESS))); 3702 __ Move(eax, Immediate(Smi::FromInt(LESS)));
3703 __ ret(0); 3703 __ ret(0);
3704 3704
3705 // Result is GREATER. 3705 // Result is GREATER.
3706 __ bind(&result_greater); 3706 __ bind(&result_greater);
3707 __ Set(eax, Immediate(Smi::FromInt(GREATER))); 3707 __ Move(eax, Immediate(Smi::FromInt(GREATER)));
3708 __ ret(0); 3708 __ ret(0);
3709 } 3709 }
3710 3710
3711 3711
3712 void StringCompareStub::GenerateAsciiCharsCompareLoop( 3712 void StringCompareStub::GenerateAsciiCharsCompareLoop(
3713 MacroAssembler* masm, 3713 MacroAssembler* masm,
3714 Register left, 3714 Register left,
3715 Register right, 3715 Register right,
3716 Register length, 3716 Register length,
3717 Register scratch, 3717 Register scratch,
(...skipping 30 matching lines...) Expand all
3748 // esp[8]: left string 3748 // esp[8]: left string
3749 3749
3750 __ mov(edx, Operand(esp, 2 * kPointerSize)); // left 3750 __ mov(edx, Operand(esp, 2 * kPointerSize)); // left
3751 __ mov(eax, Operand(esp, 1 * kPointerSize)); // right 3751 __ mov(eax, Operand(esp, 1 * kPointerSize)); // right
3752 3752
3753 Label not_same; 3753 Label not_same;
3754 __ cmp(edx, eax); 3754 __ cmp(edx, eax);
3755 __ j(not_equal, &not_same, Label::kNear); 3755 __ j(not_equal, &not_same, Label::kNear);
3756 STATIC_ASSERT(EQUAL == 0); 3756 STATIC_ASSERT(EQUAL == 0);
3757 STATIC_ASSERT(kSmiTag == 0); 3757 STATIC_ASSERT(kSmiTag == 0);
3758 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); 3758 __ Move(eax, Immediate(Smi::FromInt(EQUAL)));
3759 __ IncrementCounter(masm->isolate()->counters()->string_compare_native(), 1); 3759 __ IncrementCounter(masm->isolate()->counters()->string_compare_native(), 1);
3760 __ ret(2 * kPointerSize); 3760 __ ret(2 * kPointerSize);
3761 3761
3762 __ bind(&not_same); 3762 __ bind(&not_same);
3763 3763
3764 // Check that both objects are sequential ASCII strings. 3764 // Check that both objects are sequential ASCII strings.
3765 __ JumpIfNotBothSequentialAsciiStrings(edx, eax, ecx, ebx, &runtime); 3765 __ JumpIfNotBothSequentialAsciiStrings(edx, eax, ecx, ebx, &runtime);
3766 3766
3767 // Compare flat ASCII strings. 3767 // Compare flat ASCII strings.
3768 // Drop arguments from the stack. 3768 // Drop arguments from the stack.
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
4154 4154
4155 // Internalized strings are compared by identity. 4155 // Internalized strings are compared by identity.
4156 Label done; 4156 Label done;
4157 __ cmp(left, right); 4157 __ cmp(left, right);
4158 // Make sure eax is non-zero. At this point input operands are 4158 // Make sure eax is non-zero. At this point input operands are
4159 // guaranteed to be non-zero. 4159 // guaranteed to be non-zero.
4160 ASSERT(right.is(eax)); 4160 ASSERT(right.is(eax));
4161 __ j(not_equal, &done, Label::kNear); 4161 __ j(not_equal, &done, Label::kNear);
4162 STATIC_ASSERT(EQUAL == 0); 4162 STATIC_ASSERT(EQUAL == 0);
4163 STATIC_ASSERT(kSmiTag == 0); 4163 STATIC_ASSERT(kSmiTag == 0);
4164 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); 4164 __ Move(eax, Immediate(Smi::FromInt(EQUAL)));
4165 __ bind(&done); 4165 __ bind(&done);
4166 __ ret(0); 4166 __ ret(0);
4167 4167
4168 __ bind(&miss); 4168 __ bind(&miss);
4169 GenerateMiss(masm); 4169 GenerateMiss(masm);
4170 } 4170 }
4171 4171
4172 4172
4173 void ICCompareStub::GenerateUniqueNames(MacroAssembler* masm) { 4173 void ICCompareStub::GenerateUniqueNames(MacroAssembler* masm) {
4174 ASSERT(state_ == CompareIC::UNIQUE_NAME); 4174 ASSERT(state_ == CompareIC::UNIQUE_NAME);
(...skipping 24 matching lines...) Expand all
4199 4199
4200 // Unique names are compared by identity. 4200 // Unique names are compared by identity.
4201 Label done; 4201 Label done;
4202 __ cmp(left, right); 4202 __ cmp(left, right);
4203 // Make sure eax is non-zero. At this point input operands are 4203 // Make sure eax is non-zero. At this point input operands are
4204 // guaranteed to be non-zero. 4204 // guaranteed to be non-zero.
4205 ASSERT(right.is(eax)); 4205 ASSERT(right.is(eax));
4206 __ j(not_equal, &done, Label::kNear); 4206 __ j(not_equal, &done, Label::kNear);
4207 STATIC_ASSERT(EQUAL == 0); 4207 STATIC_ASSERT(EQUAL == 0);
4208 STATIC_ASSERT(kSmiTag == 0); 4208 STATIC_ASSERT(kSmiTag == 0);
4209 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); 4209 __ Move(eax, Immediate(Smi::FromInt(EQUAL)));
4210 __ bind(&done); 4210 __ bind(&done);
4211 __ ret(0); 4211 __ ret(0);
4212 4212
4213 __ bind(&miss); 4213 __ bind(&miss);
4214 GenerateMiss(masm); 4214 GenerateMiss(masm);
4215 } 4215 }
4216 4216
4217 4217
4218 void ICCompareStub::GenerateStrings(MacroAssembler* masm) { 4218 void ICCompareStub::GenerateStrings(MacroAssembler* masm) {
4219 ASSERT(state_ == CompareIC::STRING); 4219 ASSERT(state_ == CompareIC::STRING);
(...skipping 25 matching lines...) Expand all
4245 __ or_(tmp3, tmp2); 4245 __ or_(tmp3, tmp2);
4246 __ test(tmp3, Immediate(kIsNotStringMask)); 4246 __ test(tmp3, Immediate(kIsNotStringMask));
4247 __ j(not_zero, &miss); 4247 __ j(not_zero, &miss);
4248 4248
4249 // Fast check for identical strings. 4249 // Fast check for identical strings.
4250 Label not_same; 4250 Label not_same;
4251 __ cmp(left, right); 4251 __ cmp(left, right);
4252 __ j(not_equal, &not_same, Label::kNear); 4252 __ j(not_equal, &not_same, Label::kNear);
4253 STATIC_ASSERT(EQUAL == 0); 4253 STATIC_ASSERT(EQUAL == 0);
4254 STATIC_ASSERT(kSmiTag == 0); 4254 STATIC_ASSERT(kSmiTag == 0);
4255 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); 4255 __ Move(eax, Immediate(Smi::FromInt(EQUAL)));
4256 __ ret(0); 4256 __ ret(0);
4257 4257
4258 // Handle not identical strings. 4258 // Handle not identical strings.
4259 __ bind(&not_same); 4259 __ bind(&not_same);
4260 4260
4261 // Check that both strings are internalized. If they are, we're done 4261 // Check that both strings are internalized. If they are, we're done
4262 // because we already know they are not identical. But in the case of 4262 // because we already know they are not identical. But in the case of
4263 // non-equality compare, we still need to determine the order. We 4263 // non-equality compare, we still need to determine the order. We
4264 // also know they are both strings. 4264 // also know they are both strings.
4265 if (equality) { 4265 if (equality) {
(...skipping 1058 matching lines...) Expand 10 before | Expand all | Expand 10 after
5324 const int kApiStackSpace = 4; 5324 const int kApiStackSpace = 4;
5325 5325
5326 __ PrepareCallApiFunction(kApiArgc + kApiStackSpace); 5326 __ PrepareCallApiFunction(kApiArgc + kApiStackSpace);
5327 5327
5328 // FunctionCallbackInfo::implicit_args_. 5328 // FunctionCallbackInfo::implicit_args_.
5329 __ mov(ApiParameterOperand(2), scratch); 5329 __ mov(ApiParameterOperand(2), scratch);
5330 __ add(scratch, Immediate((argc + FCA::kArgsLength - 1) * kPointerSize)); 5330 __ add(scratch, Immediate((argc + FCA::kArgsLength - 1) * kPointerSize));
5331 // FunctionCallbackInfo::values_. 5331 // FunctionCallbackInfo::values_.
5332 __ mov(ApiParameterOperand(3), scratch); 5332 __ mov(ApiParameterOperand(3), scratch);
5333 // FunctionCallbackInfo::length_. 5333 // FunctionCallbackInfo::length_.
5334 __ Set(ApiParameterOperand(4), Immediate(argc)); 5334 __ Move(ApiParameterOperand(4), Immediate(argc));
5335 // FunctionCallbackInfo::is_construct_call_. 5335 // FunctionCallbackInfo::is_construct_call_.
5336 __ Set(ApiParameterOperand(5), Immediate(0)); 5336 __ Move(ApiParameterOperand(5), Immediate(0));
5337 5337
5338 // v8::InvocationCallback's argument. 5338 // v8::InvocationCallback's argument.
5339 __ lea(scratch, ApiParameterOperand(2)); 5339 __ lea(scratch, ApiParameterOperand(2));
5340 __ mov(ApiParameterOperand(0), scratch); 5340 __ mov(ApiParameterOperand(0), scratch);
5341 5341
5342 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback); 5342 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
5343 5343
5344 Operand context_restore_operand(ebp, 5344 Operand context_restore_operand(ebp,
5345 (2 + FCA::kContextSaveIndex) * kPointerSize); 5345 (2 + FCA::kContextSaveIndex) * kPointerSize);
5346 // Stores return the first js argument 5346 // Stores return the first js argument
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
5396 Operand(ebp, 7 * kPointerSize), 5396 Operand(ebp, 7 * kPointerSize),
5397 NULL); 5397 NULL);
5398 } 5398 }
5399 5399
5400 5400
5401 #undef __ 5401 #undef __
5402 5402
5403 } } // namespace v8::internal 5403 } } // namespace v8::internal
5404 5404
5405 #endif // V8_TARGET_ARCH_IA32 5405 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/builtins-ia32.cc ('k') | src/ia32/debug-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698