File: CodeSequence.h

package info (click to toggle)
guavac 1.2-2
  • links: PTS
  • area: main
  • in suites: potato
  • size: 2,728 kB
  • ctags: 2,387
  • sloc: cpp: 20,367; yacc: 1,664; makefile: 504; lex: 348; ansic: 286; sh: 263
file content (110 lines) | stat: -rw-r--r-- 3,951 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Copyright (c) 1996  David Engberg  All rights reserved
// $Id: CodeSequence.h,v 1.4 1996/07/12 20:43:40 geppetto Exp $
#ifndef _CodeSequence_h
#define _CodeSequence_h
#pragma interface

#include "JavaCodeAttribute.h"
#include <deque>
#include <vector>
class ostream;

//
//  Class name : CCodeSequence
//  Description : This class encapsulates a sequence of Java instructions under
//    construction.
//
class CCodeSequence {
public:
  CCodeSequence();
  CCodeSequence(const CCodeSequence& source);
  ~CCodeSequence();
  CCodeSequence& operator=(const CCodeSequence& source);

  //
  //  Struct name : CInstruction
  //  Description : This structure represents one instruction in the Java byte
  //    code sequence, along with any arguments it has.  It is meant to be
  //    small (8 bytes) and dumb to make it fast to copy and modify.
  //    As such, it doesn't present a very OO interface.  This is an
  //    intentional optimization, the alternative would rely on huge,
  //    heap-allocated polymorphism, which would be serious overkill for
  //    the job.
  //
  struct Instruction {
    CJavaCodeAttribute::Opcode fOpcode;
    union {
      unsigned long u4;
      unsigned long l4;
      signed short s2;
      signed char s1;
      struct {
	unsigned short index : 16;
	unsigned char u1 : 8;
      } fIndexPair;
    } fArguments;
  };

  typedef vector<Instruction> InstructionList;
  typedef vector<unsigned long> OffsetList;

  unsigned long size() const { return fInstructions.size(); }
  Instruction& operator[](unsigned long index) { return fInstructions[index]; }
  const Instruction& operator[](unsigned long index) const 
     { return fInstructions[index]; }
  InstructionList::const_iterator GetInstructionsBegin() const;
  InstructionList::const_iterator GetInstructionsEnd() const;
  void Insert(unsigned long index, const Instruction& value);
  void Append(const Instruction& value, unsigned long lineNumber = 0);
  void Append(CJavaCodeAttribute::Opcode opcode, unsigned long lineNumber = 0);
  void Append(CJavaCodeAttribute::Opcode opcode, unsigned long u4,
	      unsigned long lineNumber);
  void Remove(unsigned long index);
  void Remove(unsigned long index, unsigned long count);
  unsigned long CreateBlockLabel();
  // unsigned long PeekNextBlockLabel() const;
  unsigned long LabelToInstruction(unsigned long blockLabelIndex) const;
  bool InstructionToLabel(unsigned long blockLabelIndex,
			  unsigned long& label) const;

  void PeepholeOptimize();
  void EliminateDeadCode(CJavaCodeAttribute& inCodeAttribute);
  void Finalize(CJavaCodeAttribute& intoCodeAttribute);

  void PrintShortDebug(ostream& toStream) const;

protected:
  unsigned long FinalizeInstruction(unsigned long instructionIndex,
				    const OffsetList& offsetLabels);
  unsigned long InstructionSize(unsigned long instructionIndex,
				unsigned long startingAtPosition) const;
  void EmitCode(unsigned long instruction, unsigned long instructionLocation,
		const OffsetList& offsetLabels,
		CJavaCodeAttribute& into) const;
  void AppendIndex(unsigned long instruction, CJavaCodeAttribute& onto) const;

  unsigned long MatchRange(const CJavaCodeAttribute::Opcode pattern[],
			   unsigned long patternLength,
			   unsigned long startingAt,
			   bool crossBasicBlocks = false);
  bool ReplaceIncrement(unsigned long startingAt);
  bool ReplaceZeroCompare(unsigned long startingAt);
  bool ReplaceBooleanBranch(unsigned long startingAt);
  bool ReplaceBranchToBranch(unsigned long startingAt);
  void CreateBlockIfConditional(CJavaCodeAttribute::Opcode instruction);

  void MarkReachableFrom(unsigned long index, bool reachable[]);

private:
  void PrintInstruction(const Instruction& instruction,
			ostream& toStream) const;

  InstructionList fInstructions;
  OffsetList fBasicBlockOffsets;
  unsigned long fLastBasicBlock;
  vector<unsigned long> fLineNumbers;
  OffsetList fLineBeginnings;
  unsigned long fLastLine;
};

#endif