From 1434a305c876680e05d5c6045ac3686a65a51235 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 12 Apr 2010 14:22:41 -0700 Subject: [PATCH] vm: add a new rc-absolute-1 relocation class to allow storing values in 8-bit operands, and optimized code sequences for inline caches using this --- basis/compiler/constants/constants.factor | 61 +++++++++++++---------- basis/cpu/ppc/bootstrap.factor | 24 +++++---- basis/cpu/x86/32/bootstrap.factor | 4 ++ basis/cpu/x86/64/bootstrap.factor | 5 ++ basis/cpu/x86/bootstrap.factor | 52 +++++++++---------- vm/dispatch.cpp | 4 +- vm/inline_cache.cpp | 3 +- vm/instruction_operands.cpp | 5 ++ vm/instruction_operands.hpp | 12 +++-- vm/jit.cpp | 6 --- vm/jit.hpp | 2 - 11 files changed, 97 insertions(+), 81 deletions(-) diff --git a/basis/compiler/constants/constants.factor b/basis/compiler/constants/constants.factor index ac0fcff0ff..2fec5ca190 100644 --- a/basis/compiler/constants/constants.factor +++ b/basis/compiler/constants/constants.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008, 2010 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: math kernel layouts system strings words quotations byte-arrays -alien arrays literals sequences ; +alien alien.syntax arrays literals sequences ; IN: compiler.constants ! These constants must match vm/memory.h @@ -40,32 +40,41 @@ CONSTANT: deck-bits 18 : segment-end-offset ( -- n ) 2 bootstrap-cells ; inline ! Relocation classes -CONSTANT: rc-absolute-cell 0 -CONSTANT: rc-absolute 1 -CONSTANT: rc-relative 2 -CONSTANT: rc-absolute-ppc-2/2 3 -CONSTANT: rc-absolute-ppc-2 4 -CONSTANT: rc-relative-ppc-2 5 -CONSTANT: rc-relative-ppc-3 6 -CONSTANT: rc-relative-arm-3 7 -CONSTANT: rc-indirect-arm 8 -CONSTANT: rc-indirect-arm-pc 9 -CONSTANT: rc-absolute-2 10 +C-ENUM: f + rc-absolute-cell + rc-absolute + rc-relative + rc-absolute-ppc-2/2 + rc-absolute-ppc-2 + rc-relative-ppc-2 + rc-relative-ppc-3 + rc-relative-arm-3 + rc-indirect-arm + rc-indirect-arm-pc + rc-absolute-2 + rc-absolute-1 ; ! Relocation types -CONSTANT: rt-dlsym 0 -CONSTANT: rt-entry-point 1 -CONSTANT: rt-entry-point-pic 2 -CONSTANT: rt-entry-point-pic-tail 3 -CONSTANT: rt-here 4 -CONSTANT: rt-this 5 -CONSTANT: rt-literal 6 -CONSTANT: rt-untagged 7 -CONSTANT: rt-megamorphic-cache-hits 8 -CONSTANT: rt-vm 9 -CONSTANT: rt-cards-offset 10 -CONSTANT: rt-decks-offset 11 -CONSTANT: rt-exception-handler 12 +C-ENUM: f + rt-dlsym + rt-entry-point + rt-entry-point-pic + rt-entry-point-pic-tail + rt-here + rt-this + rt-literal + rt-untagged + rt-megamorphic-cache-hits + rt-vm + rt-cards-offset + rt-decks-offset + rt-exception-handler ; : rc-absolute? ( n -- ? ) - ${ rc-absolute-ppc-2/2 rc-absolute-cell rc-absolute } member? ; + ${ + rc-absolute-ppc-2/2 + rc-absolute-cell + rc-absolute + rc-absolute-2 + rc-absolute-1 + } member? ; diff --git a/basis/cpu/ppc/bootstrap.factor b/basis/cpu/ppc/bootstrap.factor index f7a1917d0e..4df7a487d4 100644 --- a/basis/cpu/ppc/bootstrap.factor +++ b/basis/cpu/ppc/bootstrap.factor @@ -286,25 +286,19 @@ CONSTANT: nv-reg 17 4 ds-reg 0 LWZ rc-absolute-ppc-2 rt-untagged jit-rel ] pic-load jit-define -! Tag -: load-tag ( -- ) - 4 4 tag-mask get ANDI - 4 4 tag-bits get SLWI ; +[ 4 4 tag-mask get ANDI ] pic-tag jit-define -[ load-tag ] pic-tag jit-define - -! Tuple [ 3 4 MR - load-tag - 0 4 tuple type-number tag-fixnum CMPI + 4 4 tag-mask get ANDI + 0 4 tuple type-number CMPI [ BNE ] - [ 4 3 tuple type-number neg 4 + LWZ ] + [ 4 3 tuple-class-offset LWZ ] jit-conditional* ] pic-tuple jit-define [ - 0 4 0 CMPI rc-absolute-ppc-2 rt-literal jit-rel + 0 4 0 CMPI rc-absolute-ppc-2 rt-untagged jit-rel ] pic-check-tag jit-define [ @@ -342,6 +336,14 @@ CONSTANT: nv-reg 17 ! ! ! Megamorphic caches [ + ! class = ... + 3 4 MR + 4 4 tag-mask get ANDI + 4 4 tag-bits get SLWI + 0 4 tuple type-number tag-fixnum CMPI + [ BNE ] + [ 4 3 tuple-class-offset LWZ ] + jit-conditional* ! cache = ... 0 3 LOAD32 rc-absolute-ppc-2/2 rt-literal jit-rel ! key = hashcode(class) diff --git a/basis/cpu/x86/32/bootstrap.factor b/basis/cpu/x86/32/bootstrap.factor index 4eb8335b67..a52a3390ac 100644 --- a/basis/cpu/x86/32/bootstrap.factor +++ b/basis/cpu/x86/32/bootstrap.factor @@ -176,6 +176,10 @@ IN: bootstrap.x86 [ jit-jump-quot ] \ lazy-jit-compile define-combinator-primitive +[ + temp1 HEX: ffffffff CMP rc-absolute-cell rt-literal jit-rel +] pic-check-tuple jit-define + ! Inline cache miss entry points : jit-load-return-address ( -- ) pic-tail-reg ESP stack-frame-size bootstrap-cell - [+] MOV ; diff --git a/basis/cpu/x86/64/bootstrap.factor b/basis/cpu/x86/64/bootstrap.factor index 39046bce6a..393d1c9b8b 100644 --- a/basis/cpu/x86/64/bootstrap.factor +++ b/basis/cpu/x86/64/bootstrap.factor @@ -160,6 +160,11 @@ IN: bootstrap.x86 [ jit-jump-quot ] \ lazy-jit-compile define-combinator-primitive +[ + temp2 HEX: ffffffff MOV rc-absolute-cell rt-literal jit-rel + temp1 temp2 CMP +] pic-check-tuple jit-define + ! Inline cache miss entry points : jit-load-return-address ( -- ) RBX RSP stack-frame-size bootstrap-cell - [+] MOV ; diff --git a/basis/cpu/x86/bootstrap.factor b/basis/cpu/x86/bootstrap.factor index 7accc4b1cb..969c02c910 100644 --- a/basis/cpu/x86/bootstrap.factor +++ b/basis/cpu/x86/bootstrap.factor @@ -206,43 +206,37 @@ big-endian off ! Load a value from a stack position [ - temp1 ds-reg HEX: ffffffff [+] MOV rc-absolute rt-untagged jit-rel + temp1 ds-reg HEX: 7f [+] MOV rc-absolute-1 rt-untagged jit-rel ] pic-load jit-define -! Tag -: load-tag ( -- ) - temp1 tag-mask get AND - temp1 tag-bits get SHL ; +[ temp1 tag-mask get AND ] pic-tag jit-define -[ load-tag ] pic-tag jit-define - -! The 'make' trick lets us compute the jump distance for the -! conditional branches there - -! Tuple [ temp0 temp1 MOV - load-tag - temp1 tuple type-number tag-fixnum CMP + temp1 tag-mask get AND + temp1 tuple type-number CMP [ JNE ] - [ temp1 temp0 tuple type-number neg bootstrap-cell + [+] MOV ] + [ temp1 temp0 tuple-class-offset [+] MOV ] jit-conditional ] pic-tuple jit-define [ - temp1 HEX: ffffffff CMP rc-absolute rt-literal jit-rel + temp1 HEX: 7f CMP rc-absolute-1 rt-untagged jit-rel ] pic-check-tag jit-define -[ - temp2 HEX: ffffffff MOV rc-absolute-cell rt-literal jit-rel - temp1 temp2 CMP -] pic-check-tuple jit-define - [ 0 JE rc-relative rt-entry-point jit-rel ] pic-hit jit-define ! ! ! Megamorphic caches [ + ! class = ... + temp0 temp1 MOV + temp1 tag-mask get AND + temp1 tag-bits get SHL + temp1 tuple type-number tag-fixnum CMP + [ JNE ] + [ temp1 temp0 tuple-class-offset [+] MOV ] + jit-conditional ! cache = ... temp0 0 MOV rc-absolute-cell rt-literal jit-rel ! key = hashcode(class) @@ -256,14 +250,16 @@ big-endian off temp0 temp2 ADD ! if(get(cache) == class) temp0 [] temp1 CMP - bootstrap-cell 4 = 14 22 ? JNE ! Yuck! - ! megamorphic_cache_hits++ - temp1 0 MOV rc-absolute-cell rt-megamorphic-cache-hits jit-rel - temp1 [] 1 ADD - ! goto get(cache + bootstrap-cell) - temp0 temp0 bootstrap-cell [+] MOV - temp0 word-entry-point-offset [+] JMP - ! fall-through on miss + [ JNE ] + [ + ! megamorphic_cache_hits++ + temp1 0 MOV rc-absolute-cell rt-megamorphic-cache-hits jit-rel + temp1 [] 1 ADD + ! goto get(cache + bootstrap-cell) + temp0 temp0 bootstrap-cell [+] MOV + temp0 word-entry-point-offset [+] JMP + ! fall-through on miss + ] jit-conditional ] mega-lookup jit-define ! ! ! Sub-primitives diff --git a/vm/dispatch.cpp b/vm/dispatch.cpp index b0f9159da7..480da1fd03 100755 --- a/vm/dispatch.cpp +++ b/vm/dispatch.cpp @@ -148,8 +148,8 @@ void quotation_jit::emit_mega_cache_lookup(cell methods_, fixnum index, cell cac data_root methods(methods_,parent); data_root cache(cache_,parent); - /* Generate machine code to determine the object's class. */ - emit_class_lookup(index,PIC_TUPLE); + /* Load the object from the datastack. */ + emit_with_literal(parent->special_objects[PIC_LOAD],tag_fixnum(-index * sizeof(cell))); /* Do a cache lookup. */ emit_with_literal(parent->special_objects[MEGA_LOOKUP],cache.value()); diff --git a/vm/inline_cache.cpp b/vm/inline_cache.cpp index c8a1b22879..b7cd7630ac 100755 --- a/vm/inline_cache.cpp +++ b/vm/inline_cache.cpp @@ -89,7 +89,8 @@ void inline_cache_jit::compile_inline_cache(fixnum index, parent->update_pic_count(inline_cache_type); /* Generate machine code to determine the object's class. */ - emit_class_lookup(index,inline_cache_type); + emit_with_literal(parent->special_objects[PIC_LOAD],tag_fixnum(-index * sizeof(cell))); + emit(parent->special_objects[inline_cache_type]); /* Generate machine code to check, in turn, if the class is one of the cached entries. */ cell i; diff --git a/vm/instruction_operands.cpp b/vm/instruction_operands.cpp index 59dbf1ef8e..b11db279a5 100644 --- a/vm/instruction_operands.cpp +++ b/vm/instruction_operands.cpp @@ -49,6 +49,8 @@ fixnum instruction_operand::load_value(cell relative_to) return load_value_masked(rel_indirect_arm_mask,20,0) + relative_to + sizeof(cell); case RC_ABSOLUTE_2: return *(u16 *)(pointer - sizeof(u16)); + case RC_ABSOLUTE_1: + return *(u8 *)(pointer - sizeof(u8)); default: critical_error("Bad rel class",rel.rel_class()); return 0; @@ -124,6 +126,9 @@ void instruction_operand::store_value(fixnum absolute_value) case RC_ABSOLUTE_2: *(u16 *)(pointer - sizeof(u16)) = (u16)absolute_value; break; + case RC_ABSOLUTE_1: + *(u8 *)(pointer - sizeof(u8)) = (u8)absolute_value; + break; default: critical_error("Bad rel class",rel.rel_class()); break; diff --git a/vm/instruction_operands.hpp b/vm/instruction_operands.hpp index 66ffddc24e..5dda411c8b 100644 --- a/vm/instruction_operands.hpp +++ b/vm/instruction_operands.hpp @@ -33,11 +33,11 @@ enum relocation_type { }; enum relocation_class { - /* absolute address in a 64-bit location */ + /* absolute address in a pointer-width location */ RC_ABSOLUTE_CELL, - /* absolute address in a 32-bit location */ + /* absolute address in a 4 byte location */ RC_ABSOLUTE, - /* relative address in a 32-bit location */ + /* relative address in a 4 byte location */ RC_RELATIVE, /* absolute address in a PowerPC LIS/ORI sequence */ RC_ABSOLUTE_PPC_2_2, @@ -53,8 +53,10 @@ enum relocation_class { RC_INDIRECT_ARM, /* pointer to address in an ARM LDR/STR instruction offset by 8 bytes */ RC_INDIRECT_ARM_PC, - /* absolute address in a 16-bit location */ - RC_ABSOLUTE_2 + /* absolute address in a 2 byte location */ + RC_ABSOLUTE_2, + /* absolute address in a 1 byte location */ + RC_ABSOLUTE_1, }; static const cell rel_absolute_ppc_2_mask = 0xffff; diff --git a/vm/jit.cpp b/vm/jit.cpp index 8d2f5abb9a..3324cfb366 100644 --- a/vm/jit.cpp +++ b/vm/jit.cpp @@ -103,12 +103,6 @@ bool jit::emit_subprimitive(cell word_, bool tail_call_p, bool stack_frame_p) return false; } -void jit::emit_class_lookup(fixnum index, cell type) -{ - emit_with_literal(parent->special_objects[PIC_LOAD],tag_fixnum(-index * sizeof(cell))); - emit(parent->special_objects[type]); -} - /* Facility to convert compiled code offsets to quotation offsets. Call jit_compute_offset() with the compiled code offset, then emit code, and at the end jit->position is the quotation position. */ diff --git a/vm/jit.hpp b/vm/jit.hpp index a9716cab79..963115d6ab 100644 --- a/vm/jit.hpp +++ b/vm/jit.hpp @@ -47,8 +47,6 @@ struct jit { bool emit_subprimitive(cell word_, bool tail_call_p, bool stack_frame_p); - void emit_class_lookup(fixnum index, cell type); - fixnum get_position() { if(computing_offset_p)