CbCによるPerl6処理系

清水隆博 並列信頼研

研究目的

研究目的

Continuation Based C (CbC)

Continuation Based C (CbC)

__code cg1(TEST testin){
    TEST testout;
    testout.number = testin.number + 1;
    testout.string = "Hello";
    goto cg2(testout);
}

__code cg2(TEST testin){
    printf("number = %d\t string= %s\n",testin.number,testin.string);
}

int main(){
    TEST test = {0,0};
    goto cg1(test);
}

スクリプト言語処理系

Rakudo

MoarVM

MoarVMのバイトコード

add_i loc_3_int, loc_0_int, loc_1_int 
set loc_2_obj, loc_3_obj

MoarVMのバイトコード

sub test_func(int $left, int $right){
    my int $sum := $left + $right;
    ++$sum;
    return $sum;
}

my $arg1 := 1;
my $arg2 := 8;

say(test_func($arg1,$arg2));

MoarVMのバイトコード

MoarVMのバイトコードインタプリタ

MVM_interp_runの内部処理

MoarVMのバイトコードインタプリタ

DISPATCH(NEXT_OP) {
    OP(const_i64):
        GET_REG(cur_op, 0).i64 = MVM_BC_get_I64(cur_op, 2);
        cur_op += 10;
        goto NEXT;
}

MVM_interp_runで使用されているマクロ

DISPATCH(NEXT_OP) {
    OP(const_i64):
 #define OP(name) OP_ ## name
    OP_const_i16:
    #OP_const_i16

MVM_interp_runで使用されているマクロ

    OP(const_i64):
        GET_REG(cur_op, 0).i64 = MVM_BC_get_I64(cur_op, 2);
        cur_op += 10;
        goto NEXT;

MVM_interp_runで使用されているマクロ

    OP(const_i64):
        GET_REG(cur_op, 0).i64 = MVM_BC_get_I64(cur_op, 2);
        cur_op += 10;
        goto NEXT;
#define NEXT_OP (op = *(MVMuint16 *)(cur_op), cur_op += 2, op)
#define NEXT *LABELS[NEXT_OP]

MVM_interp_runのラベルテーブル

static const void * const LABELS[] = {
    &&OP_no_op,
    &&OP_const_i8,
    &&OP_const_i16,
    &&OP_const_i32,
    &&OP_const_i64,
    &&OP_const_n32,
    &&OP_const_n64,
    &&OP_const_s,
    &&OP_set,
    &&OP_extend_u8,
    &&OP_extend_u16,
    &&OP_extend_u32,
    &&OP_extend_i8,
    &&OP_extend_i16,

MVM_interp_run

CbCでの変換

CbCMoarVMのバイトコードディスパッチ

__code cbc_next(INTERP i){
    __code (*c)(INTERP)
    c = CODES[(i->op = *(MVMuint16 *)(i->cur_op), i->cur_op += 2, i->op)]; // c = NEXT(i)
    goto c(i);
}

__code cbc_const_i64(INTERP i){
    GET_REG(i->cur_op, 0,i).i64 = MVM_BC_get_I64(i->cur_op, 2);
    i->cur_op += 10;
    goto cbc_next(i);
}

CodeGearの入出力インターフェイス

CodeGearの入出力インターフェイス

typedef struct interp {
    MVMuint16 op;
    MVMuint8 *cur_op;
    MVMuint8 *bytecode_start;
    MVMRegister *reg_base;
     /* Points to the current compilation unit
         . */
    MVMCompUnit *cu;
     /* The current call site we’re
         constructing. */
    MVMCallsite *cur_callsite;
    MVMThreadContext *tc;
 } INTER,*INTERP;

CbCMoarVMのCodeGearテーブル

__code (* CODES[])(INTERP) = {
  cbc_no_op,
  cbc_const_i8,
  cbc_const_i16,
  cbc_const_i32,
  cbc_const_i64,
  cbc_const_n32,
  cbc_const_n64,
  cbc_const_s,
  cbc_set,
  cbc_extend_u8,
  cbc_extend_u16,

CbCMoarVMの状態遷移

MoarVMとCbCMoarVMのトレース

Breakpoint 1, dummy () at src/core/interp.c:46
46	}
#1  0x00007ffff75689da in MVM_interp_run (tc=0x604a20,
    initial_invoke=0x7ffff76c7168 <toplevel_initial_invoke>, invoke_data=0x67ff10)
    at src/core/interp.c:1169
1169	                goto NEXT;
$2 = 162
Breakpoint 2, cbc_next (i=0x7fffffffdc30) at src/core/cbc-interp.cbc:61
61	    goto NEXT(i);
$1 = (void (*)(INTERP)) 0x7ffff7566f53 <cbc_takeclosure>
$2 = 162

MoarVMのデバッグ

25 : 25 : cbc_unless_i
247 : 247 : cbc_null
54 : 54 : cbc_return_o
140 : 140 : cbc_checkarity
558 : 558 : cbc_paramnamesused
159 : 159 : cbc_getcode
391 : 391 : cbc_decont
127 : 127 : cbc_prepargs
*139 : 162
cbc_invoke_o:cbc_takeclosure

現在のCbCMoarVM

現在のCbCMoarVM

#!/bin/sh
exec /mnt/dalmore-home/one/src/Perl6/Optimize/llvm/build_perl6/bin/moar --cbc \
     --libpath=/mnt/dalmore-home/one/src/Perl6/Optimize/llvm/build_perl6/share/nqp/lib \
     /mnt/dalmore-home/one/src/Perl6/Optimize/llvm/build_perl6/share/nqp/lib/nqp.moarvm "$@"

CbCMoarVMと通常のMoarVMの比較

フィボナッチの例題

#! nqp

sub fib($n) {
    $n < 2 ?? $n !! fib($n-1) + fib($n - 2);
}

my $N := 30;
my $z  := fib($N);
say("fib($N) = " ~ fib($N));
[単位 sec]
MoarVM 1.379 1.350 1.346
CbCMoarVM 1.636 1.804 1.787

単純ループ

#! nqp

my $count := 100_000_000;

my $i := 0;

while ++$i <= $count {
}
[単位 sec]
MoarVM 7.499 7.844 7.822
CbCMoarVM 6.135 6.362 6.074

CbCMoarVMの利点

CbCMoarVMの欠点

まとめ