~ubuntu-branches/debian/squeeze/erlang/squeeze

« back to all changes in this revision

Viewing changes to lib/hipe/rtl/hipe_rtl_gctests.erl

  • Committer: Bazaar Package Importer
  • Author(s): Erlang Packagers, Sergei Golovan
  • Date: 2006-12-03 17:07:44 UTC
  • mfrom: (2.1.11 feisty)
  • Revision ID: james.westby@ubuntu.com-20061203170744-rghjwupacqlzs6kv
Tags: 1:11.b.2-4
[ Sergei Golovan ]
Fixed erlang-base and erlang-base-hipe prerm scripts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
%%% -*- erlang-indent-level: 2 -*-
2
 
%%% $Id$
3
 
%%%
4
 
%%% Expand virtual gc tests to actual code.
5
 
 
6
 
-module(hipe_rtl_gctests).
7
 
-export([expand/1]).
8
 
 
9
 
expand(CFG) ->
10
 
   {LowLbl, HighLbl} = hipe_rtl_cfg:label_range(CFG),
11
 
   hipe_gensym:set_label(rtl,HighLbl),
12
 
   {LowVar, HighVar} = hipe_rtl_cfg:var_range(CFG),
13
 
   hipe_gensym:set_var(rtl,HighVar),
14
 
   Labels = hipe_rtl_cfg:labels(CFG),
15
 
   CFG1 = expand_gctests(Labels, CFG),
16
 
   CFG2 = hipe_rtl_cfg:label_range_update(CFG1, {LowLbl, hipe_gensym:get_label(rtl)}),
17
 
   hipe_rtl_cfg:var_range_update(CFG2, {LowVar, hipe_gensym:get_var(rtl)}).
18
 
 
19
 
expand_gctests([], CFG) ->
20
 
   CFG;
21
 
expand_gctests([L|Ls], CFG) ->
22
 
   BB = hipe_rtl_cfg:bb(CFG, L),
23
 
   Code = hipe_bb:code(BB),
24
 
   {NewCode, CFG0} = expand_gc(Code, CFG),
25
 
   CFG1 = hipe_rtl_cfg:bb_update(CFG0, L, hipe_bb:code_update(BB, NewCode)),
26
 
   expand_gctests(Ls, CFG1).
27
 
 
28
 
expand_gc([], CFG) ->
29
 
  {[], CFG};
30
 
expand_gc([I|Is], CFG) ->
31
 
  {CodeRest, CFG0} = expand_gc(Is, CFG),
32
 
  case hipe_rtl:type(I) of
33
 
    gctest ->  %% Two new blocks, The rest of this one, and one for the gc
34
 
      %% One
35
 
      ContLabel = hipe_rtl:label_name(hipe_rtl:mk_new_label()),
36
 
      CFG1 = hipe_rtl_cfg:bb_add(CFG0, ContLabel, hipe_bb:mk_bb(CodeRest)),
37
 
      %% Two
38
 
      %% Note: the pointer arithmetic is done in bytes,
39
 
      %% but the gc parameter is in words (tagged as fixnum).
40
 
      WordsNeeded = hipe_rtl:gctest_words(I),
41
 
      Tmp = hipe_rtl:mk_new_reg(),
42
 
      {GetHPInsn, HP, _PutHPInsn} = hipe_rtl_arch:heap_pointer(),
43
 
      H_LIMIT = hipe_rtl:mk_reg(hipe_rtl_arch:heap_limit_reg()),
44
 
      GCLabel = hipe_rtl:label_name(hipe_rtl:mk_new_label()),    
45
 
   
46
 
      case hipe_rtl:is_reg(WordsNeeded) of
47
 
        
48
 
        true -> %Creates a gctest for a number of words known at runtime
49
 
          HPAmount = hipe_rtl:mk_new_reg(),
50
 
          GCAmount = hipe_rtl:mk_new_var(),
51
 
          Code = [hipe_rtl:mk_alu(HPAmount, WordsNeeded, sll, hipe_rtl:mk_imm(2)),
52
 
                  hipe_rtl:mk_alu(Tmp, H_LIMIT, 'sub', HP),
53
 
                  hipe_rtl:mk_alu(GCAmount, WordsNeeded, sll, hipe_rtl:mk_imm(4)),
54
 
                  hipe_rtl:mk_alu(GCAmount, GCAmount, 'add', hipe_rtl:mk_imm(15)), 
55
 
                  hipe_rtl:mk_branch(Tmp, 'lt', HPAmount, GCLabel, ContLabel, 0.01)];
56
 
        false -> %Creates a gctest for a fixed number of words
57
 
          GCAmount = hipe_rtl:mk_imm(hipe_tagscheme:mk_fixnum(WordsNeeded)),
58
 
          HPAmount = hipe_rtl:mk_imm(WordsNeeded*4),
59
 
          %% Le grande finale
60
 
          %% Do the GC overflow test. In the old version,
61
 
          %%    if( (Tmp = HP+HPAmount) >= H_LIMIT ) goto GCLabel,
62
 
          %% Tmp could wrap around. The new version below should be safe.
63
 
          Code = [hipe_rtl:mk_alu(Tmp, H_LIMIT, 'sub', HP),
64
 
                  hipe_rtl:mk_branch(Tmp, 'lt', HPAmount, GCLabel, ContLabel, 0.01)]
65
 
      end,
66
 
      GCCode = [hipe_rtl:mk_call([], gc_1, [GCAmount], c, ContLabel, [])],
67
 
      CFG2 = hipe_rtl_cfg:bb_add(CFG1, GCLabel, hipe_bb:mk_bb(GCCode)),
68
 
 
69
 
      {[GetHPInsn | Code], CFG2};
70
 
    _ ->
71
 
      {[I|CodeRest], CFG0}
72
 
  end.