Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Eliminate code-gen for huge code refs array.
  • Loading branch information
jnthn committed May 18, 2013
1 parent 996eca2 commit 594995c
Showing 1 changed file with 2 additions and 173 deletions.
175 changes: 2 additions & 173 deletions src/vm/jvm/QAST/Compiler.nqp
Expand Up @@ -2412,186 +2412,15 @@ class QAST::CompilerJAST {
# Emits the code-ref array construction.
method coderef_array() {
my $gcr := JAST::Method.new( :name('getCodeRefs'), :returns("[$TYPE_CR;"), :static(0) );

# Get method handle lookup object.
$gcr.add_local('mhl', $TYPE_MHL);
$gcr.append(JAST::Instruction.new( :op('invokestatic'),
$TYPE_MHS, 'lookup', $TYPE_MHL ));
$gcr.append(JAST::Instruction.new( :op('astore'), 'mhl' ));

# Everything is same type at the moment; construct MethodType.
$gcr.add_local('mt', $TYPE_MT);
$gcr.append(JAST::Instruction.new( :op('getstatic'),
'Ljava/lang/Void;', 'TYPE', $TYPE_CLASS ));
$gcr.append(JAST::PushCVal.new( :value($TYPE_TC) ));
$gcr.append(JAST::PushIndex.new( :value(3) ));
$gcr.append(JAST::Instruction.new( :op('anewarray'), $TYPE_CLASS ));
$gcr.append($DUP);
$gcr.append(JAST::PushIndex.new( :value(0) ));
$gcr.append(JAST::PushCVal.new( :value($TYPE_CR) ));
$gcr.append($AASTORE);
$gcr.append($DUP);
$gcr.append(JAST::PushIndex.new( :value(1) ));
$gcr.append(JAST::PushCVal.new( :value($TYPE_CSD) ));
$gcr.append($AASTORE);
$gcr.append($DUP);
$gcr.append(JAST::PushIndex.new( :value(2) ));
$gcr.append(JAST::PushCVal.new( :value("[$TYPE_OBJ") ));
$gcr.append($AASTORE);
$gcr.append(JAST::Instruction.new( :op('invokestatic'),
$TYPE_MT, 'methodType', $TYPE_MT, $TYPE_CLASS, $TYPE_CLASS, "[$TYPE_CLASS" ));
$gcr.append(JAST::Instruction.new( :op('astore'), 'mt' ));

# Create array.
$gcr.append(JAST::PushIndex.new( :value($!cur_idx) ));
$gcr.append(JAST::Instruction.new( :op('anewarray'), $TYPE_CR ));

# Add all the code-refs. We'll bunch them 1000 at a time in order
# to avoid blowing the JVM maximum method size.
my $crmeth_num := 0;
sub new_group() {
my $cra := JAST::Method.new( :name('getCodeRefs_' ~ $crmeth_num), :returns("V"), :static(0) );
$cra.add_argument('cra', "[$TYPE_CR");
$cra.add_argument('mhl', $TYPE_MHL);
$cra.add_argument('mt', $TYPE_MT);
$cra.append($ALOAD_1);
$*JCLASS.add_method($cra);

$gcr.append($DUP);
$gcr.append($ALOAD_0);
$gcr.append($SWAP);
$gcr.append(JAST::Instruction.new( :op('aload'), 'mhl' ));
$gcr.append(JAST::Instruction.new( :op('aload'), 'mt' ));
$gcr.append(JAST::Instruction.new( :op('invokevirtual'),
'L' ~ $*JCLASS.name ~ ';', 'getCodeRefs_' ~ $crmeth_num,
'Void', "[$TYPE_CR", $TYPE_MHL, $TYPE_MT ));

$crmeth_num++;
$cra
}
sub finish_group($cra) {
$cra.append($RETURN);
}
my $TYPE_STRARR := "[$TYPE_STR;";
my int $i := 0;
my $cra := new_group();
while $i < $!cur_idx {
$cra.append($DUP); # The target array
$cra.append(JAST::PushIndex.new( :value($i) )); # The array index
$cra.append(JAST::Instruction.new( :op('new'), $TYPE_CR ));
$cra.append($DUP);

# Compilation unit.
$cra.append($ALOAD_0);

# Method handle.
$cra.append(JAST::Instruction.new( :op('aload'), 'mhl' ));
$cra.append(JAST::PushCVal.new( :value('L' ~ $*JCLASS.name ~ ';') ));
$cra.append(JAST::PushSVal.new( :value(@!jastmeth_names[$i]) ));
$cra.append(JAST::Instruction.new( :op('aload'), 'mt' ));
$cra.append(JAST::Instruction.new( :op('invokevirtual'),
$TYPE_MHL, 'findVirtual', $TYPE_MH, $TYPE_CLASS, $TYPE_STR, $TYPE_MT ));
$cra.append($ALOAD_0);
$cra.append(JAST::Instruction.new( :op('invokevirtual'),
$TYPE_MH, 'bindTo', $TYPE_MH, $TYPE_OBJ ));

# Name and comp-unit unique ID.
$cra.append(JAST::PushSVal.new( :value(@!names[$i]) ));
$cra.append(JAST::PushSVal.new( :value(@!cuids[$i]) ));

for @!lexical_name_lists[$i] {
if $_ {
$cra.append(JAST::PushSVal.new( :value(nqp::join("\0", $_)) ));
}
else {
$cra.append($ACONST_NULL);
}
}

$cra.append(JAST::PushIndex.new( :value(+@!handlers[$i]) ));
$cra.append(JAST::Instruction.new( :op('anewarray'), "[J" ));
my $hidx := 0;
for @!handlers[$i] {
$cra.append($DUP);
$cra.append(JAST::PushIndex.new( :value($hidx++) ));
$cra.append(JAST::PushIndex.new( :value(nqp::elems($_)) ));
$cra.append(JAST::Instruction.new( :op('newarray'), "J" ));
my $idx := 0;
for $_ {
$cra.append($DUP);
$cra.append(JAST::PushIndex.new( :value($idx++) ));
$cra.append(JAST::PushIVal.new( :value($_) ));
$cra.append($LASTORE);
}
$cra.append($AASTORE);
}

$cra.append(JAST::Instruction.new( :op('invokespecial'),
$TYPE_CR, '<init>',
'Void', $TYPE_CU, $TYPE_MH, $TYPE_STR, $TYPE_STR,
$TYPE_STR, $TYPE_STR, $TYPE_STR, $TYPE_STR,
"[[J"));
$cra.append($AASTORE); # Push to the array
$i++;

if $i % 1000 == 0 {
finish_group($cra);
$cra := new_group();
}
}
finish_group($cra);

# Return the array. Add method to class.
$gcr.append($ACONST_NULL);
$gcr.append($ARETURN);
$*JCLASS.add_method($gcr);
}

# Emits the mappings of code refs to their outer code refs.
method outer_map_array() {
my $gom := JAST::Method.new( :name('getOuterMap'), :returns("[Integer;"), :static(0) );

# Create array.
$gom.append(JAST::PushIndex.new( :value(2 * @!outer_mappings) ));
$gom.append(JAST::Instruction.new( :op('newarray'), 'Integer' ));

# Add all the mappings, bunching them to avoid blowing JVM
# limits.
my $ommeth_num := 0;
sub new_group() {
my $oma := JAST::Method.new( :name('getOuterMap_' ~ $ommeth_num), :returns("V"), :static(1) );
$oma.add_argument('oma', '[I');
$oma.append($ALOAD_0);
$*JCLASS.add_method($oma);

$gom.append($DUP);
$gom.append(JAST::Instruction.new( :op('invokestatic'),
'L' ~ $*JCLASS.name ~ ';', 'getOuterMap_' ~ $ommeth_num,
'Void', '[I' ));

$ommeth_num++;
$oma
}
sub finish_group($oma) {
$oma.append($RETURN);
}
my int $i := 0;
my $oma := new_group();
for @!outer_mappings -> @m {
for @m {
$oma.append($DUP);
$oma.append(JAST::PushIndex.new( :value($i++) ));
$oma.append(JAST::PushIndex.new( :value($_) ));
$oma.append($IASTORE);
}

if $i % 1000 == 0 {
finish_group($oma);
$oma := new_group();
}
}
finish_group($oma);

# Return the array. Add method to class.
$gom.append($ACONST_NULL);
$gom.append($ARETURN);
$*JCLASS.add_method($gom);
}
Expand Down

0 comments on commit 594995c

Please sign in to comment.