Changes between Version 66 and Version 67 of squirrelfish

Show
Ignore:
Timestamp:
04/20/08 15:57:03 (19 months ago)
Author:
mjs@apple.com
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • squirrelfish

    v66 v67  
    1  
    2 == squirrelfish == 
    3  
    4 '''Major bits left over:''' 
    5   * Getters and Setters 
    6   * toString/valueOf 
    7      * It occurs to me that these could both (s|g)etters and toString could be "trivially" handled through the standard js -> native -> js call model -- at least in the short-medium term 
    8   * eval 
    9  
    10 '''List of tasks in no order -- pick one, tell everyone what you're doing: 
    11 ''' 
    12  
    13 '''Geoff is working on: 
    14 ''' 
    15  
    16 Re-entry into Machine::privateExecute: 
    17   * More indirection in the register file 
    18   * Don't overwrite nested register frames when re-entering global execution 
    19   * Provide API for re-entering non-global execution (i.e., function callbacks) 
    20  
    21 Arguments object 
    22  
    23 '''Cameron is working on: 
    24 ''' 
    25  
    26 Better code generation. We have been pondering whether to have a separate peephole optimization pass or to incorporate peephole optimization into code generation. Either way, we should look at some code generation algorithms based on tile matching. We also want to choose an approach that will be compatible with planned extensions, e.g. superinstructions. 
    27  
    28 Constant pool GC 
    29  
    30 '''Oliver is working on: 
    31 ''' 
    32  
    33 Making VM throw exceptions for invalid behaviour; Finally blocks. 
    34  
    35 '''Sam is working on (when he sees fit to do so): 
    36 ''' 
    37  
    38 '''Maciej is working on: 
    39 ''' 
    40  
    41 ScopeChain hackery 
    42  
    43 '''You could take something from Geoff, or make something up yourself, or do one of these:''' 
    44  
    45 Leftover opcodes: 
    46  
    47  * ArgumentsNode 
    48  * AssignErrorNode 
    49  * BreakpointCheckStatement 
    50  * ConstDeclNode 
    51  * ConstStatementNode 
    52  * ElementNode 
    53  * EvalFunctionCallNode 
    54  * ParameterNode 
    55  * PostDecConstNode 
    56  * PostfixErrorNode 
    57  * PreDecConstNode 
    58  * PrefixErrorNode 
    59  * PropertyNode 
    60  * ReadModifyConstNode 
    61  * ThrowNode 
    62  * TryNode 
    63  
    64 Where SunSpider tests currently fail codegen: 
    65  
    66  * 3d-cube: ungettableGetter 
    67  * 3d-morph: ungettableGetter 
    68  * 3d-raytrace: crash on failing toObject conversion for base of call (bad Args to constructor) 
    69  * access-binary-trees: crash on failing toObject conversion for base of call (bad Args to constructor) 
    70  * access-fannkuch: crash on failing toObject conversion for base of call (bad Args to constructor) 
    71  * access-nbody: new expr (NBodySystem) 
    72  * access-nsieve: ungettableGetter 
    73  * bitops-3bit-bits-in-byte: SUCCESS 
    74  * bitops-bits-in-byte: SUCCESS 
    75  * bitops-bitwise-and: SUCCESS 
    76  * bitops-nsieve-bits: ungettableGetter 
    77  * controlflow-recursive: ungettableGetter 
    78  * crypto-aes: crash on failing toObject conversion for base of call (bad Args to constructor) 
    79  * crypto-md5: ungettableGetter 
    80  * crypto-sha1: ungettableGetter 
    81  * date-format-tofte: local eval - eval(ia[ij] + "()") 
    82  * date-format-xparb: bracket call - this[func]() 
    83  * math-cordic: ungettableGetter 
    84  * math-partial-sums: crash on failing toObject conversion for base of call (bad Args to constructor) 
    85  * math-spectral-norm: ungettableGetter 
    86  * regexp-dna: regexp literal 
    87  * string-base64: crash on failing toObject conversion for base of call (bad Args to constructor) 
    88  * string-fasta: crash on failing toObject conversion for base of call (bad Args to constructor) 
    89  * string-tagcloud: trying to get from a base register containing 0x0 (bad codegen?) 
    90  * string-unpack-code: crash on failing toObject conversion for base of call (bad Args to constructor) 
    91  * string-validate-input: regexp literal 
    92  
    93 Harness failures: 
    94  
    95  * sunspider-analyze-results: KJS::resolve SHOULD NEVER BE REACHED 
    96  * sunspider-compare-results: SUCCESS (but not running yet) 
    97  * sunspider-standalone-compare: KJS::resolve SHOULD NEVER BE REACHED 
    98  * sunspider-standalone-driver: new expr (invoking Array constructor) 
    99  
    100 Optimize dynamic scopes that aren't closures not to save the environment on return 
    101  
    102 Statically detect presence of "with" and/or "catch" in the parser. 
    103  
    104 Evaluation of a script is supposed to produce a value. This requires storing the value of the last value-producing statement to execute. We need to detect the last top-level value-producing statement in a program, and save its value. Basically, that just means passing an explicit "dst" register to its emitCode function. 
    105  
    106 Make const work -- const info has to go in the symbol table, so writes to const vars can turn to no-ops at compile time. 
    107  
    108 Recover lost optimizations: 
    109  
    110 {{{ 
    111 optimized multiscope access 
    112 optimized access to global built-ins (http://trac.webkit.org/projects/webkit/changeset/31226) 
    113 static type inference of things like "numeric less than" and "string add" 
    114  
    115 // WARNING: If code generation wants to optimize resolves to parent scopes, 
    116 // it needs to be aware that, for functions that require activations, 
    117 // the scope chain is off by one, since the activation hasn't been pushed yet. 
    118 }}} 
    119  
    120 return inside with needs to pop scopes 
    121  
    122 Is it safe for Lists to store a direct pointer to the register file? What if the register file reallocates? 
    123  
    124 Verify that current function gets marked by virtue of being in the register file 
    125  
    126 Change conservative mark of register file to exact mark -- use zero fill plus type tagging to know whether to mark a register 
    127  
    128 Must mark all scope chains in all active scopes -- can do this by walking up the scopeChain pointers in the register file 
    129  
    130 automatic conversion of "this" to global object doesn't work. 
    131  
    132 phase out implementsCall in favor of all clients using an inline function that calls getCallData. 
    133  
    134 Phase out implementsConstruct in favor of all clients using an inline function that calls getContructData. 
    135  
    136 For memory's sake, functions should probably shrink the register file when they return, but doing so causes a minor performance regression. 
    137  
    138 Turn built-in object construct functions non-virtual, since their callers inside the engine know their types. 
    139  
    140 Pointers to registers and labels become invalid if the register or label vector resizes. 
    141  
    142 Mark constant pools for global and eval code 
    143  
    144 Avoid copying the register file when adding globals by keeping spare capacity at the beginning of the register file, just like at the end. 
    145  
    146 GC mark for possibly uninitialized register file 
    147  
    148 Add relevant files to AllInOneFile.cpp. 
    149  
    150 remove irrelevent files 
    151  
    152 replace resolve_base_and_func: 
    153     - statically detect functions that use "this", and emit an "op_fix_this" instruction for them that does the isActivationObject check. normal function calls don't need to do it. 
    154     - for built-in functions, have a "thisObject" accessor on List, which lazily fixes up "this", or just fix up "this" in the native function invocation code, since most native functions use "this". 
    155     - remove resolve_base_and_func, and use resolve_base_and_value in its place 
    156  
    157 If a nested program overwrites the global slot holding a currently executing function, the function won't be marked during GC 
    158  
    159 What things should go in dedicated local variables? CodeBlock::jsValues? CodeBlock::identifiers? 
    160  
    161 VarStatementNode should just be nixed in favor of AssignmentNode. 
    162  
    163 Remove ::execute, ::evaluate, ::optimizeVariableAccess 
    164  
    165  
    166 Future optimizations: 
    167  
    168 Find a way to put pre-capacity at the beginning of the register file, so we can add new global symbols without having to move or copy anything. 
    169  
    170 Use RefPtr to indicate use of register -- moves to un-refed registers should be stripped or consolidated to other instructions. 
    171     - i++ => ++i 
    172     - less, jtrue => jless 
    173  
    174 optimize out redundant initializations of vars -- often, the var initialization will be dead code. any read of variable before init can statically become "load undefined". 
    175  
    176  
    177     a single run of SunSpider performs 1,191,803 var initializations 
    178  
    179     -1 means "never happend" 
    180      
    181     var buckets: [846461] [40445] [350197] [9412] [7531] [50] [9] [178] [35000] [3] [1022] [3] [4499] [-1] [1353] [-1] [-1] [1851] [-1] [0] [-1] [0] [-1] [0] [-1] [0] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1]  
    182  
    183     fun buckets: [1297008] [7] [3] [2] [1] [0] [-1] [0] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [0] [-1] [1] [-1] [-1] [0] [-1] [0] [-1] [-1] [-1] [-1] [-1] [999] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] ] 
    184  
    185 for resolve-evaluate-put, we can have a { DontCare, Clean, Dirty } switch -- get slot and if DontCare, set clean, evaluate, set slot if clean 
    186  
    187 instead of branching to see if you've emitted code, just start out with a stub that does that emitting when invoked. 
    188  
    189 single, shared constant pool 
    190  
    191 At least for loops with fewer iterations it would probably be a win to duplicate the loop condition at the start and end of the loop 
    192  
    193 Perhaps we should have a distinguished "condition code" register for expressions in a boolean context. For relational and logical operators we can output directly to the condition code register, for other opcodes you get an extra instruction. Jump instructions can read implicitly from the condition code. That avoids the less writing to r0, it just puts a bool in the condition code register. 
    194  
    195 Can't you just make all opcodes have variants that use constant table operands directly? 
    196  
    197 A named function expression can just enter its name into the symbol table instead of adding an object to the scope chain. 
    198  
    199 Shrink instructions -- usually, don't need a whole word to store int values. Perhaps use tagging of opcodes to encode the first operand. Special work-around instructions when whole words are needed 
    200  
    201 GCC is crazy: 
    202  
    203 {{{ 
    204 For the program 
    205  
    206 for (var i = 0; i < 100000000; ++i) 
    207     ; 
    208  
    209 at r31276 of the squirrelfish branch, adding the line 
    210  
    211 Machine.cpp:354         scopeChain = new (&returnInfo[6]) ScopeChain(function->scope()); // scope chain for this activation 
    212  
    213 causes a ~25% slowdown 
    214  
    215 We should write a reduction of this issue for the compiler team, and see what they have to say 
    216 }}} 
    217  
    218  
    219  
    220 {{{ 
    221 Revision 31432 was a 1.4% performance regression because it moved the register vector from a 
    222 local to a parameter. Making the register vector a data member has the same effect. WTF? 
    223 }}} 
    224  
    225 {{{ 
    226 Exception handling throw logic has to pass vPC to a function, and assign the result to vPC, eg. 
    227   if (!(vPC = throwException(codeBlock, k, scopeChain, registers, r, vPC))) 
    228 But this causes a 25% regression on the above empty-for-loop test, despite never being hit.   
    229 To avoid this we need to do: 
    230 void* throwTarget; 
    231 ... 
    232 void Machine::privateExecute(..) 
    233 { 
    234     ... 
    235     // in address table initialiser 
    236     throwTarget = &&gcc_dependency_hack; 
    237     ... 
    238     BEGIN_OPCODE(op_throw) { 
    239         ... 
    240         if (!(exceptionTarget = throwException(codeBlock, k, scopeChain, registers, r, vPC))) { ... } 
    241         ... 
    242         goto *throwTarget; 
    243     } 
    244     gcc_dependency_hack: 
    245     { 
    246         vPC = exceptionTarget; 
    247         NEXT_OPCODE; 
    248     } 
    249 } 
    250  
    251 Without this _indirect_ goto we get a 25% regression, if we use a direct goto we still get an 18% regression. 
    252  
    253 }}} 
     1see SquirrelFish