this repo has no description

Add assembly interpreter implementation of LOAD_METHOD_MODULE

authored by bernsteinbear.com and committed by

Max Bernstein 9da20009 95588822

+56 -11
+56 -11
runtime/interpreter-gen-x64.cpp
··· 1459 1459 emitJumpToGenericHandler(env); 1460 1460 } 1461 1461 1462 + static void emitHeaderHashcode(EmitEnv* env, Register r_dst, 1463 + Register r_container) { 1464 + // Load header().hashCode() as a SmallInt 1465 + // r_dst = header().hashCode() 1466 + __ movq(r_dst, 1467 + Address(r_container, heapObjectDisp(RawHeapObject::kHeaderOffset))); 1468 + __ shrq(r_dst, Immediate(RawHeader::kHashCodeOffset)); 1469 + static_assert(RawHeader::kHashCodeOffset == 32, 1470 + "expected hash code to occupy top half of qword"); 1471 + static_assert(RawHeader::kHashCodeBits == 32, 1472 + "expected hash code to occupy top half of qword"); 1473 + __ shlq(r_dst, Immediate(Object::kSmallIntTagBits)); 1474 + } 1475 + 1476 + void emitPushImmediate(EmitEnv* env, word value) { 1477 + if (Utils::fits<int32_t>(value)) { 1478 + __ pushq(Immediate(value)); 1479 + } else { 1480 + ScratchReg r_scratch(env); 1481 + 1482 + __ movq(r_scratch, Immediate(value)); 1483 + __ pushq(r_scratch); 1484 + } 1485 + } 1486 + 1487 + template <> 1488 + void emitHandler<LOAD_METHOD_MODULE>(EmitEnv* env) { 1489 + ScratchReg r_base(env); 1490 + ScratchReg r_module_id(env); 1491 + ScratchReg r_function(env); 1492 + ScratchReg r_caches(env); 1493 + Label slow_path; 1494 + 1495 + __ popq(r_base); 1496 + emitJumpIfImmediate(env, r_base, &slow_path, Assembler::kNearJump); 1497 + emitJumpIfNotHasLayoutId(env, r_base, LayoutId::kModule, &slow_path); 1498 + __ movq(r_caches, Address(env->frame, Frame::kCachesOffset)); 1499 + // TODO(emacs): Avoid a second header lookup here. I am not sure what a 1500 + // reasonable API for that would look like. 1501 + emitHeaderHashcode(env, r_module_id, r_base); 1502 + emitIcLookupMonomorphic(env, &slow_path, r_function, r_module_id, r_caches); 1503 + __ movq(r_function, 1504 + Address(r_function, heapObjectDisp(ValueCell::kValueOffset))); 1505 + emitPushImmediate(env, Unbound::object().raw()); 1506 + __ pushq(r_function); 1507 + emitNextOpcode(env); 1508 + 1509 + __ bind(&slow_path); 1510 + __ pushq(r_base); 1511 + if (env->in_jit) { 1512 + emitJumpToDeopt(env); 1513 + return; 1514 + } 1515 + emitJumpToGenericHandler(env); 1516 + } 1517 + 1462 1518 template <> 1463 1519 void emitHandler<LOAD_METHOD_POLYMORPHIC>(EmitEnv* env) { 1464 1520 ScratchReg r_base(env); ··· 2858 2914 2859 2915 env->register_state.check(env->call_trampoline_assignment); 2860 2916 emitCallTrampoline(env); 2861 - } 2862 - 2863 - void emitPushImmediate(EmitEnv* env, word value) { 2864 - if (Utils::fits<int32_t>(value)) { 2865 - __ pushq(Immediate(value)); 2866 - } else { 2867 - ScratchReg r_scratch(env); 2868 - 2869 - __ movq(r_scratch, Immediate(value)); 2870 - __ pushq(r_scratch); 2871 - } 2872 2917 } 2873 2918 2874 2919 template <>