OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_X87 | 5 #if V8_TARGET_ARCH_X87 |
6 | 6 |
7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
8 #include "src/api-arguments.h" | 8 #include "src/api-arguments.h" |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 Immediate(isolate()->factory()->the_hole_value())); | 292 Immediate(isolate()->factory()->the_hole_value())); |
293 __ j(equal, &miss); | 293 __ j(equal, &miss); |
294 __ TryGetFunctionPrototype(receiver, eax, ebx, &miss); | 294 __ TryGetFunctionPrototype(receiver, eax, ebx, &miss); |
295 __ ret(0); | 295 __ ret(0); |
296 | 296 |
297 __ bind(&miss); | 297 __ bind(&miss); |
298 PropertyAccessCompiler::TailCallBuiltin( | 298 PropertyAccessCompiler::TailCallBuiltin( |
299 masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC)); | 299 masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC)); |
300 } | 300 } |
301 | 301 |
302 | |
303 void LoadIndexedStringStub::Generate(MacroAssembler* masm) { | |
304 // Return address is on the stack. | |
305 Label miss; | |
306 | |
307 Register receiver = LoadDescriptor::ReceiverRegister(); | |
308 Register index = LoadDescriptor::NameRegister(); | |
309 Register scratch = edi; | |
310 DCHECK(!scratch.is(receiver) && !scratch.is(index)); | |
311 Register result = eax; | |
312 DCHECK(!result.is(scratch)); | |
313 DCHECK(!scratch.is(LoadWithVectorDescriptor::VectorRegister()) && | |
314 result.is(LoadDescriptor::SlotRegister())); | |
315 | |
316 // StringCharAtGenerator doesn't use the result register until it's passed | |
317 // the different miss possibilities. If it did, we would have a conflict | |
318 // when FLAG_vector_ics is true. | |
319 | |
320 StringCharAtGenerator char_at_generator(receiver, index, scratch, result, | |
321 &miss, // When not a string. | |
322 &miss, // When not a number. | |
323 &miss, // When index out of range. | |
324 RECEIVER_IS_STRING); | |
325 char_at_generator.GenerateFast(masm); | |
326 __ ret(0); | |
327 | |
328 StubRuntimeCallHelper call_helper; | |
329 char_at_generator.GenerateSlow(masm, PART_OF_IC_HANDLER, call_helper); | |
330 | |
331 __ bind(&miss); | |
332 PropertyAccessCompiler::TailCallBuiltin( | |
333 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); | |
334 } | |
335 | |
336 | |
337 void RegExpExecStub::Generate(MacroAssembler* masm) { | 302 void RegExpExecStub::Generate(MacroAssembler* masm) { |
338 // Just jump directly to runtime if native RegExp is not selected at compile | 303 // Just jump directly to runtime if native RegExp is not selected at compile |
339 // time or if regexp entry in generated code is turned off runtime switch or | 304 // time or if regexp entry in generated code is turned off runtime switch or |
340 // at compilation. | 305 // at compilation. |
341 #ifdef V8_INTERPRETED_REGEXP | 306 #ifdef V8_INTERPRETED_REGEXP |
342 __ TailCallRuntime(Runtime::kRegExpExec); | 307 __ TailCallRuntime(Runtime::kRegExpExec); |
343 #else // V8_INTERPRETED_REGEXP | 308 #else // V8_INTERPRETED_REGEXP |
344 | 309 |
345 // Stack frame on entry. | 310 // Stack frame on entry. |
346 // esp[0]: return address | 311 // esp[0]: return address |
(...skipping 1475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1822 __ CallRuntime(Runtime::kStringCharCodeAtRT); | 1787 __ CallRuntime(Runtime::kStringCharCodeAtRT); |
1823 if (!result_.is(eax)) { | 1788 if (!result_.is(eax)) { |
1824 __ mov(result_, eax); | 1789 __ mov(result_, eax); |
1825 } | 1790 } |
1826 call_helper.AfterCall(masm); | 1791 call_helper.AfterCall(masm); |
1827 __ jmp(&exit_); | 1792 __ jmp(&exit_); |
1828 | 1793 |
1829 __ Abort(kUnexpectedFallthroughFromCharCodeAtSlowCase); | 1794 __ Abort(kUnexpectedFallthroughFromCharCodeAtSlowCase); |
1830 } | 1795 } |
1831 | 1796 |
1832 | |
1833 // ------------------------------------------------------------------------- | |
1834 // StringCharFromCodeGenerator | |
1835 | |
1836 void StringCharFromCodeGenerator::GenerateFast(MacroAssembler* masm) { | |
1837 // Fast case of Heap::LookupSingleCharacterStringFromCode. | |
1838 STATIC_ASSERT(kSmiTag == 0); | |
1839 STATIC_ASSERT(kSmiShiftSize == 0); | |
1840 DCHECK(base::bits::IsPowerOfTwo32(String::kMaxOneByteCharCodeU + 1)); | |
1841 __ test(code_, Immediate(kSmiTagMask | | |
1842 ((~String::kMaxOneByteCharCodeU) << kSmiTagSize))); | |
1843 __ j(not_zero, &slow_case_); | |
1844 | |
1845 Factory* factory = masm->isolate()->factory(); | |
1846 __ Move(result_, Immediate(factory->single_character_string_cache())); | |
1847 STATIC_ASSERT(kSmiTag == 0); | |
1848 STATIC_ASSERT(kSmiTagSize == 1); | |
1849 STATIC_ASSERT(kSmiShiftSize == 0); | |
1850 // At this point code register contains smi tagged one byte char code. | |
1851 __ mov(result_, FieldOperand(result_, | |
1852 code_, times_half_pointer_size, | |
1853 FixedArray::kHeaderSize)); | |
1854 __ cmp(result_, factory->undefined_value()); | |
1855 __ j(equal, &slow_case_); | |
1856 __ bind(&exit_); | |
1857 } | |
1858 | |
1859 | |
1860 void StringCharFromCodeGenerator::GenerateSlow( | |
1861 MacroAssembler* masm, | |
1862 const RuntimeCallHelper& call_helper) { | |
1863 __ Abort(kUnexpectedFallthroughToCharFromCodeSlowCase); | |
1864 | |
1865 __ bind(&slow_case_); | |
1866 call_helper.BeforeCall(masm); | |
1867 __ push(code_); | |
1868 __ CallRuntime(Runtime::kStringCharFromCode); | |
1869 if (!result_.is(eax)) { | |
1870 __ mov(result_, eax); | |
1871 } | |
1872 call_helper.AfterCall(masm); | |
1873 __ jmp(&exit_); | |
1874 | |
1875 __ Abort(kUnexpectedFallthroughFromCharFromCodeSlowCase); | |
1876 } | |
1877 | |
1878 void StringHelper::GenerateFlatOneByteStringEquals(MacroAssembler* masm, | 1797 void StringHelper::GenerateFlatOneByteStringEquals(MacroAssembler* masm, |
1879 Register left, | 1798 Register left, |
1880 Register right, | 1799 Register right, |
1881 Register scratch1, | 1800 Register scratch1, |
1882 Register scratch2) { | 1801 Register scratch2) { |
1883 Register length = scratch1; | 1802 Register length = scratch1; |
1884 | 1803 |
1885 // Compare lengths. | 1804 // Compare lengths. |
1886 Label strings_not_equal, check_zero_length; | 1805 Label strings_not_equal, check_zero_length; |
1887 __ mov(length, FieldOperand(left, String::kLengthOffset)); | 1806 __ mov(length, FieldOperand(left, String::kLengthOffset)); |
(...skipping 2110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3998 kStackUnwindSpace, nullptr, return_value_operand, | 3917 kStackUnwindSpace, nullptr, return_value_operand, |
3999 NULL); | 3918 NULL); |
4000 } | 3919 } |
4001 | 3920 |
4002 #undef __ | 3921 #undef __ |
4003 | 3922 |
4004 } // namespace internal | 3923 } // namespace internal |
4005 } // namespace v8 | 3924 } // namespace v8 |
4006 | 3925 |
4007 #endif // V8_TARGET_ARCH_X87 | 3926 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |