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

Side by Side Diff: src/hydrogen.cc

Issue 27011002: Handle string + number in hydrogen. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 1265 matching lines...) Expand 10 before | Expand all | Expand 10 after
1276 array_length, elements_length); 1276 array_length, elements_length);
1277 1277
1278 if_builder.End(); 1278 if_builder.End();
1279 } 1279 }
1280 1280
1281 Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map); 1281 Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map);
1282 } 1282 }
1283 1283
1284 1284
1285 HValue* HGraphBuilder::BuildLookupNumberStringCache( 1285 HValue* HGraphBuilder::BuildLookupNumberStringCache(
1286 HValue* object, 1286 HValue* object, ToStringMode mode, HIfContinuation* continuation) {
1287 HIfContinuation* continuation) {
1288 // Create a joinable continuation. 1287 // Create a joinable continuation.
1289 HIfContinuation found(graph()->CreateBasicBlock(), 1288 HIfContinuation found(graph()->CreateBasicBlock(),
1290 graph()->CreateBasicBlock()); 1289 graph()->CreateBasicBlock());
1291 1290
1292 // Load the number string cache. 1291 // Load the number string cache.
1293 HValue* number_string_cache = 1292 HValue* number_string_cache =
1294 Add<HLoadRoot>(Heap::kNumberStringCacheRootIndex); 1293 Add<HLoadRoot>(Heap::kNumberStringCacheRootIndex);
1295 1294
1296 // Make the hash maks from the length of the number string cache. It 1295 // Make the hash maks from the length of the number string cache. It
1297 // contains two elements (number and string) for each cache entry. 1296 // contains two elements (number and string) for each cache entry.
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1359 Add<HLoadNamedField>(key, HObjectAccess::ForHeapNumberValue()), 1358 Add<HLoadNamedField>(key, HObjectAccess::ForHeapNumberValue()),
1360 Add<HLoadNamedField>(object, HObjectAccess::ForHeapNumberValue()), 1359 Add<HLoadNamedField>(object, HObjectAccess::ForHeapNumberValue()),
1361 Token::EQ); 1360 Token::EQ);
1362 if_keyeqobject.Then(); 1361 if_keyeqobject.Then();
1363 { 1362 {
1364 // Make the key_index available. 1363 // Make the key_index available.
1365 Push(key_index); 1364 Push(key_index);
1366 } 1365 }
1367 if_keyeqobject.JoinContinuation(&found); 1366 if_keyeqobject.JoinContinuation(&found);
1368 } 1367 }
1368 if (mode == CHECK_NUMBER) {
1369 if_objectisnumber.Else();
1370 if_objectisnumber.Deopt("Expected Argument to be Numeric");
1371 }
1369 if_keyisnumber.JoinContinuation(&found); 1372 if_keyisnumber.JoinContinuation(&found);
1370 } 1373 }
1371 if_objectisnumber.JoinContinuation(&found); 1374 if_objectisnumber.JoinContinuation(&found);
1372 } 1375 }
1373 if_objectissmi.End(); 1376 if_objectissmi.End();
1374 1377
1375 // Check for cache hit. 1378 // Check for cache hit.
1376 IfBuilder if_found(this, &found); 1379 IfBuilder if_found(this, &found);
1377 if_found.Then(); 1380 if_found.Then();
1378 1381
1379 // Load the value in case of cache hit. 1382 // Load the value in case of cache hit.
1380 HValue* key_index = Pop(); 1383 HValue* key_index = Pop();
1381 HValue* value_index = Add<HAdd>(key_index, graph()->GetConstant1()); 1384 HValue* value_index = Add<HAdd>(key_index, graph()->GetConstant1());
1382 HValue* value = AddFastElementAccess(number_string_cache, value_index, 1385 HValue* value = AddFastElementAccess(number_string_cache, value_index,
1383 NULL, NULL, FAST_ELEMENTS, false, 1386 NULL, NULL, FAST_ELEMENTS, false,
1384 ALLOW_RETURN_HOLE, STANDARD_STORE); 1387 ALLOW_RETURN_HOLE, STANDARD_STORE);
1385 AddIncrementCounter(isolate()->counters()->number_to_string_native()); 1388 AddIncrementCounter(isolate()->counters()->number_to_string_native());
1386 1389
1387 if_found.CaptureContinuation(continuation); 1390 if_found.CaptureContinuation(continuation);
1388 1391
1389 // The value is only available in true branch of continuation. 1392 // The value is only available in true branch of continuation.
1390 return value; 1393 return value;
1391 } 1394 }
1392 1395
1393 1396
1394 HValue* HGraphBuilder::BuildNumberToString(HValue* number) { 1397 HValue* HGraphBuilder::BuildNumberToString(HValue* number, ToStringMode mode) {
1395 NoObservableSideEffectsScope scope(this); 1398 NoObservableSideEffectsScope scope(this);
1396 1399
1397 // Lookup the number in the number string cache. 1400 // Lookup the number in the number string cache.
1398 HIfContinuation continuation; 1401 HIfContinuation continuation;
1399 HValue* value = BuildLookupNumberStringCache(number, &continuation); 1402 HValue* value = BuildLookupNumberStringCache(number, mode, &continuation);
1400 IfBuilder if_found(this, &continuation); 1403 IfBuilder if_found(this, &continuation);
1401 if_found.Then(); 1404 if_found.Then();
1402 1405
1403 // Cache hit. 1406 // Cache hit.
1404 Push(value); 1407 Push(value);
1405 1408
1406 if_found.Else(); 1409 if_found.Else();
1407 1410
1408 // Cache miss, fallback to runtime. 1411 // Cache miss, fallback to runtime.
1409 Add<HPushArgument>(number); 1412 Add<HPushArgument>(number);
(...skipping 6492 matching lines...) Expand 10 before | Expand all | Expand 10 after
7902 // operation in optimized code, which is more expensive, than a stub call. 7905 // operation in optimized code, which is more expensive, than a stub call.
7903 if (binop_stub && is_non_primitive && !is_string_add) { 7906 if (binop_stub && is_non_primitive && !is_string_add) {
7904 HValue* function = AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op)); 7907 HValue* function = AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op));
7905 Add<HPushArgument>(left); 7908 Add<HPushArgument>(left);
7906 Add<HPushArgument>(right); 7909 Add<HPushArgument>(right);
7907 instr = NewUncasted<HInvokeFunction>(function, 2); 7910 instr = NewUncasted<HInvokeFunction>(function, 2);
7908 } else { 7911 } else {
7909 switch (op) { 7912 switch (op) {
7910 case Token::ADD: 7913 case Token::ADD:
7911 if (is_string_add) { 7914 if (is_string_add) {
7912 StringAddFlags flags = STRING_ADD_CHECK_BOTH; 7915 StringAddFlags flags = STRING_ADD_CHECK_NONE;
7913 if (left_type->Is(Type::String())) { 7916 if (left_type->Is(Type::String())) {
7914 BuildCheckHeapObject(left); 7917 BuildCheckHeapObject(left);
7915 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); 7918 AddInstruction(HCheckInstanceType::NewIsString(left, zone()));
7916 flags = STRING_ADD_CHECK_RIGHT; 7919 if (right_type->Is(Type::Number())) {
7920 right = BuildNumberToString(right, CHECK_NUMBER);
7921 } else {
7922 flags = STRING_ADD_CHECK_RIGHT;
7923 }
7917 } 7924 }
7918 if (right_type->Is(Type::String())) { 7925 if (right_type->Is(Type::String())) {
7926 if (left_type->Is(Type::Number())) {
7927 left = BuildNumberToString(left, CHECK_NUMBER);
7928 } else {
7929 flags = (flags == STRING_ADD_CHECK_RIGHT)
7930 ? STRING_ADD_CHECK_NONE : STRING_ADD_CHECK_LEFT;
7931 }
7919 BuildCheckHeapObject(right); 7932 BuildCheckHeapObject(right);
7920 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); 7933 AddInstruction(HCheckInstanceType::NewIsString(right, zone()));
7921 flags = (flags == STRING_ADD_CHECK_BOTH)
7922 ? STRING_ADD_CHECK_LEFT : STRING_ADD_CHECK_NONE;
7923 } 7934 }
7924 instr = NewUncasted<HStringAdd>(left, right, flags); 7935 instr = NewUncasted<HStringAdd>(left, right, flags);
7925 } else { 7936 } else {
7926 instr = NewUncasted<HAdd>(left, right); 7937 instr = NewUncasted<HAdd>(left, right);
7927 } 7938 }
7928 break; 7939 break;
7929 case Token::SUB: 7940 case Token::SUB:
7930 instr = NewUncasted<HSub>(left, right); 7941 instr = NewUncasted<HSub>(left, right);
7931 break; 7942 break;
7932 case Token::MUL: 7943 case Token::MUL:
(...skipping 1184 matching lines...) Expand 10 before | Expand all | Expand 10 after
9117 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) { 9128 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) {
9118 return Bailout(kInlinedRuntimeFunctionGetFromCache); 9129 return Bailout(kInlinedRuntimeFunctionGetFromCache);
9119 } 9130 }
9120 9131
9121 9132
9122 // Fast support for number to string. 9133 // Fast support for number to string.
9123 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) { 9134 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) {
9124 ASSERT_EQ(1, call->arguments()->length()); 9135 ASSERT_EQ(1, call->arguments()->length());
9125 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9136 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9126 HValue* number = Pop(); 9137 HValue* number = Pop();
9127 HValue* result = BuildNumberToString(number); 9138 HValue* result = BuildNumberToString(number, ALLOW_SIDE_EFFECTS);
9128 return ast_context()->ReturnValue(result); 9139 return ast_context()->ReturnValue(result);
9129 } 9140 }
9130 9141
9131 9142
9132 // Fast call for custom callbacks. 9143 // Fast call for custom callbacks.
9133 void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) { 9144 void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) {
9134 // 1 ~ The function to call is not itself an argument to the call. 9145 // 1 ~ The function to call is not itself an argument to the call.
9135 int arg_count = call->arguments()->length() - 1; 9146 int arg_count = call->arguments()->length() - 1;
9136 ASSERT(arg_count >= 1); // There's always at least a receiver. 9147 ASSERT(arg_count >= 1); // There's always at least a receiver.
9137 9148
(...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after
9875 if (ShouldProduceTraceOutput()) { 9886 if (ShouldProduceTraceOutput()) {
9876 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 9887 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
9877 } 9888 }
9878 9889
9879 #ifdef DEBUG 9890 #ifdef DEBUG
9880 graph_->Verify(false); // No full verify. 9891 graph_->Verify(false); // No full verify.
9881 #endif 9892 #endif
9882 } 9893 }
9883 9894
9884 } } // namespace v8::internal 9895 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698