| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |