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

Side by Side Diff: src/arm/full-codegen-arm.cc

Issue 2087009: Custom call IC-s for String.prototype.{charAt,charCodeAt}. (Closed)
Patch Set: ARM port. Created 10 years, 7 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
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 1809 matching lines...) Expand 10 before | Expand all | Expand 10 after
1820 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 1820 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
1821 1821
1822 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall)); 1822 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall));
1823 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); 1823 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
1824 1824
1825 // Replace function on TOS with result in r0, or pop it. 1825 // Replace function on TOS with result in r0, or pop it.
1826 DropAndApply(1, context_, r0); 1826 DropAndApply(1, context_, r0);
1827 } 1827 }
1828 1828
1829 1829
1830 void FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* expr) {
1831 Handle<String> name = expr->name();
1832 if (strcmp("_IsSmi", *name->ToCString()) == 0) {
1833 EmitIsSmi(expr->arguments());
1834 } else if (strcmp("_IsNonNegativeSmi", *name->ToCString()) == 0) {
1835 EmitIsNonNegativeSmi(expr->arguments());
1836 } else if (strcmp("_IsObject", *name->ToCString()) == 0) {
1837 EmitIsObject(expr->arguments());
1838 } else if (strcmp("_IsUndetectableObject", *name->ToCString()) == 0) {
1839 EmitIsUndetectableObject(expr->arguments());
1840 } else if (strcmp("_IsFunction", *name->ToCString()) == 0) {
1841 EmitIsFunction(expr->arguments());
1842 } else if (strcmp("_IsArray", *name->ToCString()) == 0) {
1843 EmitIsArray(expr->arguments());
1844 } else if (strcmp("_IsRegExp", *name->ToCString()) == 0) {
1845 EmitIsRegExp(expr->arguments());
1846 } else if (strcmp("_IsConstructCall", *name->ToCString()) == 0) {
1847 EmitIsConstructCall(expr->arguments());
1848 } else if (strcmp("_ObjectEquals", *name->ToCString()) == 0) {
1849 EmitObjectEquals(expr->arguments());
1850 } else if (strcmp("_Arguments", *name->ToCString()) == 0) {
1851 EmitArguments(expr->arguments());
1852 } else if (strcmp("_ArgumentsLength", *name->ToCString()) == 0) {
1853 EmitArgumentsLength(expr->arguments());
1854 } else if (strcmp("_ClassOf", *name->ToCString()) == 0) {
1855 EmitClassOf(expr->arguments());
1856 } else if (strcmp("_Log", *name->ToCString()) == 0) {
1857 EmitLog(expr->arguments());
1858 } else if (strcmp("_RandomHeapNumber", *name->ToCString()) == 0) {
1859 EmitRandomHeapNumber(expr->arguments());
1860 } else if (strcmp("_SubString", *name->ToCString()) == 0) {
1861 EmitSubString(expr->arguments());
1862 } else if (strcmp("_RegExpExec", *name->ToCString()) == 0) {
1863 EmitRegExpExec(expr->arguments());
1864 } else if (strcmp("_ValueOf", *name->ToCString()) == 0) {
1865 EmitValueOf(expr->arguments());
1866 } else if (strcmp("_SetValueOf", *name->ToCString()) == 0) {
1867 EmitSetValueOf(expr->arguments());
1868 } else if (strcmp("_NumberToString", *name->ToCString()) == 0) {
1869 EmitNumberToString(expr->arguments());
1870 } else if (strcmp("_CharFromCode", *name->ToCString()) == 0) {
1871 EmitCharFromCode(expr->arguments());
1872 } else if (strcmp("_FastCharCodeAt", *name->ToCString()) == 0) {
1873 EmitFastCharCodeAt(expr->arguments());
1874 } else if (strcmp("_StringAdd", *name->ToCString()) == 0) {
1875 EmitStringAdd(expr->arguments());
1876 } else if (strcmp("_StringCompare", *name->ToCString()) == 0) {
1877 EmitStringCompare(expr->arguments());
1878 } else if (strcmp("_MathPow", *name->ToCString()) == 0) {
1879 EmitMathPow(expr->arguments());
1880 } else if (strcmp("_MathSin", *name->ToCString()) == 0) {
1881 EmitMathSin(expr->arguments());
1882 } else if (strcmp("_MathCos", *name->ToCString()) == 0) {
1883 EmitMathCos(expr->arguments());
1884 } else if (strcmp("_MathSqrt", *name->ToCString()) == 0) {
1885 EmitMathSqrt(expr->arguments());
1886 } else if (strcmp("_CallFunction", *name->ToCString()) == 0) {
1887 EmitCallFunction(expr->arguments());
1888 } else if (strcmp("_RegExpConstructResult", *name->ToCString()) == 0) {
1889 EmitRegExpConstructResult(expr->arguments());
1890 } else if (strcmp("_SwapElements", *name->ToCString()) == 0) {
1891 EmitSwapElements(expr->arguments());
1892 } else if (strcmp("_GetFromCache", *name->ToCString()) == 0) {
1893 EmitGetFromCache(expr->arguments());
1894 } else {
1895 UNREACHABLE();
1896 }
1897 }
1898
1899
1900 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { 1830 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) {
1901 ASSERT(args->length() == 1); 1831 ASSERT(args->length() == 1);
1902 1832
1903 VisitForValue(args->at(0), kAccumulator); 1833 VisitForValue(args->at(0), kAccumulator);
1904 1834
1905 Label materialize_true, materialize_false; 1835 Label materialize_true, materialize_false;
1906 Label* if_true = NULL; 1836 Label* if_true = NULL;
1907 Label* if_false = NULL; 1837 Label* if_false = NULL;
1908 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1838 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
1909 1839
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
2340 2270
2341 // Load the argument on the stack and call the stub. 2271 // Load the argument on the stack and call the stub.
2342 VisitForValue(args->at(0), kStack); 2272 VisitForValue(args->at(0), kStack);
2343 2273
2344 NumberToStringStub stub; 2274 NumberToStringStub stub;
2345 __ CallStub(&stub); 2275 __ CallStub(&stub);
2346 Apply(context_, r0); 2276 Apply(context_, r0);
2347 } 2277 }
2348 2278
2349 2279
2350 void FullCodeGenerator::EmitCharFromCode(ZoneList<Expression*>* args) { 2280 void FullCodeGenerator::EmitStringCharFromCode(ZoneList<Expression*>* args) {
2351 ASSERT(args->length() == 1); 2281 ASSERT(args->length() == 1);
2352 2282
2353 VisitForValue(args->at(0), kAccumulator); 2283 VisitForValue(args->at(0), kAccumulator);
2354 2284
2355 Label slow_case, done; 2285 Label done;
2356 // Fast case of Heap::LookupSingleCharacterStringFromCode. 2286 StringCharFromCodeGenerator generator(r0, r1);
2357 ASSERT(kSmiTag == 0); 2287 generator.GenerateFast(masm_);
2358 ASSERT(kSmiShiftSize == 0); 2288 __ jmp(&done);
2359 ASSERT(IsPowerOf2(String::kMaxAsciiCharCode + 1));
2360 __ tst(r0, Operand(kSmiTagMask |
2361 ((~String::kMaxAsciiCharCode) << kSmiTagSize)));
2362 __ b(nz, &slow_case);
2363 __ mov(r1, Operand(Factory::single_character_string_cache()));
2364 ASSERT(kSmiTag == 0);
2365 ASSERT(kSmiTagSize == 1);
2366 ASSERT(kSmiShiftSize == 0);
2367 // At this point code register contains smi tagged ascii char code.
2368 __ add(r1, r1, Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize));
2369 __ ldr(r1, MemOperand(r1, FixedArray::kHeaderSize - kHeapObjectTag));
2370 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
2371 __ cmp(r1, r2);
2372 __ b(eq, &slow_case);
2373 __ mov(r0, r1);
2374 __ b(&done);
2375 2289
2376 __ bind(&slow_case); 2290 NopRuntimeCallHelper call_helper;
2377 __ push(r0); 2291 generator.GenerateSlow(masm_, call_helper);
2378 __ CallRuntime(Runtime::kCharFromCode, 1);
2379 2292
2380 __ bind(&done); 2293 __ bind(&done);
2381 Apply(context_, r0); 2294 Apply(context_, r1);
2382 } 2295 }
2383 2296
2384 2297
2385 void FullCodeGenerator::EmitFastCharCodeAt(ZoneList<Expression*>* args) { 2298 void FullCodeGenerator::EmitStringCharCodeAt(ZoneList<Expression*>* args) {
2386 // TODO(fsc): Port the complete implementation from the classic back-end. 2299 ASSERT(args->length() == 2);
2387 // Move the undefined value into the result register, which will 2300
2388 // trigger the slow case. 2301 VisitForValue(args->at(0), kStack);
2389 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 2302 VisitForValue(args->at(1), kAccumulator);
2390 Apply(context_, r0); 2303
2304 Register object = r1;
2305 Register index = r0;
2306 Register scratch = r2;
2307 Register result = r3;
2308
2309 __ pop(object);
2310
2311 Label need_conversion;
2312 Label index_out_of_range;
2313 Label done;
2314 StringCharCodeAtGenerator generator(object,
2315 index,
2316 scratch,
2317 result,
2318 &need_conversion,
2319 &need_conversion,
2320 &index_out_of_range,
2321 STRING_ANY_NUMBER_INDEX);
2322 generator.GenerateFast(masm_);
2323 __ jmp(&done);
2324
2325 __ bind(&index_out_of_range);
2326 // When the index is out of range, the spec requires us to return
2327 // NaN.
2328 __ LoadRoot(result, Heap::kNanValueRootIndex);
2329 __ jmp(&done);
2330
2331 __ bind(&need_conversion);
2332 // Load the undefined value into the result register, which will
2333 // trigger conversion.
2334 __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
2335 __ jmp(&done);
2336
2337 NopRuntimeCallHelper call_helper;
2338 generator.GenerateSlow(masm_, call_helper);
2339
2340 __ bind(&done);
2341 Apply(context_, result);
2391 } 2342 }
2392 2343
2344
2345 void FullCodeGenerator::EmitStringCharAt(ZoneList<Expression*>* args) {
2346 ASSERT(args->length() == 2);
2347
2348 VisitForValue(args->at(0), kStack);
2349 VisitForValue(args->at(1), kAccumulator);
2350
2351 Register object = r1;
2352 Register index = r0;
2353 Register scratch1 = r2;
2354 Register scratch2 = r3;
2355 Register result = r0;
2356
2357 __ pop(object);
2358
2359 Label need_conversion;
2360 Label index_out_of_range;
2361 Label done;
2362 StringCharAtGenerator generator(object,
2363 index,
2364 scratch1,
2365 scratch2,
2366 result,
2367 &need_conversion,
2368 &need_conversion,
2369 &index_out_of_range,
2370 STRING_ANY_NUMBER_INDEX);
2371 generator.GenerateFast(masm_);
2372 __ jmp(&done);
2373
2374 __ bind(&index_out_of_range);
2375 // When the index is out of range, the spec requires us to return
2376 // the empty string.
2377 __ LoadRoot(result, Heap::kEmptyStringRootIndex);
2378 __ jmp(&done);
2379
2380 __ bind(&need_conversion);
2381 // Move smi zero into the result register, which will trigger
2382 // conversion.
2383 __ mov(result, Operand(Smi::FromInt(0)));
2384 __ jmp(&done);
2385
2386 NopRuntimeCallHelper call_helper;
2387 generator.GenerateSlow(masm_, call_helper);
2388
2389 __ bind(&done);
2390 Apply(context_, result);
2391 }
2392
2393
2393 void FullCodeGenerator::EmitStringAdd(ZoneList<Expression*>* args) { 2394 void FullCodeGenerator::EmitStringAdd(ZoneList<Expression*>* args) {
2394 ASSERT_EQ(2, args->length()); 2395 ASSERT_EQ(2, args->length());
2395 2396
2396 VisitForValue(args->at(0), kStack); 2397 VisitForValue(args->at(0), kStack);
2397 VisitForValue(args->at(1), kStack); 2398 VisitForValue(args->at(1), kStack);
2398 2399
2399 StringAddStub stub(NO_STRING_ADD_FLAGS); 2400 StringAddStub stub(NO_STRING_ADD_FLAGS);
2400 __ CallStub(&stub); 2401 __ CallStub(&stub);
2401 Apply(context_, r0); 2402 Apply(context_, r0);
2402 } 2403 }
(...skipping 729 matching lines...) Expand 10 before | Expand all | Expand 10 after
3132 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. 3133 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value.
3133 __ add(pc, r1, Operand(masm_->CodeObject())); 3134 __ add(pc, r1, Operand(masm_->CodeObject()));
3134 } 3135 }
3135 3136
3136 3137
3137 #undef __ 3138 #undef __
3138 3139
3139 } } // namespace v8::internal 3140 } } // namespace v8::internal
3140 3141
3141 #endif // V8_TARGET_ARCH_ARM 3142 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/codegen-arm.cc ('k') | src/arm/ic-arm.cc » ('j') | src/codegen.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698