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

Side by Side Diff: src/x64/ic-x64.cc

Issue 6020012: Cleanup of x64 code. Rearrange functions in ic-x64.cc to match order in ic-i... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 11 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/x64/debug-x64.cc ('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 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 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 Smi::FromInt(PropertyDetails::TypeField::mask())); 371 Smi::FromInt(PropertyDetails::TypeField::mask()));
372 __ j(not_zero, miss); 372 __ j(not_zero, miss);
373 373
374 // Get the value at the masked, scaled index. 374 // Get the value at the masked, scaled index.
375 const int kValueOffset = 375 const int kValueOffset =
376 NumberDictionary::kElementsStartOffset + kPointerSize; 376 NumberDictionary::kElementsStartOffset + kPointerSize;
377 __ movq(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset)); 377 __ movq(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset));
378 } 378 }
379 379
380 380
381 // One byte opcode for test rax,0xXXXXXXXX. 381 // The offset from the inlined patch site to the start of the inlined
382 static const byte kTestEaxByte = 0xA9; 382 // load instruction.
383 const int LoadIC::kOffsetToLoadInstruction = 20;
383 384
384 385
385 static bool PatchInlinedMapCheck(Address address, Object* map) { 386 void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
386 if (V8::UseCrankshaft()) return false; 387 // ----------- S t a t e -------------
388 // -- rax : receiver
389 // -- rcx : name
390 // -- rsp[0] : return address
391 // -----------------------------------
392 Label miss;
387 393
388 // Arguments are address of start of call sequence that called 394 StubCompiler::GenerateLoadArrayLength(masm, rax, rdx, &miss);
389 // the IC, 395 __ bind(&miss);
390 Address test_instruction_address = 396 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
391 address + Assembler::kCallTargetAddressOffset;
392 // The keyed load has a fast inlined case if the IC call instruction
393 // is immediately followed by a test instruction.
394 if (*test_instruction_address != kTestEaxByte) return false;
395
396 // Fetch the offset from the test instruction to the map compare
397 // instructions (starting with the 64-bit immediate mov of the map
398 // address). This offset is stored in the last 4 bytes of the 5
399 // byte test instruction.
400 Address delta_address = test_instruction_address + 1;
401 int delta = *reinterpret_cast<int*>(delta_address);
402 // Compute the map address. The map address is in the last 8 bytes
403 // of the 10-byte immediate mov instruction (incl. REX prefix), so we add 2
404 // to the offset to get the map address.
405 Address map_address = test_instruction_address + delta + 2;
406 // Patch the map check.
407 *(reinterpret_cast<Object**>(map_address)) = map;
408 return true;
409 } 397 }
410 398
411 399
412 bool KeyedLoadIC::PatchInlinedLoad(Address address, Object* map) { 400 void LoadIC::GenerateStringLength(MacroAssembler* masm) {
413 return PatchInlinedMapCheck(address, map); 401 // ----------- S t a t e -------------
402 // -- rax : receiver
403 // -- rcx : name
404 // -- rsp[0] : return address
405 // -----------------------------------
406 Label miss;
407
408 StubCompiler::GenerateLoadStringLength(masm, rax, rdx, rbx, &miss);
409 __ bind(&miss);
410 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
414 } 411 }
415 412
416 413
417 bool KeyedStoreIC::PatchInlinedStore(Address address, Object* map) { 414 void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) {
418 return PatchInlinedMapCheck(address, map); 415 // ----------- S t a t e -------------
416 // -- rax : receiver
417 // -- rcx : name
418 // -- rsp[0] : return address
419 // -----------------------------------
420 Label miss;
421
422 StubCompiler::GenerateLoadFunctionPrototype(masm, rax, rdx, rbx, &miss);
423 __ bind(&miss);
424 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
419 } 425 }
420 426
421 427
422 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
423 // ----------- S t a t e -------------
424 // -- rax : key
425 // -- rdx : receiver
426 // -- rsp[0] : return address
427 // -----------------------------------
428
429 __ IncrementCounter(&Counters::keyed_load_miss, 1);
430
431 __ pop(rbx);
432 __ push(rdx); // receiver
433 __ push(rax); // name
434 __ push(rbx); // return address
435
436 // Perform tail call to the entry.
437 ExternalReference ref = ExternalReference(IC_Utility(kKeyedLoadIC_Miss));
438 __ TailCallExternalReference(ref, 2, 1);
439 }
440
441
442 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
443 // ----------- S t a t e -------------
444 // -- rax : key
445 // -- rdx : receiver
446 // -- rsp[0] : return address
447 // -----------------------------------
448
449 __ pop(rbx);
450 __ push(rdx); // receiver
451 __ push(rax); // name
452 __ push(rbx); // return address
453
454 // Perform tail call to the entry.
455 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
456 }
457
458
459 // Checks the receiver for special cases (value type, slow case bits). 428 // Checks the receiver for special cases (value type, slow case bits).
460 // Falls through for regular JS object. 429 // Falls through for regular JS object.
461 static void GenerateKeyedLoadReceiverCheck(MacroAssembler* masm, 430 static void GenerateKeyedLoadReceiverCheck(MacroAssembler* masm,
462 Register receiver, 431 Register receiver,
463 Register map, 432 Register map,
464 int interceptor_bit, 433 int interceptor_bit,
465 Label* slow) { 434 Label* slow) {
466 // Register use: 435 // Register use:
467 // receiver - holds the receiver and is unchanged. 436 // receiver - holds the receiver and is unchanged.
468 // Scratch registers: 437 // Scratch registers:
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
916 885
917 // Perform tail call to the entry. 886 // Perform tail call to the entry.
918 __ TailCallExternalReference(ExternalReference( 887 __ TailCallExternalReference(ExternalReference(
919 IC_Utility(kKeyedLoadPropertyWithInterceptor)), 2, 1); 888 IC_Utility(kKeyedLoadPropertyWithInterceptor)), 2, 1);
920 889
921 __ bind(&slow); 890 __ bind(&slow);
922 GenerateMiss(masm); 891 GenerateMiss(masm);
923 } 892 }
924 893
925 894
926 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
927 // ----------- S t a t e -------------
928 // -- rax : value
929 // -- rcx : key
930 // -- rdx : receiver
931 // -- rsp[0] : return address
932 // -----------------------------------
933
934 __ pop(rbx);
935 __ push(rdx); // receiver
936 __ push(rcx); // key
937 __ push(rax); // value
938 __ push(rbx); // return address
939
940 // Do tail-call to runtime routine.
941 ExternalReference ref = ExternalReference(IC_Utility(kKeyedStoreIC_Miss));
942 __ TailCallExternalReference(ref, 3, 1);
943 }
944
945
946 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) {
947 // ----------- S t a t e -------------
948 // -- rax : value
949 // -- rcx : key
950 // -- rdx : receiver
951 // -- rsp[0] : return address
952 // -----------------------------------
953
954 __ pop(rbx);
955 __ push(rdx); // receiver
956 __ push(rcx); // key
957 __ push(rax); // value
958 __ push(rbx); // return address
959
960 // Do tail-call to runtime routine.
961 __ TailCallRuntime(Runtime::kSetProperty, 3, 1);
962 }
963
964
965 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) { 895 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
966 // ----------- S t a t e ------------- 896 // ----------- S t a t e -------------
967 // -- rax : value 897 // -- rax : value
968 // -- rcx : key 898 // -- rcx : key
969 // -- rdx : receiver 899 // -- rdx : receiver
970 // -- rsp[0] : return address 900 // -- rsp[0] : return address
971 // ----------------------------------- 901 // -----------------------------------
972 Label slow, slow_with_tagged_index, fast, array, extra, check_pixel_array; 902 Label slow, slow_with_tagged_index, fast, array, extra, check_pixel_array;
973 903
974 // Check that the object isn't a smi. 904 // Check that the object isn't a smi.
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
1229 } 1159 }
1230 __ ret(0); 1160 __ ret(0);
1231 } 1161 }
1232 1162
1233 // Slow case: call runtime. 1163 // Slow case: call runtime.
1234 __ bind(&slow); 1164 __ bind(&slow);
1235 GenerateRuntimeSetProperty(masm); 1165 GenerateRuntimeSetProperty(masm);
1236 } 1166 }
1237 1167
1238 1168
1239 // Defined in ic.cc.
1240 Object* CallIC_Miss(Arguments args);
1241
1242
1243 static void GenerateCallMiss(MacroAssembler* masm, int argc, IC::UtilityId id) {
1244 // ----------- S t a t e -------------
1245 // rcx : function name
1246 // rsp[0] : return address
1247 // rsp[8] : argument argc
1248 // rsp[16] : argument argc - 1
1249 // ...
1250 // rsp[argc * 8] : argument 1
1251 // rsp[(argc + 1) * 8] : argument 0 = receiver
1252 // -----------------------------------
1253
1254 if (id == IC::kCallIC_Miss) {
1255 __ IncrementCounter(&Counters::call_miss, 1);
1256 } else {
1257 __ IncrementCounter(&Counters::keyed_call_miss, 1);
1258 }
1259
1260 // Get the receiver of the function from the stack; 1 ~ return address.
1261 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
1262
1263 // Enter an internal frame.
1264 __ EnterInternalFrame();
1265
1266 // Push the receiver and the name of the function.
1267 __ push(rdx);
1268 __ push(rcx);
1269
1270 // Call the entry.
1271 CEntryStub stub(1);
1272 __ movq(rax, Immediate(2));
1273 __ movq(rbx, ExternalReference(IC_Utility(id)));
1274 __ CallStub(&stub);
1275
1276 // Move result to rdi and exit the internal frame.
1277 __ movq(rdi, rax);
1278 __ LeaveInternalFrame();
1279
1280 // Check if the receiver is a global object of some sort.
1281 // This can happen only for regular CallIC but not KeyedCallIC.
1282 if (id == IC::kCallIC_Miss) {
1283 Label invoke, global;
1284 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); // receiver
1285 __ JumpIfSmi(rdx, &invoke);
1286 __ CmpObjectType(rdx, JS_GLOBAL_OBJECT_TYPE, rcx);
1287 __ j(equal, &global);
1288 __ CmpInstanceType(rcx, JS_BUILTINS_OBJECT_TYPE);
1289 __ j(not_equal, &invoke);
1290
1291 // Patch the receiver on the stack.
1292 __ bind(&global);
1293 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
1294 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
1295 __ bind(&invoke);
1296 }
1297
1298 // Invoke the function.
1299 ParameterCount actual(argc);
1300 __ InvokeFunction(rdi, actual, JUMP_FUNCTION);
1301 }
1302
1303
1304 // The generated code does not accept smi keys. 1169 // The generated code does not accept smi keys.
1305 // The generated code falls through if both probes miss. 1170 // The generated code falls through if both probes miss.
1306 static void GenerateMonomorphicCacheProbe(MacroAssembler* masm, 1171 static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
1307 int argc, 1172 int argc,
1308 Code::Kind kind) { 1173 Code::Kind kind) {
1309 // ----------- S t a t e ------------- 1174 // ----------- S t a t e -------------
1310 // rcx : function name 1175 // rcx : function name
1311 // rdx : receiver 1176 // rdx : receiver
1312 // ----------------------------------- 1177 // -----------------------------------
1313 Label number, non_number, non_string, boolean, probe, miss; 1178 Label number, non_number, non_string, boolean, probe, miss;
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1402 // rax: elements 1267 // rax: elements
1403 // Search the dictionary placing the result in rdi. 1268 // Search the dictionary placing the result in rdi.
1404 GenerateDictionaryLoad(masm, &miss, rax, rcx, rbx, rdi, rdi); 1269 GenerateDictionaryLoad(masm, &miss, rax, rcx, rbx, rdi, rdi);
1405 1270
1406 GenerateFunctionTailCall(masm, argc, &miss); 1271 GenerateFunctionTailCall(masm, argc, &miss);
1407 1272
1408 __ bind(&miss); 1273 __ bind(&miss);
1409 } 1274 }
1410 1275
1411 1276
1412 void CallIC::GenerateMiss(MacroAssembler* masm, int argc) { 1277 static void GenerateCallMiss(MacroAssembler* masm, int argc, IC::UtilityId id) {
1413 // ----------- S t a t e ------------- 1278 // ----------- S t a t e -------------
1414 // rcx : function name 1279 // rcx : function name
1415 // rsp[0] : return address 1280 // rsp[0] : return address
1416 // rsp[8] : argument argc 1281 // rsp[8] : argument argc
1417 // rsp[16] : argument argc - 1 1282 // rsp[16] : argument argc - 1
1418 // ... 1283 // ...
1419 // rsp[argc * 8] : argument 1 1284 // rsp[argc * 8] : argument 1
1420 // rsp[(argc + 1) * 8] : argument 0 = receiver 1285 // rsp[(argc + 1) * 8] : argument 0 = receiver
1421 // ----------------------------------- 1286 // -----------------------------------
1422 GenerateCallMiss(masm, argc, IC::kCallIC_Miss); 1287
1288 if (id == IC::kCallIC_Miss) {
1289 __ IncrementCounter(&Counters::call_miss, 1);
1290 } else {
1291 __ IncrementCounter(&Counters::keyed_call_miss, 1);
1292 }
1293
1294 // Get the receiver of the function from the stack; 1 ~ return address.
1295 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
1296
1297 // Enter an internal frame.
1298 __ EnterInternalFrame();
1299
1300 // Push the receiver and the name of the function.
1301 __ push(rdx);
1302 __ push(rcx);
1303
1304 // Call the entry.
1305 CEntryStub stub(1);
1306 __ movq(rax, Immediate(2));
1307 __ movq(rbx, ExternalReference(IC_Utility(id)));
1308 __ CallStub(&stub);
1309
1310 // Move result to rdi and exit the internal frame.
1311 __ movq(rdi, rax);
1312 __ LeaveInternalFrame();
1313
1314 // Check if the receiver is a global object of some sort.
1315 // This can happen only for regular CallIC but not KeyedCallIC.
1316 if (id == IC::kCallIC_Miss) {
1317 Label invoke, global;
1318 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); // receiver
1319 __ JumpIfSmi(rdx, &invoke);
1320 __ CmpObjectType(rdx, JS_GLOBAL_OBJECT_TYPE, rcx);
1321 __ j(equal, &global);
1322 __ CmpInstanceType(rcx, JS_BUILTINS_OBJECT_TYPE);
1323 __ j(not_equal, &invoke);
1324
1325 // Patch the receiver on the stack.
1326 __ bind(&global);
1327 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
1328 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
1329 __ bind(&invoke);
1330 }
1331
1332 // Invoke the function.
1333 ParameterCount actual(argc);
1334 __ InvokeFunction(rdi, actual, JUMP_FUNCTION);
1423 } 1335 }
1424 1336
1425 1337
1426 void CallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) { 1338 void CallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
1427 // ----------- S t a t e ------------- 1339 // ----------- S t a t e -------------
1428 // rcx : function name 1340 // rcx : function name
1429 // rsp[0] : return address 1341 // rsp[0] : return address
1430 // rsp[8] : argument argc 1342 // rsp[8] : argument argc
1431 // rsp[16] : argument argc - 1 1343 // rsp[16] : argument argc - 1
1432 // ... 1344 // ...
(...skipping 17 matching lines...) Expand all
1450 // ... 1362 // ...
1451 // rsp[argc * 8] : argument 1 1363 // rsp[argc * 8] : argument 1
1452 // rsp[(argc + 1) * 8] : argument 0 = receiver 1364 // rsp[(argc + 1) * 8] : argument 0 = receiver
1453 // ----------------------------------- 1365 // -----------------------------------
1454 1366
1455 GenerateCallNormal(masm, argc); 1367 GenerateCallNormal(masm, argc);
1456 GenerateMiss(masm, argc); 1368 GenerateMiss(masm, argc);
1457 } 1369 }
1458 1370
1459 1371
1460 void KeyedCallIC::GenerateMiss(MacroAssembler* masm, int argc) { 1372 void CallIC::GenerateMiss(MacroAssembler* masm, int argc) {
1461 // ----------- S t a t e ------------- 1373 // ----------- S t a t e -------------
1462 // rcx : function name 1374 // rcx : function name
1463 // rsp[0] : return address 1375 // rsp[0] : return address
1464 // rsp[8] : argument argc 1376 // rsp[8] : argument argc
1465 // rsp[16] : argument argc - 1 1377 // rsp[16] : argument argc - 1
1466 // ... 1378 // ...
1467 // rsp[argc * 8] : argument 1 1379 // rsp[argc * 8] : argument 1
1468 // rsp[(argc + 1) * 8] : argument 0 = receiver 1380 // rsp[(argc + 1) * 8] : argument 0 = receiver
1469 // ----------------------------------- 1381 // -----------------------------------
1470 1382
1471 GenerateCallMiss(masm, argc, IC::kKeyedCallIC_Miss); 1383 GenerateCallMiss(masm, argc, IC::kCallIC_Miss);
1472 } 1384 }
1473 1385
1474 1386
1475 void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) { 1387 void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
1476 // ----------- S t a t e ------------- 1388 // ----------- S t a t e -------------
1477 // rcx : function name 1389 // rcx : function name
1478 // rsp[0] : return address 1390 // rsp[0] : return address
1479 // rsp[8] : argument argc 1391 // rsp[8] : argument argc
1480 // rsp[16] : argument argc - 1 1392 // rsp[16] : argument argc - 1
1481 // ... 1393 // ...
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1587 // ... 1499 // ...
1588 // rsp[argc * 8] : argument 1 1500 // rsp[argc * 8] : argument 1
1589 // rsp[(argc + 1) * 8] : argument 0 = receiver 1501 // rsp[(argc + 1) * 8] : argument 0 = receiver
1590 // ----------------------------------- 1502 // -----------------------------------
1591 1503
1592 GenerateCallNormal(masm, argc); 1504 GenerateCallNormal(masm, argc);
1593 GenerateMiss(masm, argc); 1505 GenerateMiss(masm, argc);
1594 } 1506 }
1595 1507
1596 1508
1597 // The offset from the inlined patch site to the start of the inlined 1509 void KeyedCallIC::GenerateMiss(MacroAssembler* masm, int argc) {
1598 // load instruction.
1599 const int LoadIC::kOffsetToLoadInstruction = 20;
1600
1601
1602 void LoadIC::GenerateMiss(MacroAssembler* masm) {
1603 // ----------- S t a t e ------------- 1510 // ----------- S t a t e -------------
1604 // -- rax : receiver 1511 // rcx : function name
1605 // -- rcx : name 1512 // rsp[0] : return address
1606 // -- rsp[0] : return address 1513 // rsp[8] : argument argc
1514 // rsp[16] : argument argc - 1
1515 // ...
1516 // rsp[argc * 8] : argument 1
1517 // rsp[(argc + 1) * 8] : argument 0 = receiver
1607 // ----------------------------------- 1518 // -----------------------------------
1608 1519
1609 __ IncrementCounter(&Counters::load_miss, 1); 1520 GenerateCallMiss(masm, argc, IC::kKeyedCallIC_Miss);
1610
1611 __ pop(rbx);
1612 __ push(rax); // receiver
1613 __ push(rcx); // name
1614 __ push(rbx); // return address
1615
1616 // Perform tail call to the entry.
1617 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss));
1618 __ TailCallExternalReference(ref, 2, 1);
1619 }
1620
1621
1622 void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
1623 // ----------- S t a t e -------------
1624 // -- rax : receiver
1625 // -- rcx : name
1626 // -- rsp[0] : return address
1627 // -----------------------------------
1628 Label miss;
1629
1630 StubCompiler::GenerateLoadArrayLength(masm, rax, rdx, &miss);
1631 __ bind(&miss);
1632 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
1633 }
1634
1635
1636 void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) {
1637 // ----------- S t a t e -------------
1638 // -- rax : receiver
1639 // -- rcx : name
1640 // -- rsp[0] : return address
1641 // -----------------------------------
1642 Label miss;
1643
1644 StubCompiler::GenerateLoadFunctionPrototype(masm, rax, rdx, rbx, &miss);
1645 __ bind(&miss);
1646 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
1647 } 1521 }
1648 1522
1649 1523
1650 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { 1524 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
1651 // ----------- S t a t e ------------- 1525 // ----------- S t a t e -------------
1652 // -- rax : receiver 1526 // -- rax : receiver
1653 // -- rcx : name 1527 // -- rcx : name
1654 // -- rsp[0] : return address 1528 // -- rsp[0] : return address
1655 // ----------------------------------- 1529 // -----------------------------------
1656 1530
(...skipping 22 matching lines...) Expand all
1679 // Search the dictionary placing the result in rax. 1553 // Search the dictionary placing the result in rax.
1680 GenerateDictionaryLoad(masm, &miss, rdx, rcx, rbx, rdi, rax); 1554 GenerateDictionaryLoad(masm, &miss, rdx, rcx, rbx, rdi, rax);
1681 __ ret(0); 1555 __ ret(0);
1682 1556
1683 // Cache miss: Jump to runtime. 1557 // Cache miss: Jump to runtime.
1684 __ bind(&miss); 1558 __ bind(&miss);
1685 GenerateMiss(masm); 1559 GenerateMiss(masm);
1686 } 1560 }
1687 1561
1688 1562
1689 void LoadIC::GenerateStringLength(MacroAssembler* masm) { 1563 void LoadIC::GenerateMiss(MacroAssembler* masm) {
1690 // ----------- S t a t e ------------- 1564 // ----------- S t a t e -------------
1691 // -- rax : receiver 1565 // -- rax : receiver
1692 // -- rcx : name 1566 // -- rcx : name
1693 // -- rsp[0] : return address 1567 // -- rsp[0] : return address
1694 // ----------------------------------- 1568 // -----------------------------------
1695 Label miss;
1696 1569
1697 StubCompiler::GenerateLoadStringLength(masm, rax, rdx, rbx, &miss); 1570 __ IncrementCounter(&Counters::load_miss, 1);
1698 __ bind(&miss); 1571
1699 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); 1572 __ pop(rbx);
1573 __ push(rax); // receiver
1574 __ push(rcx); // name
1575 __ push(rbx); // return address
1576
1577 // Perform tail call to the entry.
1578 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss));
1579 __ TailCallExternalReference(ref, 2, 1);
1700 } 1580 }
1701 1581
1702 1582
1703 bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) { 1583 bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) {
1704 if (V8::UseCrankshaft()) return false; 1584 if (V8::UseCrankshaft()) return false;
1705 1585
1706 // The address of the instruction following the call. 1586 // The address of the instruction following the call.
1707 Address test_instruction_address = 1587 Address test_instruction_address =
1708 address + Assembler::kCallTargetAddressOffset; 1588 address + Assembler::kCallTargetAddressOffset;
1709 // If the instruction following the call is not a test rax, nothing 1589 // If the instruction following the call is not a test rax, nothing
1710 // was inlined. 1590 // was inlined.
1711 if (*test_instruction_address != kTestEaxByte) return false; 1591 if (*test_instruction_address != Assembler::kTestEaxByte) return false;
1712 1592
1713 Address delta_address = test_instruction_address + 1; 1593 Address delta_address = test_instruction_address + 1;
1714 // The delta to the start of the map check instruction. 1594 // The delta to the start of the map check instruction.
1715 int delta = *reinterpret_cast<int*>(delta_address); 1595 int delta = *reinterpret_cast<int*>(delta_address);
1716 1596
1717 // The map address is the last 8 bytes of the 10-byte 1597 // The map address is the last 8 bytes of the 10-byte
1718 // immediate move instruction, so we add 2 to get the 1598 // immediate move instruction, so we add 2 to get the
1719 // offset to the last 8 bytes. 1599 // offset to the last 8 bytes.
1720 Address map_address = test_instruction_address + delta + 2; 1600 Address map_address = test_instruction_address + delta + 2;
1721 *(reinterpret_cast<Object**>(map_address)) = map; 1601 *(reinterpret_cast<Object**>(map_address)) = map;
(...skipping 10 matching lines...) Expand all
1732 1612
1733 bool LoadIC::PatchInlinedContextualLoad(Address address, 1613 bool LoadIC::PatchInlinedContextualLoad(Address address,
1734 Object* map, 1614 Object* map,
1735 Object* cell, 1615 Object* cell,
1736 bool is_dont_delete) { 1616 bool is_dont_delete) {
1737 // TODO(<bug#>): implement this. 1617 // TODO(<bug#>): implement this.
1738 return false; 1618 return false;
1739 } 1619 }
1740 1620
1741 1621
1742 // The offset from the inlined patch site to the start of the inlined
1743 // store instruction.
1744 const int StoreIC::kOffsetToStoreInstruction = 20;
1745
1746
1747 bool StoreIC::PatchInlinedStore(Address address, Object* map, int offset) { 1622 bool StoreIC::PatchInlinedStore(Address address, Object* map, int offset) {
1748 if (V8::UseCrankshaft()) return false; 1623 if (V8::UseCrankshaft()) return false;
1749 1624
1750 // The address of the instruction following the call. 1625 // The address of the instruction following the call.
1751 Address test_instruction_address = 1626 Address test_instruction_address =
1752 address + Assembler::kCallTargetAddressOffset; 1627 address + Assembler::kCallTargetAddressOffset;
1753 1628
1754 // If the instruction following the call is not a test rax, nothing 1629 // If the instruction following the call is not a test rax, nothing
1755 // was inlined. 1630 // was inlined.
1756 if (*test_instruction_address != kTestEaxByte) return false; 1631 if (*test_instruction_address != Assembler::kTestEaxByte) return false;
1757 1632
1758 // Extract the encoded deltas from the test rax instruction. 1633 // Extract the encoded deltas from the test rax instruction.
1759 Address encoded_offsets_address = test_instruction_address + 1; 1634 Address encoded_offsets_address = test_instruction_address + 1;
1760 int encoded_offsets = *reinterpret_cast<int*>(encoded_offsets_address); 1635 int encoded_offsets = *reinterpret_cast<int*>(encoded_offsets_address);
1761 int delta_to_map_check = -(encoded_offsets & 0xFFFF); 1636 int delta_to_map_check = -(encoded_offsets & 0xFFFF);
1762 int delta_to_record_write = encoded_offsets >> 16; 1637 int delta_to_record_write = encoded_offsets >> 16;
1763 1638
1764 // Patch the map to check. The map address is the last 8 bytes of 1639 // Patch the map to check. The map address is the last 8 bytes of
1765 // the 10-byte immediate move instruction. 1640 // the 10-byte immediate move instruction.
1766 Address map_check_address = test_instruction_address + delta_to_map_check; 1641 Address map_check_address = test_instruction_address + delta_to_map_check;
(...skipping 18 matching lines...) Expand all
1785 // (-1) or we should be clearing the inlined version. 1660 // (-1) or we should be clearing the inlined version.
1786 ASSERT(*reinterpret_cast<int*>(offset_address) == kMaxInt || 1661 ASSERT(*reinterpret_cast<int*>(offset_address) == kMaxInt ||
1787 *reinterpret_cast<int*>(offset_address) == -1 || 1662 *reinterpret_cast<int*>(offset_address) == -1 ||
1788 (offset == 0 && map == Heap::null_value())); 1663 (offset == 0 && map == Heap::null_value()));
1789 *reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag; 1664 *reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag;
1790 1665
1791 return true; 1666 return true;
1792 } 1667 }
1793 1668
1794 1669
1795 void StoreIC::GenerateMiss(MacroAssembler* masm) { 1670 static bool PatchInlinedMapCheck(Address address, Object* map) {
1671 if (V8::UseCrankshaft()) return false;
1672
1673 // Arguments are address of start of call sequence that called
1674 // the IC,
1675 Address test_instruction_address =
1676 address + Assembler::kCallTargetAddressOffset;
1677 // The keyed load has a fast inlined case if the IC call instruction
1678 // is immediately followed by a test instruction.
1679 if (*test_instruction_address != Assembler::kTestEaxByte) return false;
1680
1681 // Fetch the offset from the test instruction to the map compare
1682 // instructions (starting with the 64-bit immediate mov of the map
1683 // address). This offset is stored in the last 4 bytes of the 5
1684 // byte test instruction.
1685 Address delta_address = test_instruction_address + 1;
1686 int delta = *reinterpret_cast<int*>(delta_address);
1687 // Compute the map address. The map address is in the last 8 bytes
1688 // of the 10-byte immediate mov instruction (incl. REX prefix), so we add 2
1689 // to the offset to get the map address.
1690 Address map_address = test_instruction_address + delta + 2;
1691 // Patch the map check.
1692 *(reinterpret_cast<Object**>(map_address)) = map;
1693 return true;
1694 }
1695
1696
1697 bool KeyedLoadIC::PatchInlinedLoad(Address address, Object* map) {
1698 return PatchInlinedMapCheck(address, map);
1699 }
1700
1701
1702 bool KeyedStoreIC::PatchInlinedStore(Address address, Object* map) {
1703 return PatchInlinedMapCheck(address, map);
1704 }
1705
1706
1707 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
1796 // ----------- S t a t e ------------- 1708 // ----------- S t a t e -------------
1797 // -- rax : value 1709 // -- rax : key
1798 // -- rcx : name
1799 // -- rdx : receiver 1710 // -- rdx : receiver
1800 // -- rsp[0] : return address 1711 // -- rsp[0] : return address
1712 // -----------------------------------
1713
1714 __ IncrementCounter(&Counters::keyed_load_miss, 1);
1715
1716 __ pop(rbx);
1717 __ push(rdx); // receiver
1718 __ push(rax); // name
1719 __ push(rbx); // return address
1720
1721 // Perform tail call to the entry.
1722 ExternalReference ref = ExternalReference(IC_Utility(kKeyedLoadIC_Miss));
1723 __ TailCallExternalReference(ref, 2, 1);
1724 }
1725
1726
1727 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
1728 // ----------- S t a t e -------------
1729 // -- rax : key
1730 // -- rdx : receiver
1731 // -- rsp[0] : return address
1801 // ----------------------------------- 1732 // -----------------------------------
1802 1733
1803 __ pop(rbx); 1734 __ pop(rbx);
1804 __ push(rdx); // receiver 1735 __ push(rdx); // receiver
1805 __ push(rcx); // name 1736 __ push(rax); // name
1806 __ push(rax); // value
1807 __ push(rbx); // return address 1737 __ push(rbx); // return address
1808 1738
1809 // Perform tail call to the entry. 1739 // Perform tail call to the entry.
1810 ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss)); 1740 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
1811 __ TailCallExternalReference(ref, 3, 1);
1812 } 1741 }
1813 1742
1814 1743
1815 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { 1744 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
1816 // ----------- S t a t e ------------- 1745 // ----------- S t a t e -------------
1817 // -- rax : value 1746 // -- rax : value
1818 // -- rcx : name 1747 // -- rcx : name
1819 // -- rdx : receiver 1748 // -- rdx : receiver
1820 // -- rsp[0] : return address 1749 // -- rsp[0] : return address
1821 // ----------------------------------- 1750 // -----------------------------------
1822 1751
1823 // Get the receiver from the stack and probe the stub cache. 1752 // Get the receiver from the stack and probe the stub cache.
1824 Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, 1753 Code::Flags flags = Code::ComputeFlags(Code::STORE_IC,
1825 NOT_IN_LOOP, 1754 NOT_IN_LOOP,
1826 MONOMORPHIC); 1755 MONOMORPHIC);
1827 StubCache::GenerateProbe(masm, flags, rdx, rcx, rbx, no_reg); 1756 StubCache::GenerateProbe(masm, flags, rdx, rcx, rbx, no_reg);
1828 1757
1829 // Cache miss: Jump to runtime. 1758 // Cache miss: Jump to runtime.
1830 GenerateMiss(masm); 1759 GenerateMiss(masm);
1831 } 1760 }
1832 1761
1833 1762
1763 void StoreIC::GenerateMiss(MacroAssembler* masm) {
1764 // ----------- S t a t e -------------
1765 // -- rax : value
1766 // -- rcx : name
1767 // -- rdx : receiver
1768 // -- rsp[0] : return address
1769 // -----------------------------------
1770
1771 __ pop(rbx);
1772 __ push(rdx); // receiver
1773 __ push(rcx); // name
1774 __ push(rax); // value
1775 __ push(rbx); // return address
1776
1777 // Perform tail call to the entry.
1778 ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss));
1779 __ TailCallExternalReference(ref, 3, 1);
1780 }
1781
1782
1783 // The offset from the inlined patch site to the start of the inlined
1784 // store instruction.
1785 const int StoreIC::kOffsetToStoreInstruction = 20;
1786
1787
1834 void StoreIC::GenerateArrayLength(MacroAssembler* masm) { 1788 void StoreIC::GenerateArrayLength(MacroAssembler* masm) {
1835 // ----------- S t a t e ------------- 1789 // ----------- S t a t e -------------
1836 // -- rax : value 1790 // -- rax : value
1837 // -- rcx : name 1791 // -- rcx : name
1838 // -- rdx : receiver 1792 // -- rdx : receiver
1839 // -- rsp[0] : return address 1793 // -- rsp[0] : return address
1840 // ----------------------------------- 1794 // -----------------------------------
1841 // 1795 //
1842 // This accepts as a receiver anything JSObject::SetElementsLength accepts 1796 // This accepts as a receiver anything JSObject::SetElementsLength accepts
1843 // (currently anything except for external and pixel arrays which means 1797 // (currently anything except for external and pixel arrays which means
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1916 __ push(rdx); 1870 __ push(rdx);
1917 __ push(rcx); 1871 __ push(rcx);
1918 __ push(rax); 1872 __ push(rax);
1919 __ push(rbx); 1873 __ push(rbx);
1920 1874
1921 // Do tail-call to runtime routine. 1875 // Do tail-call to runtime routine.
1922 __ TailCallRuntime(Runtime::kSetProperty, 3, 1); 1876 __ TailCallRuntime(Runtime::kSetProperty, 3, 1);
1923 } 1877 }
1924 1878
1925 1879
1880 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) {
1881 // ----------- S t a t e -------------
1882 // -- rax : value
1883 // -- rcx : key
1884 // -- rdx : receiver
1885 // -- rsp[0] : return address
1886 // -----------------------------------
1887
1888 __ pop(rbx);
1889 __ push(rdx); // receiver
1890 __ push(rcx); // key
1891 __ push(rax); // value
1892 __ push(rbx); // return address
1893
1894 // Do tail-call to runtime routine.
1895 __ TailCallRuntime(Runtime::kSetProperty, 3, 1);
1896 }
1897
1898
1899 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
1900 // ----------- S t a t e -------------
1901 // -- rax : value
1902 // -- rcx : key
1903 // -- rdx : receiver
1904 // -- rsp[0] : return address
1905 // -----------------------------------
1906
1907 __ pop(rbx);
1908 __ push(rdx); // receiver
1909 __ push(rcx); // key
1910 __ push(rax); // value
1911 __ push(rbx); // return address
1912
1913 // Do tail-call to runtime routine.
1914 ExternalReference ref = ExternalReference(IC_Utility(kKeyedStoreIC_Miss));
1915 __ TailCallExternalReference(ref, 3, 1);
1916 }
1917
1918
1926 #undef __ 1919 #undef __
1927 1920
1928 1921
1929 Condition CompareIC::ComputeCondition(Token::Value op) { 1922 Condition CompareIC::ComputeCondition(Token::Value op) {
1930 switch (op) { 1923 switch (op) {
1931 case Token::EQ_STRICT: 1924 case Token::EQ_STRICT:
1932 case Token::EQ: 1925 case Token::EQ:
1933 return equal; 1926 return equal;
1934 case Token::LT: 1927 case Token::LT:
1935 return less; 1928 return less;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1969 GetStateName(state), 1962 GetStateName(state),
1970 Token::Name(op_)); 1963 Token::Name(op_));
1971 } 1964 }
1972 #endif 1965 #endif
1973 } 1966 }
1974 1967
1975 void PatchInlinedSmiCode(Address address) { 1968 void PatchInlinedSmiCode(Address address) {
1976 UNIMPLEMENTED(); 1969 UNIMPLEMENTED();
1977 } 1970 }
1978 1971
1972
1979 } } // namespace v8::internal 1973 } } // namespace v8::internal
1980 1974
1981 #endif // V8_TARGET_ARCH_X64 1975 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/debug-x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698