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

Side by Side Diff: src/hydrogen.cc

Issue 23726041: Turn the NumberToStringStub into a hydrogen stub. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments. 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') | src/hydrogen-instructions.h » ('j') | 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 1255 matching lines...) Expand 10 before | Expand all | Expand 10 after
1266 BuildGrowElementsCapacity(object, elements, from_kind, to_kind, 1266 BuildGrowElementsCapacity(object, elements, from_kind, to_kind,
1267 array_length, elements_length); 1267 array_length, elements_length);
1268 1268
1269 if_builder.End(); 1269 if_builder.End();
1270 } 1270 }
1271 1271
1272 Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map); 1272 Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map);
1273 } 1273 }
1274 1274
1275 1275
1276 HValue* HGraphBuilder::BuildLookupNumberStringCache(
1277 HValue* object,
1278 HIfContinuation* continuation) {
1279 // Create a joinable continuation.
1280 HIfContinuation found(graph()->CreateBasicBlock(),
1281 graph()->CreateBasicBlock());
1282
1283 // Load the number string cache.
1284 HValue* number_string_cache =
1285 Add<HLoadRoot>(Heap::kNumberStringCacheRootIndex);
1286
1287 // Make the hash maks from the length of the number string cache. It
1288 // contains two elements (number and string) for each cache entry.
1289 HValue* mask = AddLoadFixedArrayLength(number_string_cache);
1290 mask->set_type(HType::Smi());
1291 mask = Add<HSar>(mask, graph()->GetConstant1());
1292 mask = Add<HSub>(mask, graph()->GetConstant1());
1293
1294 // Check whether object is a smi.
1295 IfBuilder if_objectissmi(this);
1296 if_objectissmi.If<HIsSmiAndBranch>(object);
1297 if_objectissmi.Then();
1298 {
1299 // Compute hash for smi similar to smi_get_hash().
1300 HValue* hash = Add<HBitwise>(Token::BIT_AND, object, mask);
1301
1302 // Load the key.
1303 HValue* key_index = Add<HShl>(hash, graph()->GetConstant1());
1304 HValue* key = AddFastElementAccess(number_string_cache, key_index,
1305 NULL, NULL, FAST_ELEMENTS, false,
1306 ALLOW_RETURN_HOLE, STANDARD_STORE);
1307
1308 // Check if object == key.
1309 IfBuilder if_objectiskey(this);
1310 if_objectiskey.If<HCompareObjectEqAndBranch>(key, object);
1311 if_objectiskey.Then();
1312 {
1313 // Make the key_index available.
1314 Push(key_index);
1315 }
1316 if_objectiskey.JoinContinuation(&found);
1317 }
1318 if_objectissmi.Else();
1319 {
1320 // Check if object is a heap number.
1321 IfBuilder if_objectisnumber(this);
1322 if_objectisnumber.If<HCompareMap>(
1323 object, isolate()->factory()->heap_number_map());
1324 if_objectisnumber.Then();
1325 {
1326 // Compute hash for heap number similar to double_get_hash().
1327 HValue* low = Add<HLoadNamedField>(
1328 object, HObjectAccess::ForHeapNumberValueLowestBits());
1329 HValue* high = Add<HLoadNamedField>(
1330 object, HObjectAccess::ForHeapNumberValueHighestBits());
1331 HValue* hash = Add<HBitwise>(Token::BIT_XOR, low, high);
1332 hash = Add<HBitwise>(Token::BIT_AND, hash, mask);
1333
1334 // Load the key.
1335 HValue* key_index = Add<HShl>(hash, graph()->GetConstant1());
1336 HValue* key = AddFastElementAccess(number_string_cache, key_index,
1337 NULL, NULL, FAST_ELEMENTS, false,
1338 ALLOW_RETURN_HOLE, STANDARD_STORE);
1339
1340 // Check if key is a heap number.
1341 IfBuilder if_keyisnumber(this);
1342 if_keyisnumber.IfNot<HIsSmiAndBranch>(key);
1343 if_keyisnumber.AndIf<HCompareMap>(
1344 key, isolate()->factory()->heap_number_map());
1345 if_keyisnumber.Then();
1346 {
1347 // Check if values of key and object match.
1348 IfBuilder if_keyeqobject(this);
1349 if_keyeqobject.If<HCompareNumericAndBranch>(
1350 Add<HLoadNamedField>(key, HObjectAccess::ForHeapNumberValue()),
1351 Add<HLoadNamedField>(object, HObjectAccess::ForHeapNumberValue()),
1352 Token::EQ);
1353 if_keyeqobject.Then();
1354 {
1355 // Make the key_index available.
1356 Push(key_index);
1357 }
1358 if_keyeqobject.JoinContinuation(&found);
1359 }
1360 if_keyisnumber.JoinContinuation(&found);
1361 }
1362 if_objectisnumber.JoinContinuation(&found);
1363 }
1364 if_objectissmi.End();
1365
1366 // Check for cache hit.
1367 IfBuilder if_found(this, &found);
1368 if_found.Then();
1369
1370 // Load the value in case of cache hit.
1371 HValue* key_index = Pop();
1372 HValue* value_index = Add<HAdd>(key_index, graph()->GetConstant1());
1373 HValue* value = AddFastElementAccess(number_string_cache, value_index,
1374 NULL, NULL, FAST_ELEMENTS, false,
1375 ALLOW_RETURN_HOLE, STANDARD_STORE);
1376 AddIncrementCounter(isolate()->counters()->number_to_string_native());
1377
1378 if_found.CaptureContinuation(continuation);
1379
1380 // The value is only available in true branch of continuation.
1381 return value;
1382 }
1383
1384
1385 HValue* HGraphBuilder::BuildNumberToString(HValue* number) {
1386 NoObservableSideEffectsScope scope(this);
1387
1388 // Lookup the number in the number string cache.
1389 HIfContinuation continuation;
1390 HValue* value = BuildLookupNumberStringCache(number, &continuation);
1391 IfBuilder if_found(this, &continuation);
1392 if_found.Then();
1393
1394 // Cache hit.
1395 Push(value);
1396
1397 if_found.Else();
1398
1399 // Cache miss, fallback to runtime.
1400 Add<HPushArgument>(number);
1401 Push(Add<HCallRuntime>(
1402 isolate()->factory()->empty_string(),
1403 Runtime::FunctionForId(Runtime::kNumberToStringSkipCache),
1404 1));
1405
1406 if_found.End();
1407
1408 return Pop();
1409 }
1410
1411
1276 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( 1412 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
1277 HValue* checked_object, 1413 HValue* checked_object,
1278 HValue* key, 1414 HValue* key,
1279 HValue* val, 1415 HValue* val,
1280 bool is_js_array, 1416 bool is_js_array,
1281 ElementsKind elements_kind, 1417 ElementsKind elements_kind,
1282 bool is_store, 1418 bool is_store,
1283 LoadKeyedHoleMode load_mode, 1419 LoadKeyedHoleMode load_mode,
1284 KeyedAccessStoreMode store_mode) { 1420 KeyedAccessStoreMode store_mode) {
1285 ASSERT(!IsExternalArrayElementsKind(elements_kind) || !is_js_array); 1421 ASSERT(!IsExternalArrayElementsKind(elements_kind) || !is_js_array);
(...skipping 7716 matching lines...) Expand 10 before | Expand all | Expand 10 after
9002 9138
9003 // Support for fast native caches. 9139 // Support for fast native caches.
9004 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) { 9140 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) {
9005 return Bailout(kInlinedRuntimeFunctionGetFromCache); 9141 return Bailout(kInlinedRuntimeFunctionGetFromCache);
9006 } 9142 }
9007 9143
9008 9144
9009 // Fast support for number to string. 9145 // Fast support for number to string.
9010 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) { 9146 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) {
9011 ASSERT_EQ(1, call->arguments()->length()); 9147 ASSERT_EQ(1, call->arguments()->length());
9012 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9148 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9013 HValue* context = environment()->context(); 9149 HValue* number = Pop();
9014 HCallStub* result = 9150 HValue* result = BuildNumberToString(number);
9015 new(zone()) HCallStub(context, CodeStub::NumberToString, 1); 9151 return ast_context()->ReturnValue(result);
9016 Drop(1);
9017 return ast_context()->ReturnInstruction(result, call->id());
9018 } 9152 }
9019 9153
9020 9154
9021 // Fast call for custom callbacks. 9155 // Fast call for custom callbacks.
9022 void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) { 9156 void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) {
9023 // 1 ~ The function to call is not itself an argument to the call. 9157 // 1 ~ The function to call is not itself an argument to the call.
9024 int arg_count = call->arguments()->length() - 1; 9158 int arg_count = call->arguments()->length() - 1;
9025 ASSERT(arg_count >= 1); // There's always at least a receiver. 9159 ASSERT(arg_count >= 1); // There's always at least a receiver.
9026 9160
9027 for (int i = 0; i < arg_count; ++i) { 9161 for (int i = 0; i < arg_count; ++i) {
(...skipping 746 matching lines...) Expand 10 before | Expand all | Expand 10 after
9774 if (ShouldProduceTraceOutput()) { 9908 if (ShouldProduceTraceOutput()) {
9775 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 9909 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
9776 } 9910 }
9777 9911
9778 #ifdef DEBUG 9912 #ifdef DEBUG
9779 graph_->Verify(false); // No full verify. 9913 graph_->Verify(false); // No full verify.
9780 #endif 9914 #endif
9781 } 9915 }
9782 9916
9783 } } // namespace v8::internal 9917 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698