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/ia32/full-codegen-ia32.cc

Issue 2087009: Custom call IC-s for String.prototype.{charAt,charCodeAt}. (Closed)
Patch Set: ARM port. Created 10 years, 6 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 1884 matching lines...) Expand 10 before | Expand all | Expand 10 after
1895 __ mov(edi, Operand(esp, eax, times_pointer_size, kPointerSize)); 1895 __ mov(edi, Operand(esp, eax, times_pointer_size, kPointerSize));
1896 1896
1897 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall)); 1897 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall));
1898 __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL); 1898 __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
1899 1899
1900 // Replace function on TOS with result in eax, or pop it. 1900 // Replace function on TOS with result in eax, or pop it.
1901 DropAndApply(1, context_, eax); 1901 DropAndApply(1, context_, eax);
1902 } 1902 }
1903 1903
1904 1904
1905 void FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* expr) {
1906 Handle<String> name = expr->name();
1907 if (strcmp("_IsSmi", *name->ToCString()) == 0) {
1908 EmitIsSmi(expr->arguments());
1909 } else if (strcmp("_IsNonNegativeSmi", *name->ToCString()) == 0) {
1910 EmitIsNonNegativeSmi(expr->arguments());
1911 } else if (strcmp("_IsObject", *name->ToCString()) == 0) {
1912 EmitIsObject(expr->arguments());
1913 } else if (strcmp("_IsUndetectableObject", *name->ToCString()) == 0) {
1914 EmitIsUndetectableObject(expr->arguments());
1915 } else if (strcmp("_IsFunction", *name->ToCString()) == 0) {
1916 EmitIsFunction(expr->arguments());
1917 } else if (strcmp("_IsArray", *name->ToCString()) == 0) {
1918 EmitIsArray(expr->arguments());
1919 } else if (strcmp("_IsRegExp", *name->ToCString()) == 0) {
1920 EmitIsRegExp(expr->arguments());
1921 } else if (strcmp("_IsConstructCall", *name->ToCString()) == 0) {
1922 EmitIsConstructCall(expr->arguments());
1923 } else if (strcmp("_ObjectEquals", *name->ToCString()) == 0) {
1924 EmitObjectEquals(expr->arguments());
1925 } else if (strcmp("_Arguments", *name->ToCString()) == 0) {
1926 EmitArguments(expr->arguments());
1927 } else if (strcmp("_ArgumentsLength", *name->ToCString()) == 0) {
1928 EmitArgumentsLength(expr->arguments());
1929 } else if (strcmp("_ClassOf", *name->ToCString()) == 0) {
1930 EmitClassOf(expr->arguments());
1931 } else if (strcmp("_Log", *name->ToCString()) == 0) {
1932 EmitLog(expr->arguments());
1933 } else if (strcmp("_RandomHeapNumber", *name->ToCString()) == 0) {
1934 EmitRandomHeapNumber(expr->arguments());
1935 } else if (strcmp("_SubString", *name->ToCString()) == 0) {
1936 EmitSubString(expr->arguments());
1937 } else if (strcmp("_RegExpExec", *name->ToCString()) == 0) {
1938 EmitRegExpExec(expr->arguments());
1939 } else if (strcmp("_ValueOf", *name->ToCString()) == 0) {
1940 EmitValueOf(expr->arguments());
1941 } else if (strcmp("_SetValueOf", *name->ToCString()) == 0) {
1942 EmitSetValueOf(expr->arguments());
1943 } else if (strcmp("_NumberToString", *name->ToCString()) == 0) {
1944 EmitNumberToString(expr->arguments());
1945 } else if (strcmp("_CharFromCode", *name->ToCString()) == 0) {
1946 EmitCharFromCode(expr->arguments());
1947 } else if (strcmp("_FastCharCodeAt", *name->ToCString()) == 0) {
1948 EmitFastCharCodeAt(expr->arguments());
1949 } else if (strcmp("_StringAdd", *name->ToCString()) == 0) {
1950 EmitStringAdd(expr->arguments());
1951 } else if (strcmp("_StringCompare", *name->ToCString()) == 0) {
1952 EmitStringCompare(expr->arguments());
1953 } else if (strcmp("_MathPow", *name->ToCString()) == 0) {
1954 EmitMathPow(expr->arguments());
1955 } else if (strcmp("_MathSin", *name->ToCString()) == 0) {
1956 EmitMathSin(expr->arguments());
1957 } else if (strcmp("_MathCos", *name->ToCString()) == 0) {
1958 EmitMathCos(expr->arguments());
1959 } else if (strcmp("_MathSqrt", *name->ToCString()) == 0) {
1960 EmitMathSqrt(expr->arguments());
1961 } else if (strcmp("_CallFunction", *name->ToCString()) == 0) {
1962 EmitCallFunction(expr->arguments());
1963 } else if (strcmp("_RegExpConstructResult", *name->ToCString()) == 0) {
1964 EmitRegExpConstructResult(expr->arguments());
1965 } else if (strcmp("_SwapElements", *name->ToCString()) == 0) {
1966 EmitSwapElements(expr->arguments());
1967 } else if (strcmp("_GetFromCache", *name->ToCString()) == 0) {
1968 EmitGetFromCache(expr->arguments());
1969 } else {
1970 UNREACHABLE();
1971 }
1972 }
1973
1974
1975 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { 1905 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) {
1976 ASSERT(args->length() == 1); 1906 ASSERT(args->length() == 1);
1977 1907
1978 VisitForValue(args->at(0), kAccumulator); 1908 VisitForValue(args->at(0), kAccumulator);
1979 1909
1980 Label materialize_true, materialize_false; 1910 Label materialize_true, materialize_false;
1981 Label* if_true = NULL; 1911 Label* if_true = NULL;
1982 Label* if_false = NULL; 1912 Label* if_false = NULL;
1983 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1913 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
1984 1914
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
2423 2353
2424 // Load the argument on the stack and call the stub. 2354 // Load the argument on the stack and call the stub.
2425 VisitForValue(args->at(0), kStack); 2355 VisitForValue(args->at(0), kStack);
2426 2356
2427 NumberToStringStub stub; 2357 NumberToStringStub stub;
2428 __ CallStub(&stub); 2358 __ CallStub(&stub);
2429 Apply(context_, eax); 2359 Apply(context_, eax);
2430 } 2360 }
2431 2361
2432 2362
2433 void FullCodeGenerator::EmitCharFromCode(ZoneList<Expression*>* args) { 2363 void FullCodeGenerator::EmitStringCharFromCode(ZoneList<Expression*>* args) {
2434 ASSERT(args->length() == 1); 2364 ASSERT(args->length() == 1);
2435 2365
2436 VisitForValue(args->at(0), kAccumulator); 2366 VisitForValue(args->at(0), kAccumulator);
2437 2367
2438 Label slow_case, done; 2368 Label done;
2439 // Fast case of Heap::LookupSingleCharacterStringFromCode. 2369 StringCharFromCodeGenerator generator(eax, ebx);
2440 ASSERT(kSmiTag == 0); 2370 generator.GenerateFast(masm_);
2441 ASSERT(kSmiShiftSize == 0);
2442 ASSERT(IsPowerOf2(String::kMaxAsciiCharCode + 1));
2443 __ test(eax,
2444 Immediate(kSmiTagMask |
2445 ((~String::kMaxAsciiCharCode) << kSmiTagSize)));
2446 __ j(not_zero, &slow_case);
2447 __ Set(ebx, Immediate(Factory::single_character_string_cache()));
2448 ASSERT(kSmiTag == 0);
2449 ASSERT(kSmiTagSize == 1);
2450 ASSERT(kSmiShiftSize == 0);
2451 // At this point code register contains smi tagged ascii char code.
2452 __ mov(ebx, FieldOperand(ebx,
2453 eax, times_half_pointer_size,
2454 FixedArray::kHeaderSize));
2455 __ cmp(ebx, Factory::undefined_value());
2456 __ j(equal, &slow_case);
2457 __ mov(eax, ebx);
2458 __ jmp(&done); 2371 __ jmp(&done);
2459 2372
2460 __ bind(&slow_case); 2373 NopRuntimeCallHelper call_helper;
2461 __ push(eax); 2374 generator.GenerateSlow(masm_, call_helper);
2462 __ CallRuntime(Runtime::kCharFromCode, 1);
2463 2375
2464 __ bind(&done); 2376 __ bind(&done);
2465 Apply(context_, eax); 2377 Apply(context_, ebx);
2466 } 2378 }
2467 2379
2468 2380
2469 void FullCodeGenerator::EmitFastCharCodeAt(ZoneList<Expression*>* args) { 2381 void FullCodeGenerator::EmitStringCharCodeAt(ZoneList<Expression*>* args) {
2470 // TODO(fsc): Port the complete implementation from the classic back-end. 2382 ASSERT(args->length() == 2);
2383
2384 VisitForValue(args->at(0), kStack);
2385 VisitForValue(args->at(1), kAccumulator);
2386
2387 Register object = ebx;
2388 Register index = eax;
2389 Register scratch = ecx;
2390 Register result = edx;
2391
2392 __ pop(object);
2393
2394 Label need_conversion;
2395 Label index_out_of_range;
2396 Label done;
2397 StringCharCodeAtGenerator generator(object,
2398 index,
2399 scratch,
2400 result,
2401 &need_conversion,
2402 &need_conversion,
2403 &index_out_of_range,
2404 STRING_ANY_NUMBER_INDEX);
2405 generator.GenerateFast(masm_);
2406 __ jmp(&done);
2407
2408 __ bind(&index_out_of_range);
2409 // When the index is out of range, the spec requires us to return
2410 // NaN.
2411 __ Set(result, Immediate(Factory::nan_value()));
2412 __ jmp(&done);
2413
2414 __ bind(&need_conversion);
2471 // Move the undefined value into the result register, which will 2415 // Move the undefined value into the result register, which will
2472 // trigger the slow case. 2416 // trigger conversion.
2473 __ Set(eax, Immediate(Factory::undefined_value())); 2417 __ Set(result, Immediate(Factory::undefined_value()));
2474 Apply(context_, eax); 2418 __ jmp(&done);
2419
2420 NopRuntimeCallHelper call_helper;
2421 generator.GenerateSlow(masm_, call_helper);
2422
2423 __ bind(&done);
2424 Apply(context_, result);
2475 } 2425 }
2476 2426
2427
2428 void FullCodeGenerator::EmitStringCharAt(ZoneList<Expression*>* args) {
2429 ASSERT(args->length() == 2);
2430
2431 VisitForValue(args->at(0), kStack);
2432 VisitForValue(args->at(1), kAccumulator);
2433
2434 Register object = ebx;
2435 Register index = eax;
2436 Register scratch1 = ecx;
2437 Register scratch2 = edx;
2438 Register result = eax;
2439
2440 __ pop(object);
2441
2442 Label need_conversion;
2443 Label index_out_of_range;
2444 Label done;
2445 StringCharAtGenerator generator(object,
2446 index,
2447 scratch1,
2448 scratch2,
2449 result,
2450 &need_conversion,
2451 &need_conversion,
2452 &index_out_of_range,
2453 STRING_ANY_NUMBER_INDEX);
2454 generator.GenerateFast(masm_);
2455 __ jmp(&done);
2456
2457 __ bind(&index_out_of_range);
2458 // When the index is out of range, the spec requires us to return
2459 // the empty string.
2460 __ Set(result, Immediate(Factory::empty_string()));
2461 __ jmp(&done);
2462
2463 __ bind(&need_conversion);
2464 // Move smi zero into the result register, which will trigger
2465 // conversion.
2466 __ Set(result, Immediate(Smi::FromInt(0)));
2467 __ jmp(&done);
2468
2469 NopRuntimeCallHelper call_helper;
2470 generator.GenerateSlow(masm_, call_helper);
2471
2472 __ bind(&done);
2473 Apply(context_, result);
2474 }
2475
2476
2477 void FullCodeGenerator::EmitStringAdd(ZoneList<Expression*>* args) { 2477 void FullCodeGenerator::EmitStringAdd(ZoneList<Expression*>* args) {
2478 ASSERT_EQ(2, args->length()); 2478 ASSERT_EQ(2, args->length());
2479 2479
2480 VisitForValue(args->at(0), kStack); 2480 VisitForValue(args->at(0), kStack);
2481 VisitForValue(args->at(1), kStack); 2481 VisitForValue(args->at(1), kStack);
2482 2482
2483 StringAddStub stub(NO_STRING_ADD_FLAGS); 2483 StringAddStub stub(NO_STRING_ADD_FLAGS);
2484 __ CallStub(&stub); 2484 __ CallStub(&stub);
2485 Apply(context_, eax); 2485 Apply(context_, eax);
2486 } 2486 }
(...skipping 747 matching lines...) Expand 10 before | Expand all | Expand 10 after
3234 // And return. 3234 // And return.
3235 __ ret(0); 3235 __ ret(0);
3236 } 3236 }
3237 3237
3238 3238
3239 #undef __ 3239 #undef __
3240 3240
3241 } } // namespace v8::internal 3241 } } // namespace v8::internal
3242 3242
3243 #endif // V8_TARGET_ARCH_IA32 3243 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« src/codegen.h ('K') | « src/ia32/codegen-ia32.cc ('k') | src/ia32/ic-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698