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

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

Issue 6577036: [Isolates] Merge from bleeding_edge to isolates, revisions 6100-6300. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: '' Created 9 years, 10 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/full-codegen-x64.cc ('k') | src/x64/lithium-codegen-x64.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 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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1404 // rax: elements 1269 // rax: elements
1405 // Search the dictionary placing the result in rdi. 1270 // Search the dictionary placing the result in rdi.
1406 GenerateDictionaryLoad(masm, &miss, rax, rcx, rbx, rdi, rdi); 1271 GenerateDictionaryLoad(masm, &miss, rax, rcx, rbx, rdi, rdi);
1407 1272
1408 GenerateFunctionTailCall(masm, argc, &miss); 1273 GenerateFunctionTailCall(masm, argc, &miss);
1409 1274
1410 __ bind(&miss); 1275 __ bind(&miss);
1411 } 1276 }
1412 1277
1413 1278
1414 void CallIC::GenerateMiss(MacroAssembler* masm, int argc) { 1279 static void GenerateCallMiss(MacroAssembler* masm, int argc, IC::UtilityId id) {
1415 // ----------- S t a t e ------------- 1280 // ----------- S t a t e -------------
1416 // rcx : function name 1281 // rcx : function name
1417 // rsp[0] : return address 1282 // rsp[0] : return address
1418 // rsp[8] : argument argc 1283 // rsp[8] : argument argc
1419 // rsp[16] : argument argc - 1 1284 // rsp[16] : argument argc - 1
1420 // ... 1285 // ...
1421 // rsp[argc * 8] : argument 1 1286 // rsp[argc * 8] : argument 1
1422 // rsp[(argc + 1) * 8] : argument 0 = receiver 1287 // rsp[(argc + 1) * 8] : argument 0 = receiver
1423 // ----------------------------------- 1288 // -----------------------------------
1424 GenerateCallMiss(masm, argc, IC::kCallIC_Miss); 1289
1290 if (id == IC::kCallIC_Miss) {
1291 __ IncrementCounter(COUNTERS->call_miss(), 1);
1292 } else {
1293 __ IncrementCounter(COUNTERS->keyed_call_miss(), 1);
1294 }
1295
1296 // Get the receiver of the function from the stack; 1 ~ return address.
1297 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
1298
1299 // Enter an internal frame.
1300 __ EnterInternalFrame();
1301
1302 // Push the receiver and the name of the function.
1303 __ push(rdx);
1304 __ push(rcx);
1305
1306 // Call the entry.
1307 CEntryStub stub(1);
1308 __ movq(rax, Immediate(2));
1309 __ movq(rbx, ExternalReference(IC_Utility(id)));
1310 __ CallStub(&stub);
1311
1312 // Move result to rdi and exit the internal frame.
1313 __ movq(rdi, rax);
1314 __ LeaveInternalFrame();
1315
1316 // Check if the receiver is a global object of some sort.
1317 // This can happen only for regular CallIC but not KeyedCallIC.
1318 if (id == IC::kCallIC_Miss) {
1319 Label invoke, global;
1320 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); // receiver
1321 __ JumpIfSmi(rdx, &invoke);
1322 __ CmpObjectType(rdx, JS_GLOBAL_OBJECT_TYPE, rcx);
1323 __ j(equal, &global);
1324 __ CmpInstanceType(rcx, JS_BUILTINS_OBJECT_TYPE);
1325 __ j(not_equal, &invoke);
1326
1327 // Patch the receiver on the stack.
1328 __ bind(&global);
1329 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
1330 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
1331 __ bind(&invoke);
1332 }
1333
1334 // Invoke the function.
1335 ParameterCount actual(argc);
1336 __ InvokeFunction(rdi, actual, JUMP_FUNCTION);
1425 } 1337 }
1426 1338
1427 1339
1428 void CallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) { 1340 void CallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
1429 // ----------- S t a t e ------------- 1341 // ----------- S t a t e -------------
1430 // rcx : function name 1342 // rcx : function name
1431 // rsp[0] : return address 1343 // rsp[0] : return address
1432 // rsp[8] : argument argc 1344 // rsp[8] : argument argc
1433 // rsp[16] : argument argc - 1 1345 // rsp[16] : argument argc - 1
1434 // ... 1346 // ...
(...skipping 17 matching lines...) Expand all
1452 // ... 1364 // ...
1453 // rsp[argc * 8] : argument 1 1365 // rsp[argc * 8] : argument 1
1454 // rsp[(argc + 1) * 8] : argument 0 = receiver 1366 // rsp[(argc + 1) * 8] : argument 0 = receiver
1455 // ----------------------------------- 1367 // -----------------------------------
1456 1368
1457 GenerateCallNormal(masm, argc); 1369 GenerateCallNormal(masm, argc);
1458 GenerateMiss(masm, argc); 1370 GenerateMiss(masm, argc);
1459 } 1371 }
1460 1372
1461 1373
1462 void KeyedCallIC::GenerateMiss(MacroAssembler* masm, int argc) { 1374 void CallIC::GenerateMiss(MacroAssembler* masm, int argc) {
1463 // ----------- S t a t e ------------- 1375 // ----------- S t a t e -------------
1464 // rcx : function name 1376 // rcx : function name
1465 // rsp[0] : return address 1377 // rsp[0] : return address
1466 // rsp[8] : argument argc 1378 // rsp[8] : argument argc
1467 // rsp[16] : argument argc - 1 1379 // rsp[16] : argument argc - 1
1468 // ... 1380 // ...
1469 // rsp[argc * 8] : argument 1 1381 // rsp[argc * 8] : argument 1
1470 // rsp[(argc + 1) * 8] : argument 0 = receiver 1382 // rsp[(argc + 1) * 8] : argument 0 = receiver
1471 // ----------------------------------- 1383 // -----------------------------------
1472 1384
1473 GenerateCallMiss(masm, argc, IC::kKeyedCallIC_Miss); 1385 GenerateCallMiss(masm, argc, IC::kCallIC_Miss);
1474 } 1386 }
1475 1387
1476 1388
1477 void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) { 1389 void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
1478 // ----------- S t a t e ------------- 1390 // ----------- S t a t e -------------
1479 // rcx : function name 1391 // rcx : function name
1480 // rsp[0] : return address 1392 // rsp[0] : return address
1481 // rsp[8] : argument argc 1393 // rsp[8] : argument argc
1482 // rsp[16] : argument argc - 1 1394 // rsp[16] : argument argc - 1
1483 // ... 1395 // ...
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1589 // ... 1501 // ...
1590 // rsp[argc * 8] : argument 1 1502 // rsp[argc * 8] : argument 1
1591 // rsp[(argc + 1) * 8] : argument 0 = receiver 1503 // rsp[(argc + 1) * 8] : argument 0 = receiver
1592 // ----------------------------------- 1504 // -----------------------------------
1593 1505
1594 GenerateCallNormal(masm, argc); 1506 GenerateCallNormal(masm, argc);
1595 GenerateMiss(masm, argc); 1507 GenerateMiss(masm, argc);
1596 } 1508 }
1597 1509
1598 1510
1599 // The offset from the inlined patch site to the start of the inlined 1511 void KeyedCallIC::GenerateMiss(MacroAssembler* masm, int argc) {
1600 // load instruction.
1601 const int LoadIC::kOffsetToLoadInstruction = 20;
1602
1603
1604 void LoadIC::GenerateMiss(MacroAssembler* masm) {
1605 // ----------- S t a t e ------------- 1512 // ----------- S t a t e -------------
1606 // -- rax : receiver 1513 // rcx : function name
1607 // -- rcx : name 1514 // rsp[0] : return address
1608 // -- rsp[0] : return address 1515 // rsp[8] : argument argc
1516 // rsp[16] : argument argc - 1
1517 // ...
1518 // rsp[argc * 8] : argument 1
1519 // rsp[(argc + 1) * 8] : argument 0 = receiver
1609 // ----------------------------------- 1520 // -----------------------------------
1610 1521
1611 __ IncrementCounter(COUNTERS->load_miss(), 1); 1522 GenerateCallMiss(masm, argc, IC::kKeyedCallIC_Miss);
1612
1613 __ pop(rbx);
1614 __ push(rax); // receiver
1615 __ push(rcx); // name
1616 __ push(rbx); // return address
1617
1618 // Perform tail call to the entry.
1619 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss));
1620 __ TailCallExternalReference(ref, 2, 1);
1621 }
1622
1623
1624 void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
1625 // ----------- S t a t e -------------
1626 // -- rax : receiver
1627 // -- rcx : name
1628 // -- rsp[0] : return address
1629 // -----------------------------------
1630 Label miss;
1631
1632 StubCompiler::GenerateLoadArrayLength(masm, rax, rdx, &miss);
1633 __ bind(&miss);
1634 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
1635 }
1636
1637
1638 void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) {
1639 // ----------- S t a t e -------------
1640 // -- rax : receiver
1641 // -- rcx : name
1642 // -- rsp[0] : return address
1643 // -----------------------------------
1644 Label miss;
1645
1646 StubCompiler::GenerateLoadFunctionPrototype(masm, rax, rdx, rbx, &miss);
1647 __ bind(&miss);
1648 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
1649 } 1523 }
1650 1524
1651 1525
1652 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { 1526 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
1653 // ----------- S t a t e ------------- 1527 // ----------- S t a t e -------------
1654 // -- rax : receiver 1528 // -- rax : receiver
1655 // -- rcx : name 1529 // -- rcx : name
1656 // -- rsp[0] : return address 1530 // -- rsp[0] : return address
1657 // ----------------------------------- 1531 // -----------------------------------
1658 1532
(...skipping 23 matching lines...) Expand all
1682 // Search the dictionary placing the result in rax. 1556 // Search the dictionary placing the result in rax.
1683 GenerateDictionaryLoad(masm, &miss, rdx, rcx, rbx, rdi, rax); 1557 GenerateDictionaryLoad(masm, &miss, rdx, rcx, rbx, rdi, rax);
1684 __ ret(0); 1558 __ ret(0);
1685 1559
1686 // Cache miss: Jump to runtime. 1560 // Cache miss: Jump to runtime.
1687 __ bind(&miss); 1561 __ bind(&miss);
1688 GenerateMiss(masm); 1562 GenerateMiss(masm);
1689 } 1563 }
1690 1564
1691 1565
1692 void LoadIC::GenerateStringLength(MacroAssembler* masm) { 1566 void LoadIC::GenerateMiss(MacroAssembler* masm) {
1693 // ----------- S t a t e ------------- 1567 // ----------- S t a t e -------------
1694 // -- rax : receiver 1568 // -- rax : receiver
1695 // -- rcx : name 1569 // -- rcx : name
1696 // -- rsp[0] : return address 1570 // -- rsp[0] : return address
1697 // ----------------------------------- 1571 // -----------------------------------
1698 Label miss;
1699 1572
1700 StubCompiler::GenerateLoadStringLength(masm, rax, rdx, rbx, &miss); 1573 __ IncrementCounter(COUNTERS->load_miss(), 1);
1701 __ bind(&miss); 1574
1702 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); 1575 __ pop(rbx);
1576 __ push(rax); // receiver
1577 __ push(rcx); // name
1578 __ push(rbx); // return address
1579
1580 // Perform tail call to the entry.
1581 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss));
1582 __ TailCallExternalReference(ref, 2, 1);
1703 } 1583 }
1704 1584
1705 1585
1706 bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) { 1586 bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) {
1707 if (V8::UseCrankshaft()) return false; 1587 if (V8::UseCrankshaft()) return false;
1708 1588
1709 // The address of the instruction following the call. 1589 // The address of the instruction following the call.
1710 Address test_instruction_address = 1590 Address test_instruction_address =
1711 address + Assembler::kCallTargetAddressOffset; 1591 address + Assembler::kCallTargetAddressOffset;
1712 // If the instruction following the call is not a test rax, nothing 1592 // If the instruction following the call is not a test rax, nothing
1713 // was inlined. 1593 // was inlined.
1714 if (*test_instruction_address != kTestEaxByte) return false; 1594 if (*test_instruction_address != Assembler::kTestEaxByte) return false;
1715 1595
1716 Address delta_address = test_instruction_address + 1; 1596 Address delta_address = test_instruction_address + 1;
1717 // The delta to the start of the map check instruction. 1597 // The delta to the start of the map check instruction.
1718 int delta = *reinterpret_cast<int*>(delta_address); 1598 int delta = *reinterpret_cast<int*>(delta_address);
1719 1599
1720 // The map address is the last 8 bytes of the 10-byte 1600 // The map address is the last 8 bytes of the 10-byte
1721 // immediate move instruction, so we add 2 to get the 1601 // immediate move instruction, so we add 2 to get the
1722 // offset to the last 8 bytes. 1602 // offset to the last 8 bytes.
1723 Address map_address = test_instruction_address + delta + 2; 1603 Address map_address = test_instruction_address + delta + 2;
1724 *(reinterpret_cast<Object**>(map_address)) = map; 1604 *(reinterpret_cast<Object**>(map_address)) = map;
(...skipping 10 matching lines...) Expand all
1735 1615
1736 bool LoadIC::PatchInlinedContextualLoad(Address address, 1616 bool LoadIC::PatchInlinedContextualLoad(Address address,
1737 Object* map, 1617 Object* map,
1738 Object* cell, 1618 Object* cell,
1739 bool is_dont_delete) { 1619 bool is_dont_delete) {
1740 // TODO(<bug#>): implement this. 1620 // TODO(<bug#>): implement this.
1741 return false; 1621 return false;
1742 } 1622 }
1743 1623
1744 1624
1745 // The offset from the inlined patch site to the start of the inlined
1746 // store instruction.
1747 const int StoreIC::kOffsetToStoreInstruction = 20;
1748
1749
1750 bool StoreIC::PatchInlinedStore(Address address, Object* map, int offset) { 1625 bool StoreIC::PatchInlinedStore(Address address, Object* map, int offset) {
1751 if (V8::UseCrankshaft()) return false; 1626 if (V8::UseCrankshaft()) return false;
1752 1627
1753 // The address of the instruction following the call. 1628 // The address of the instruction following the call.
1754 Address test_instruction_address = 1629 Address test_instruction_address =
1755 address + Assembler::kCallTargetAddressOffset; 1630 address + Assembler::kCallTargetAddressOffset;
1756 1631
1757 // If the instruction following the call is not a test rax, nothing 1632 // If the instruction following the call is not a test rax, nothing
1758 // was inlined. 1633 // was inlined.
1759 if (*test_instruction_address != kTestEaxByte) return false; 1634 if (*test_instruction_address != Assembler::kTestEaxByte) return false;
1760 1635
1761 // Extract the encoded deltas from the test rax instruction. 1636 // Extract the encoded deltas from the test rax instruction.
1762 Address encoded_offsets_address = test_instruction_address + 1; 1637 Address encoded_offsets_address = test_instruction_address + 1;
1763 int encoded_offsets = *reinterpret_cast<int*>(encoded_offsets_address); 1638 int encoded_offsets = *reinterpret_cast<int*>(encoded_offsets_address);
1764 int delta_to_map_check = -(encoded_offsets & 0xFFFF); 1639 int delta_to_map_check = -(encoded_offsets & 0xFFFF);
1765 int delta_to_record_write = encoded_offsets >> 16; 1640 int delta_to_record_write = encoded_offsets >> 16;
1766 1641
1767 // Patch the map to check. The map address is the last 8 bytes of 1642 // Patch the map to check. The map address is the last 8 bytes of
1768 // the 10-byte immediate move instruction. 1643 // the 10-byte immediate move instruction.
1769 Address map_check_address = test_instruction_address + delta_to_map_check; 1644 Address map_check_address = test_instruction_address + delta_to_map_check;
(...skipping 18 matching lines...) Expand all
1788 // (-1) or we should be clearing the inlined version. 1663 // (-1) or we should be clearing the inlined version.
1789 ASSERT(*reinterpret_cast<int*>(offset_address) == kMaxInt || 1664 ASSERT(*reinterpret_cast<int*>(offset_address) == kMaxInt ||
1790 *reinterpret_cast<int*>(offset_address) == -1 || 1665 *reinterpret_cast<int*>(offset_address) == -1 ||
1791 (offset == 0 && map == HEAP->null_value())); 1666 (offset == 0 && map == HEAP->null_value()));
1792 *reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag; 1667 *reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag;
1793 1668
1794 return true; 1669 return true;
1795 } 1670 }
1796 1671
1797 1672
1798 void StoreIC::GenerateMiss(MacroAssembler* masm) { 1673 static bool PatchInlinedMapCheck(Address address, Object* map) {
1674 if (V8::UseCrankshaft()) return false;
1675
1676 // Arguments are address of start of call sequence that called
1677 // the IC,
1678 Address test_instruction_address =
1679 address + Assembler::kCallTargetAddressOffset;
1680 // The keyed load has a fast inlined case if the IC call instruction
1681 // is immediately followed by a test instruction.
1682 if (*test_instruction_address != Assembler::kTestEaxByte) return false;
1683
1684 // Fetch the offset from the test instruction to the map compare
1685 // instructions (starting with the 64-bit immediate mov of the map
1686 // address). This offset is stored in the last 4 bytes of the 5
1687 // byte test instruction.
1688 Address delta_address = test_instruction_address + 1;
1689 int delta = *reinterpret_cast<int*>(delta_address);
1690 // Compute the map address. The map address is in the last 8 bytes
1691 // of the 10-byte immediate mov instruction (incl. REX prefix), so we add 2
1692 // to the offset to get the map address.
1693 Address map_address = test_instruction_address + delta + 2;
1694 // Patch the map check.
1695 *(reinterpret_cast<Object**>(map_address)) = map;
1696 return true;
1697 }
1698
1699
1700 bool KeyedLoadIC::PatchInlinedLoad(Address address, Object* map) {
1701 return PatchInlinedMapCheck(address, map);
1702 }
1703
1704
1705 bool KeyedStoreIC::PatchInlinedStore(Address address, Object* map) {
1706 return PatchInlinedMapCheck(address, map);
1707 }
1708
1709
1710 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
1799 // ----------- S t a t e ------------- 1711 // ----------- S t a t e -------------
1800 // -- rax : value 1712 // -- rax : key
1801 // -- rcx : name
1802 // -- rdx : receiver 1713 // -- rdx : receiver
1803 // -- rsp[0] : return address 1714 // -- rsp[0] : return address
1715 // -----------------------------------
1716
1717 __ IncrementCounter(COUNTERS->keyed_load_miss(), 1);
1718
1719 __ pop(rbx);
1720 __ push(rdx); // receiver
1721 __ push(rax); // name
1722 __ push(rbx); // return address
1723
1724 // Perform tail call to the entry.
1725 ExternalReference ref = ExternalReference(IC_Utility(kKeyedLoadIC_Miss));
1726 __ TailCallExternalReference(ref, 2, 1);
1727 }
1728
1729
1730 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
1731 // ----------- S t a t e -------------
1732 // -- rax : key
1733 // -- rdx : receiver
1734 // -- rsp[0] : return address
1804 // ----------------------------------- 1735 // -----------------------------------
1805 1736
1806 __ pop(rbx); 1737 __ pop(rbx);
1807 __ push(rdx); // receiver 1738 __ push(rdx); // receiver
1808 __ push(rcx); // name 1739 __ push(rax); // name
1809 __ push(rax); // value
1810 __ push(rbx); // return address 1740 __ push(rbx); // return address
1811 1741
1812 // Perform tail call to the entry. 1742 // Perform tail call to the entry.
1813 ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss)); 1743 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
1814 __ TailCallExternalReference(ref, 3, 1);
1815 } 1744 }
1816 1745
1817 1746
1818 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { 1747 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
1819 // ----------- S t a t e ------------- 1748 // ----------- S t a t e -------------
1820 // -- rax : value 1749 // -- rax : value
1821 // -- rcx : name 1750 // -- rcx : name
1822 // -- rdx : receiver 1751 // -- rdx : receiver
1823 // -- rsp[0] : return address 1752 // -- rsp[0] : return address
1824 // ----------------------------------- 1753 // -----------------------------------
1825 1754
1826 // Get the receiver from the stack and probe the stub cache. 1755 // Get the receiver from the stack and probe the stub cache.
1827 Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, 1756 Code::Flags flags = Code::ComputeFlags(Code::STORE_IC,
1828 NOT_IN_LOOP, 1757 NOT_IN_LOOP,
1829 MONOMORPHIC); 1758 MONOMORPHIC);
1830 Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rdx, rcx, rbx, 1759 Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rdx, rcx, rbx,
1831 no_reg); 1760 no_reg);
1832 1761
1833 // Cache miss: Jump to runtime. 1762 // Cache miss: Jump to runtime.
1834 GenerateMiss(masm); 1763 GenerateMiss(masm);
1835 } 1764 }
1836 1765
1837 1766
1767 void StoreIC::GenerateMiss(MacroAssembler* masm) {
1768 // ----------- S t a t e -------------
1769 // -- rax : value
1770 // -- rcx : name
1771 // -- rdx : receiver
1772 // -- rsp[0] : return address
1773 // -----------------------------------
1774
1775 __ pop(rbx);
1776 __ push(rdx); // receiver
1777 __ push(rcx); // name
1778 __ push(rax); // value
1779 __ push(rbx); // return address
1780
1781 // Perform tail call to the entry.
1782 ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss));
1783 __ TailCallExternalReference(ref, 3, 1);
1784 }
1785
1786
1787 // The offset from the inlined patch site to the start of the inlined
1788 // store instruction.
1789 const int StoreIC::kOffsetToStoreInstruction = 20;
1790
1791
1838 void StoreIC::GenerateArrayLength(MacroAssembler* masm) { 1792 void StoreIC::GenerateArrayLength(MacroAssembler* masm) {
1839 // ----------- S t a t e ------------- 1793 // ----------- S t a t e -------------
1840 // -- rax : value 1794 // -- rax : value
1841 // -- rcx : name 1795 // -- rcx : name
1842 // -- rdx : receiver 1796 // -- rdx : receiver
1843 // -- rsp[0] : return address 1797 // -- rsp[0] : return address
1844 // ----------------------------------- 1798 // -----------------------------------
1845 // 1799 //
1846 // This accepts as a receiver anything JSObject::SetElementsLength accepts 1800 // This accepts as a receiver anything JSObject::SetElementsLength accepts
1847 // (currently anything except for external and pixel arrays which means 1801 // (currently anything except for external and pixel arrays which means
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1920 __ push(rdx); 1874 __ push(rdx);
1921 __ push(rcx); 1875 __ push(rcx);
1922 __ push(rax); 1876 __ push(rax);
1923 __ push(rbx); 1877 __ push(rbx);
1924 1878
1925 // Do tail-call to runtime routine. 1879 // Do tail-call to runtime routine.
1926 __ TailCallRuntime(Runtime::kSetProperty, 3, 1); 1880 __ TailCallRuntime(Runtime::kSetProperty, 3, 1);
1927 } 1881 }
1928 1882
1929 1883
1884 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) {
1885 // ----------- S t a t e -------------
1886 // -- rax : value
1887 // -- rcx : key
1888 // -- rdx : receiver
1889 // -- rsp[0] : return address
1890 // -----------------------------------
1891
1892 __ pop(rbx);
1893 __ push(rdx); // receiver
1894 __ push(rcx); // key
1895 __ push(rax); // value
1896 __ push(rbx); // return address
1897
1898 // Do tail-call to runtime routine.
1899 __ TailCallRuntime(Runtime::kSetProperty, 3, 1);
1900 }
1901
1902
1903 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
1904 // ----------- S t a t e -------------
1905 // -- rax : value
1906 // -- rcx : key
1907 // -- rdx : receiver
1908 // -- rsp[0] : return address
1909 // -----------------------------------
1910
1911 __ pop(rbx);
1912 __ push(rdx); // receiver
1913 __ push(rcx); // key
1914 __ push(rax); // value
1915 __ push(rbx); // return address
1916
1917 // Do tail-call to runtime routine.
1918 ExternalReference ref = ExternalReference(IC_Utility(kKeyedStoreIC_Miss));
1919 __ TailCallExternalReference(ref, 3, 1);
1920 }
1921
1922
1930 #undef __ 1923 #undef __
1931 1924
1932 1925
1933 Condition CompareIC::ComputeCondition(Token::Value op) { 1926 Condition CompareIC::ComputeCondition(Token::Value op) {
1934 switch (op) { 1927 switch (op) {
1935 case Token::EQ_STRICT: 1928 case Token::EQ_STRICT:
1936 case Token::EQ: 1929 case Token::EQ:
1937 return equal; 1930 return equal;
1938 case Token::LT: 1931 case Token::LT:
1939 return less; 1932 return less;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1973 GetStateName(state), 1966 GetStateName(state),
1974 Token::Name(op_)); 1967 Token::Name(op_));
1975 } 1968 }
1976 #endif 1969 #endif
1977 } 1970 }
1978 1971
1979 void PatchInlinedSmiCode(Address address) { 1972 void PatchInlinedSmiCode(Address address) {
1980 UNIMPLEMENTED(); 1973 UNIMPLEMENTED();
1981 } 1974 }
1982 1975
1976
1983 } } // namespace v8::internal 1977 } } // namespace v8::internal
1984 1978
1985 #endif // V8_TARGET_ARCH_X64 1979 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/full-codegen-x64.cc ('k') | src/x64/lithium-codegen-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698