[前][次][番号順一覧][スレッド一覧]

ruby-changes:68622

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:11:02 +0900 (JST)
Subject: [ruby-changes:68622] e0c5d4ecd9 (master): Implemented side-exits to interpreter. setlocal_WC_0

https://git.ruby-lang.org/ruby.git/commit/?id=e0c5d4ecd9

From e0c5d4ecd9e864fa531ecceb29ed0e195bf08644 Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Mon, 28 Sep 2020 15:50:41 -0400
Subject: Implemented side-exits to interpreter. setlocal_WC_0

---
 ujit_asm.c       | 115 +++++++++++++++++++++++++++------
 ujit_asm.h       |  36 ++++++++++-
 ujit_asm_tests.c |  29 +++------
 ujit_compile.c   | 194 ++++++++++++++++++++++++++++---------------------------
 4 files changed, 240 insertions(+), 134 deletions(-)

diff --git a/ujit_asm.c b/ujit_asm.c
index 5d70c7b299..6a79e85854 100644
--- a/ujit_asm.c
+++ b/ujit_asm.c
@@ -127,6 +127,14 @@ x86opnd_t mem_opnd(size_t num_bits, x86opnd_t base_reg, int32_t disp) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L127
     return opnd;
 }
 
+x86opnd_t resize_opnd(x86opnd_t opnd, size_t num_bits)
+{
+    assert (num_bits % 8 == 0);
+    x86opnd_t sub = opnd;
+    sub.num_bits = num_bits;
+    return sub;
+}
+
 x86opnd_t imm_opnd(int64_t imm)
 {
     x86opnd_t opnd = {
@@ -149,11 +157,12 @@ x86opnd_t const_ptr_opnd(void* ptr) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L157
     return opnd;
 }
 
-void cb_init(codeblock_t* cb, size_t mem_size)
+// Allocate a block of executable memory
+uint8_t* alloc_exec_mem(size_t mem_size)
 {
     // Map the memory as executable
-    cb->mem_block = (uint8_t*)mmap(
-        &cb_init,
+    uint8_t* mem_block = (uint8_t*)mmap(
+        &alloc_exec_mem,
         mem_size,
         PROT_READ | PROT_WRITE | PROT_EXEC,
         MAP_PRIVATE | MAP_ANON,
@@ -162,12 +171,19 @@ void cb_init(codeblock_t* cb, size_t mem_size) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L171
     );
 
     // Check that the memory mapping was successful
-    if (cb->mem_block == MAP_FAILED)
+    if (mem_block == MAP_FAILED)
     {
         fprintf(stderr, "mmap call failed\n");
         exit(-1);
     }
 
+    return mem_block;
+}
+
+// Initialize a code block object
+void cb_init(codeblock_t* cb, uint8_t* mem_block, size_t mem_size)
+{
+    cb->mem_block = mem_block;
     cb->mem_size = mem_size;
     cb->write_pos = 0;
     cb->num_labels = 0;
@@ -801,6 +817,26 @@ void cb_write_jcc(codeblock_t* cb, const char* mnem, uint8_t op0, uint8_t op1, s https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L817
     cb_write_int(cb, 0, 32);
 }
 
+// Encode a relative jump to a pointer at a 32-bit offset (direct or conditional)
+void cb_write_jcc_ptr(codeblock_t* cb, const char* mnem, uint8_t op0, uint8_t op1, uint8_t* dst_ptr)
+{
+    //cb.writeASM(mnem, label);
+
+    // Write the opcode
+    cb_write_byte(cb, op0);
+    cb_write_byte(cb, op1);
+
+    // Pointer to the end of this jump
+    uint8_t* end_ptr = &cb->mem_block[cb->write_pos] + 4;
+
+    // Compute the jump offset
+    int64_t rel64 = (int64_t)(dst_ptr - end_ptr);
+    assert (rel64 >= -2147483648 && rel64 <= 2147483647);
+
+    // Write the relative 32-bit jump offset
+    cb_write_int(cb, (int32_t)rel64, 32);
+}
+
 // Encode a conditional move instruction
 void cb_write_cmov(codeblock_t* cb, const char* mnem, uint8_t opcode1, x86opnd_t dst, x86opnd_t src)
 {
@@ -1097,6 +1133,38 @@ void jpo (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jpo" , 0x0F, 0x https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L1133
 void js  (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "js"  , 0x0F, 0x88, label_idx); }
 void jz  (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jz"  , 0x0F, 0x84, label_idx); }
 
+/// jcc - Conditional relative jump to a pointer (32-bit offset)
+void ja_ptr  (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "ja"  , 0x0F, 0x87, ptr); }
+void jae_ptr (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jae" , 0x0F, 0x83, ptr); }
+void jb_ptr  (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jb"  , 0x0F, 0x82, ptr); }
+void jbe_ptr (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jbe" , 0x0F, 0x86, ptr); }
+void jc_ptr  (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jc"  , 0x0F, 0x82, ptr); }
+void je_ptr  (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "je"  , 0x0F, 0x84, ptr); }
+void jg_ptr  (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jg"  , 0x0F, 0x8F, ptr); }
+void jge_ptr (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jge" , 0x0F, 0x8D, ptr); }
+void jl_ptr  (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jl"  , 0x0F, 0x8C, ptr); }
+void jle_ptr (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jle" , 0x0F, 0x8E, ptr); }
+void jna_ptr (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jna" , 0x0F, 0x86, ptr); }
+void jnae_ptr(codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jnae", 0x0F, 0x82, ptr); }
+void jnb_ptr (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jnb" , 0x0F, 0x83, ptr); }
+void jnbe_ptr(codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jnbe", 0x0F, 0x87, ptr); }
+void jnc_ptr (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jnc" , 0x0F, 0x83, ptr); }
+void jne_ptr (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jne" , 0x0F, 0x85, ptr); }
+void jng_ptr (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jng" , 0x0F, 0x8E, ptr); }
+void jnge_ptr(codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jnge", 0x0F, 0x8C, ptr); }
+void jnl_ptr (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jnl" , 0x0F, 0x8D, ptr); }
+void jnle_ptr(codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jnle", 0x0F, 0x8F, ptr); }
+void jno_ptr (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jno" , 0x0F, 0x81, ptr); }
+void jnp_ptr (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jnp" , 0x0F, 0x8b, ptr); }
+void jns_ptr (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jns" , 0x0F, 0x89, ptr); }
+void jnz_ptr (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jnz" , 0x0F, 0x85, ptr); }
+void jo_ptr  (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jo"  , 0x0F, 0x80, ptr); }
+void jp_ptr  (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jp"  , 0x0F, 0x8A, ptr); }
+void jpe_ptr (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jpe" , 0x0F, 0x8A, ptr); }
+void jpo_ptr (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jpo" , 0x0F, 0x8B, ptr); }
+void js_ptr  (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "js"  , 0x0F, 0x88, ptr); }
+void jz_ptr  (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "jz"  , 0x0F, 0x84, ptr); }
+
 /// jmp - Direct relative jump to label
 void jmp(codeblock_t* cb, size_t label_idx)
 {
@@ -1119,19 +1187,6 @@ void jmp_rm(codeblock_t* cb, x86opnd_t opnd) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L1187
     cb_write_rm(cb, false, false, NO_OPND, opnd, 4, 1, 0xFF);
 }
 
-/*
-/// jmp - Jump with relative 8-bit offset
-void jmp8(CodeBlock cb, int8_t offset)
-{
-    /// Opcode for direct jump with relative 8-bit offset
-    const ubyte JMP_REL8_OPCODE = 0xEB;
-
-    cb.writeASM("jmp", ((offset > 0)? "+":"-") ~ to!string(offset));
-    cb.writeByte(JMP_REL8_OPCODE);
-    cb.writeByte(offset);
-}
-*/
-
 // jmp - Jump with relative 32-bit offset
 void jmp32(codeblock_t* cb, int32_t offset)
 {
@@ -1204,7 +1259,7 @@ void mov(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L1259
             0xC6, // opMemImm8
             0xFF, // opMemImmSml (not available)
             0xFF, // opMemImmLrg
-            0xFF,  // opExtImm
+            0xFF, // opExtImm
             dst,
             src
         );
@@ -1517,6 +1572,30 @@ void sub(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L1572
     );
 }
 
+/// test - Logical Compare
+void test(codeblock_t* cb, x86opnd_t rm_opnd, x86opnd_t imm_opnd)
+{
+    assert (rm_opnd.type == OPND_REG || rm_opnd.type == OPND_MEM);
+    assert (imm_opnd.type == OPND_IMM);
+    assert (imm_opnd.imm >= 0);
+    assert (unsig_imm_size(imm_opnd.unsig_imm) <= 32);
+    assert (unsig_imm_size(imm_opnd.unsig_imm) <= rm_opnd.num_bits);
+
+    // Use the smallest operand size possible
+    rm_opnd = resize_opnd(rm_opnd, unsig_imm_size(imm_opnd.unsig_imm));
+
+    if (rm_opnd.num_bits == 8)
+    {
+        cb_write_rm(cb, false, false, NO_OPND, rm_opnd, 0x00, 1, 0xF6);
+        cb_write_int(cb, imm_opnd.imm, rm_opnd.num_bits);
+    }
+    else
+    {
+        cb_write_rm(cb, rm_opnd.num_bits == 16, false, NO_OPND, rm_opnd, 0x00, 1, 0xF7);
+        cb_write_int(cb, imm_opnd.imm, rm_opnd.num_bits);
+    }
+}
+
 /// Undefined opcode
 void ud2(codeblock_t* cb)
 {
diff --git a/ujit_asm.h b/ujit_asm.h
index d594897fa0..707c56cb2a 100644
--- a/ujit_asm.h
+++ b/ujit_asm.h
@@ -219,7 +219,8 @@ x86opnd_t imm_opnd(int64_t val); https://github.com/ruby/ruby/blob/trunk/ujit_asm.h#L219
 x86opnd_t const_ptr_opnd(void* ptr);
 
 // Code block methods
-void cb_init(codeblock_t* cb, size_t mem_size);
+uint8_t* alloc_exec_mem(size_t mem_size);
+void cb_init(codeblock_t* cb, uint8_t* mem_block, size_t mem_size);
 void cb_align_pos(codeblock_t* cb, size_t multiple);
 void cb_set_pos(codeblock_t* cb, size_t pos);
 uint8_t* cb_get_ptr(codeblock_t* cb, size_t index);
@@ -289,7 +290,7 @@ void jnc(codeblock_t* cb, size_t label_idx); https://github.com/ruby/ruby/blob/trunk/ujit_asm.h#L290
 void jne(codeblock_t* cb, size_t label_idx);
 void jng(codeblock_t* cb, size_t label_idx);
 void jnge(codeblock_t* cb, size_t label_idx);
-//void jnl(codeblock_t* cb, size_t label_idx);
+void jnl(codeblock_t* cb, size_t label_idx);
 void jnle(codeblock_t* cb, size_t label_idx);
 void jno(codeblock_t* cb, size_t label_idx);
 void jnp(codeblock_t* cb, size_t label_idx);
@@ -301,6 +302,36 @@ void jpe(codeblock_t* cb, size_t label_idx); https://github.com/ruby/ruby/blob/trunk/ujit_asm.h#L302
 void jpo(codeblock_t* cb, size_t label_idx);
 void js(codeblock_t* cb, size_t label_idx);
 void jz(codeblock_t* cb, size_t label_idx);
+void ja_ptr(codeblock_t* cb, uint8_t* ptr);
+void jae_ptr(codeblock_t* cb (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]