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

Side by Side Diff: src/x64/full-codegen-x64.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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 1886 matching lines...) Expand 10 before | Expand all | Expand 10 after
1897 __ movq(rdi, Operand(rsp, rax, times_pointer_size, kPointerSize)); 1897 __ movq(rdi, Operand(rsp, rax, times_pointer_size, kPointerSize));
1898 1898
1899 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall)); 1899 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall));
1900 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); 1900 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
1901 1901
1902 // Replace function on TOS with result in rax, or pop it. 1902 // Replace function on TOS with result in rax, or pop it.
1903 DropAndApply(1, context_, rax); 1903 DropAndApply(1, context_, rax);
1904 } 1904 }
1905 1905
1906 1906
1907 void FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* expr) {
1908 Handle<String> name = expr->name();
1909 if (strcmp("_IsSmi", *name->ToCString()) == 0) {
1910 EmitIsSmi(expr->arguments());
1911 } else if (strcmp("_IsNonNegativeSmi", *name->ToCString()) == 0) {
1912 EmitIsNonNegativeSmi(expr->arguments());
1913 } else if (strcmp("_IsObject", *name->ToCString()) == 0) {
1914 EmitIsObject(expr->arguments());
1915 } else if (strcmp("_IsUndetectableObject", *name->ToCString()) == 0) {
1916 EmitIsUndetectableObject(expr->arguments());
1917 } else if (strcmp("_IsFunction", *name->ToCString()) == 0) {
1918 EmitIsFunction(expr->arguments());
1919 } else if (strcmp("_IsArray", *name->ToCString()) == 0) {
1920 EmitIsArray(expr->arguments());
1921 } else if (strcmp("_IsRegExp", *name->ToCString()) == 0) {
1922 EmitIsRegExp(expr->arguments());
1923 } else if (strcmp("_IsConstructCall", *name->ToCString()) == 0) {
1924 EmitIsConstructCall(expr->arguments());
1925 } else if (strcmp("_ObjectEquals", *name->ToCString()) == 0) {
1926 EmitObjectEquals(expr->arguments());
1927 } else if (strcmp("_Arguments", *name->ToCString()) == 0) {
1928 EmitArguments(expr->arguments());
1929 } else if (strcmp("_ArgumentsLength", *name->ToCString()) == 0) {
1930 EmitArgumentsLength(expr->arguments());
1931 } else if (strcmp("_ClassOf", *name->ToCString()) == 0) {
1932 EmitClassOf(expr->arguments());
1933 } else if (strcmp("_Log", *name->ToCString()) == 0) {
1934 EmitLog(expr->arguments());
1935 } else if (strcmp("_RandomHeapNumber", *name->ToCString()) == 0) {
1936 EmitRandomHeapNumber(expr->arguments());
1937 } else if (strcmp("_SubString", *name->ToCString()) == 0) {
1938 EmitSubString(expr->arguments());
1939 } else if (strcmp("_RegExpExec", *name->ToCString()) == 0) {
1940 EmitRegExpExec(expr->arguments());
1941 } else if (strcmp("_ValueOf", *name->ToCString()) == 0) {
1942 EmitValueOf(expr->arguments());
1943 } else if (strcmp("_SetValueOf", *name->ToCString()) == 0) {
1944 EmitSetValueOf(expr->arguments());
1945 } else if (strcmp("_NumberToString", *name->ToCString()) == 0) {
1946 EmitNumberToString(expr->arguments());
1947 } else if (strcmp("_CharFromCode", *name->ToCString()) == 0) {
1948 EmitCharFromCode(expr->arguments());
1949 } else if (strcmp("_FastCharCodeAt", *name->ToCString()) == 0) {
1950 EmitFastCharCodeAt(expr->arguments());
1951 } else if (strcmp("_StringAdd", *name->ToCString()) == 0) {
1952 EmitStringAdd(expr->arguments());
1953 } else if (strcmp("_StringCompare", *name->ToCString()) == 0) {
1954 EmitStringCompare(expr->arguments());
1955 } else if (strcmp("_MathPow", *name->ToCString()) == 0) {
1956 EmitMathPow(expr->arguments());
1957 } else if (strcmp("_MathSin", *name->ToCString()) == 0) {
1958 EmitMathSin(expr->arguments());
1959 } else if (strcmp("_MathCos", *name->ToCString()) == 0) {
1960 EmitMathCos(expr->arguments());
1961 } else if (strcmp("_MathSqrt", *name->ToCString()) == 0) {
1962 EmitMathSqrt(expr->arguments());
1963 } else if (strcmp("_CallFunction", *name->ToCString()) == 0) {
1964 EmitCallFunction(expr->arguments());
1965 } else if (strcmp("_RegExpConstructResult", *name->ToCString()) == 0) {
1966 EmitRegExpConstructResult(expr->arguments());
1967 } else if (strcmp("_SwapElements", *name->ToCString()) == 0) {
1968 EmitSwapElements(expr->arguments());
1969 } else if (strcmp("_GetFromCache", *name->ToCString()) == 0) {
1970 EmitGetFromCache(expr->arguments());
1971 } else {
1972 UNREACHABLE();
1973 }
1974 }
1975
1976
1977 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { 1907 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) {
1978 ASSERT(args->length() == 1); 1908 ASSERT(args->length() == 1);
1979 1909
1980 VisitForValue(args->at(0), kAccumulator); 1910 VisitForValue(args->at(0), kAccumulator);
1981 1911
1982 Label materialize_true, materialize_false; 1912 Label materialize_true, materialize_false;
1983 Label* if_true = NULL; 1913 Label* if_true = NULL;
1984 Label* if_false = NULL; 1914 Label* if_false = NULL;
1985 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1915 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
1986 1916
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
2405 2335
2406 // Load the argument on the stack and call the stub. 2336 // Load the argument on the stack and call the stub.
2407 VisitForValue(args->at(0), kStack); 2337 VisitForValue(args->at(0), kStack);
2408 2338
2409 NumberToStringStub stub; 2339 NumberToStringStub stub;
2410 __ CallStub(&stub); 2340 __ CallStub(&stub);
2411 Apply(context_, rax); 2341 Apply(context_, rax);
2412 } 2342 }
2413 2343
2414 2344
2415 void FullCodeGenerator::EmitCharFromCode(ZoneList<Expression*>* args) { 2345 void FullCodeGenerator::EmitStringCharFromCode(ZoneList<Expression*>* args) {
2416 ASSERT(args->length() == 1); 2346 ASSERT(args->length() == 1);
2417 2347
2418 VisitForValue(args->at(0), kAccumulator); 2348 VisitForValue(args->at(0), kAccumulator);
2419 2349
2420 Label slow_case, done; 2350 Label done;
2421 // Fast case of Heap::LookupSingleCharacterStringFromCode. 2351 StringCharFromCodeGenerator generator(rax, rbx);
2422 __ JumpIfNotSmi(rax, &slow_case); 2352 generator.GenerateFast(masm_);
2423 __ SmiToInteger32(rcx, rax);
2424 __ cmpl(rcx, Immediate(String::kMaxAsciiCharCode));
2425 __ j(above, &slow_case);
2426
2427 __ Move(rbx, Factory::single_character_string_cache());
2428 __ movq(rbx, FieldOperand(rbx,
2429 rcx,
2430 times_pointer_size,
2431 FixedArray::kHeaderSize));
2432
2433 __ CompareRoot(rbx, Heap::kUndefinedValueRootIndex);
2434 __ j(equal, &slow_case);
2435 __ movq(rax, rbx);
2436 __ jmp(&done); 2353 __ jmp(&done);
2437 2354
2438 __ bind(&slow_case); 2355 NopRuntimeCallHelper call_helper;
2439 __ push(rax); 2356 generator.GenerateSlow(masm_, call_helper);
2440 __ CallRuntime(Runtime::kCharFromCode, 1);
2441 2357
2442 __ bind(&done); 2358 __ bind(&done);
2443 Apply(context_, rax); 2359 Apply(context_, rbx);
2444 } 2360 }
2445 2361
2446 2362
2447 void FullCodeGenerator::EmitFastCharCodeAt(ZoneList<Expression*>* args) { 2363 void FullCodeGenerator::EmitStringCharCodeAt(ZoneList<Expression*>* args) {
2448 // TODO(fsc): Port the complete implementation from the classic back-end. 2364 ASSERT(args->length() == 2);
2365
2366 VisitForValue(args->at(0), kStack);
2367 VisitForValue(args->at(1), kAccumulator);
2368
2369 Register object = rbx;
2370 Register index = rax;
2371 Register scratch = rcx;
2372 Register result = rdx;
2373
2374 __ pop(object);
2375
2376 Label need_conversion;
2377 Label index_out_of_range;
2378 Label done;
2379 StringCharCodeAtGenerator generator(object,
2380 index,
2381 scratch,
2382 result,
2383 &need_conversion,
2384 &need_conversion,
2385 &index_out_of_range,
2386 STRING_ANY_NUMBER_INDEX);
2387 generator.GenerateFast(masm_);
2388 __ jmp(&done);
2389
2390 __ bind(&index_out_of_range);
2391 // When the index is out of range, the spec requires us to return
2392 // NaN.
2393 __ LoadRoot(result, Heap::kNanValueRootIndex);
2394 __ jmp(&done);
2395
2396 __ bind(&need_conversion);
2449 // Move the undefined value into the result register, which will 2397 // Move the undefined value into the result register, which will
2450 // trigger the slow case. 2398 // trigger conversion.
2451 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 2399 __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
2452 Apply(context_, rax); 2400 __ jmp(&done);
2401
2402 NopRuntimeCallHelper call_helper;
2403 generator.GenerateSlow(masm_, call_helper);
2404
2405 __ bind(&done);
2406 Apply(context_, result);
2453 } 2407 }
2454 2408
2409
2410 void FullCodeGenerator::EmitStringCharAt(ZoneList<Expression*>* args) {
2411 ASSERT(args->length() == 2);
2412
2413 VisitForValue(args->at(0), kStack);
2414 VisitForValue(args->at(1), kAccumulator);
2415
2416 Register object = rbx;
2417 Register index = rax;
2418 Register scratch1 = rcx;
2419 Register scratch2 = rdx;
2420 Register result = rax;
2421
2422 __ pop(object);
2423
2424 Label need_conversion;
2425 Label index_out_of_range;
2426 Label done;
2427 StringCharAtGenerator generator(object,
2428 index,
2429 scratch1,
2430 scratch2,
2431 result,
2432 &need_conversion,
2433 &need_conversion,
2434 &index_out_of_range,
2435 STRING_ANY_NUMBER_INDEX);
2436 generator.GenerateFast(masm_);
2437 __ jmp(&done);
2438
2439 __ bind(&index_out_of_range);
2440 // When the index is out of range, the spec requires us to return
2441 // the empty string.
2442 __ LoadRoot(result, Heap::kEmptyStringRootIndex);
2443 __ jmp(&done);
2444
2445 __ bind(&need_conversion);
2446 // Move smi zero into the result register, which will trigger
2447 // conversion.
2448 __ Move(result, Smi::FromInt(0));
2449 __ jmp(&done);
2450
2451 NopRuntimeCallHelper call_helper;
2452 generator.GenerateSlow(masm_, call_helper);
2453
2454 __ bind(&done);
2455 Apply(context_, result);
2456 }
2457
2458
2455 void FullCodeGenerator::EmitStringAdd(ZoneList<Expression*>* args) { 2459 void FullCodeGenerator::EmitStringAdd(ZoneList<Expression*>* args) {
2456 ASSERT_EQ(2, args->length()); 2460 ASSERT_EQ(2, args->length());
2457 2461
2458 VisitForValue(args->at(0), kStack); 2462 VisitForValue(args->at(0), kStack);
2459 VisitForValue(args->at(1), kStack); 2463 VisitForValue(args->at(1), kStack);
2460 2464
2461 StringAddStub stub(NO_STRING_ADD_FLAGS); 2465 StringAddStub stub(NO_STRING_ADD_FLAGS);
2462 __ CallStub(&stub); 2466 __ CallStub(&stub);
2463 Apply(context_, rax); 2467 Apply(context_, rax);
2464 } 2468 }
(...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after
3210 __ ret(0); 3214 __ ret(0);
3211 } 3215 }
3212 3216
3213 3217
3214 #undef __ 3218 #undef __
3215 3219
3216 3220
3217 } } // namespace v8::internal 3221 } } // namespace v8::internal
3218 3222
3219 #endif // V8_TARGET_ARCH_X64 3223 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/codegen.h ('K') | « src/x64/codegen-x64.cc ('k') | src/x64/ic-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698