| 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 |