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

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

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

Powered by Google App Engine
This is Rietveld 408576698