зеркало из https://github.com/mozilla/gecko-dev.git
166 строки
7.7 KiB
C++
166 строки
7.7 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is mozilla.org code.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
*/
|
|
#ifndef BYTECODETRANSLATOR_H
|
|
#define BYTECODETRANSLATOR_H
|
|
|
|
#include "BytecodeGraph.h"
|
|
|
|
class BytecodeTranslator: public TranslationCommonEnv
|
|
{
|
|
// Helper for translating a BytecodeBlock
|
|
class BlockTranslator
|
|
{
|
|
const BytecodeTranslator &bt; // Backpointer to the current BytecodeTranslator
|
|
Pool &envPool; // The pool for allocating translation environment parts (disappears after primitives are generated)
|
|
Pool &primitivePool; // The pool for allocating new parts of the primitive graph
|
|
ClassFileSummary &classFileSummary; // The BytecodeGraph's ClassFileSummary
|
|
TranslationEnv *translationEnv; // The current state of local and stack variables; never nil
|
|
BytecodeBlock █ // The block which we're currently translating
|
|
ControlNode *cn; // The control node currently being generated or nil if we are done
|
|
|
|
public:
|
|
BlockTranslator(const BytecodeTranslator &bt, TranslationEnv &env, BytecodeBlock &block, ControlNode *cn);
|
|
|
|
TranslationEnv &getEnv() const {return *translationEnv;}
|
|
void setEnv(TranslationEnv &env) {translationEnv = &env;}
|
|
ControlGraph &getControlGraph() const {return bt.controlGraph;}
|
|
|
|
private:
|
|
void appendControlNode(ControlEdge &e);
|
|
void genException(ControlKind ck, Primitive *tryPrimitive, const Class &exceptionClass, bool canOwnEnv) const;
|
|
void genThrowCommon(const VariableOrConstant &exception, const Class &exceptionClass, bool canOwnEnv);
|
|
void genSimpleThrow(cobj exceptionObject, bool canOwnEnv);
|
|
void genPossibleThrow(Primitive &prim, const Class &exceptionClass);
|
|
void createBasicBlock(BasicBlock &successor);
|
|
void createIf(Condition2 cond2, bool reverseCond2,
|
|
VariableOrConstant &c, BasicBlock &successorFalse,
|
|
BasicBlock &successorTrue, Uint32 bci);
|
|
void createContinuedIf(Condition2 cond2, bool reverseCond2,
|
|
VariableOrConstant &c,
|
|
BasicBlock &successorTrue, Uint32 bci);
|
|
void genNullGuard(const VariableOrConstant &arg, Uint32 bci);
|
|
void genTableSwitch(const bytecode *bc, Uint32 bci);
|
|
void genLookupSwitch(const bytecode *bc, Uint32 bci);
|
|
void genReadObjectType(const VariableOrConstant &object,
|
|
VariableOrConstant &type, Uint32 bci) const;
|
|
void genGetStatic(ConstantPoolIndex cpi, Uint32 bci) const;
|
|
void genPutStatic(ConstantPoolIndex cpi, Uint32 bci) const;
|
|
void genGetField(ConstantPoolIndex cpi, Uint32 bci);
|
|
void genPutField(ConstantPoolIndex cpi, Uint32 bci);
|
|
void genReadArrayLength(const VariableOrConstant &arrayAddr, VariableOrConstant &arrayLength, Uint32 bci);
|
|
void genArrayCastGuard(const VariableOrConstant &array, const VariableOrConstant &object);
|
|
void genArrayEltAccess(TypeKind tk, bool write, Uint32 bci);
|
|
void genCheckInterfaceAssignability(VariableOrConstant &type, const Type &targetInterface, VariableOrConstant *results, Uint32 bci) const;
|
|
void genCheckCastNonNull(const Type &t, const VariableOrConstant &arg, Uint32 bci);
|
|
void genCheckCast(ConstantPoolIndex cpi, const VariableOrConstant &arg, Uint32 bci);
|
|
void genInstanceOfNonNull(const Type &t, const VariableOrConstant &arg, VariableOrConstant &result, ControlNode *cnFalse, Uint32 bci);
|
|
void genInstanceOf(ConstantPoolIndex cpi, const VariableOrConstant &arg, VariableOrConstant &result, Uint32 bci);
|
|
void genNewCommon(const SysCall &sysCall, uint nArgs, const VariableOrConstant *args, Uint32 bci);
|
|
void genTempArrayOfDim(Int32 dim, Uint32 bci);
|
|
Primitive &genMonitor(PrimitiveOperation op, const VariableOrConstant &arg, Uint32 bci) const;
|
|
void genThrow(const VariableOrConstant &exception);
|
|
void genReceiverNullCheck(const Signature &sig, VariableOrConstant &receiver, Uint32 bci);
|
|
void genVirtualLookup(const VariableOrConstant &receiver, Uint32 vIndex, VariableOrConstant &functionAddr, Uint32 bci) const;
|
|
void genInterfaceLookup(const VariableOrConstant &receiver, Uint32 interfaceNumber, Uint32 vIndex, const Method *method,
|
|
VariableOrConstant &functionAddr, Uint32 bci) const;
|
|
void genInvoke(bytecode opcode, ConstantPoolIndex cpi, uint nArgs, Uint32 bci);
|
|
public:
|
|
void genLivePrimitives();
|
|
void genCycleHeader();
|
|
|
|
#ifdef DEBUG
|
|
bool translatorDone() const {return !cn;}
|
|
#endif
|
|
};
|
|
|
|
BytecodeGraph &bytecodeGraph; // The BytecodeGraph from which we're translating
|
|
ControlGraph &controlGraph; // The primitive graph to which we're translating
|
|
|
|
BytecodeTranslator(BytecodeGraph &bytecodeGraph, ControlGraph &controlGraph, Pool &envPool);
|
|
|
|
static void normalizeEnv(TranslationEnv &env, BasicBlock::StackNormalization stackNormalization);
|
|
static void linkPredecessor(BasicBlock &block, ControlEdge &controlEdge, TranslationEnv &predecessorEnv, bool canOwnEnv);
|
|
static void finishedOnePredecessor(BasicBlock &block);
|
|
static void finishedOutgoingEdges(BasicBlock &block);
|
|
ControlNode *createControlNode(BasicBlock &block, bool mergeBlock) const;
|
|
|
|
void genPrimitives(EndBlock &block) const;
|
|
void genPrimitives(CatchBlock &block) const;
|
|
void genPrimitives(BytecodeBlock &block) const;
|
|
void genRawPrimitiveGraph() const;
|
|
void addSynchronization(VariableOrConstant &syncHolder, Uint32 bci) const;
|
|
public:
|
|
static ControlGraph *genPrimitiveGraph(BytecodeGraph &bytecodeGraph, Pool &primitivePool, Pool &tempPool);
|
|
|
|
friend class BytecodeTranslator::BlockTranslator; // BlockTranslator calls the private methods above
|
|
};
|
|
|
|
|
|
// --- INLINES ----------------------------------------------------------------
|
|
|
|
|
|
//
|
|
// Initialize a translator that will translate a single BytecodeBlock.
|
|
//
|
|
inline BytecodeTranslator::BlockTranslator::BlockTranslator(const BytecodeTranslator &bt, TranslationEnv &env, BytecodeBlock &block,
|
|
ControlNode *cn):
|
|
bt(bt),
|
|
envPool(bt.envPool),
|
|
primitivePool(bt.primitivePool),
|
|
classFileSummary(bt.bytecodeGraph.classFileSummary),
|
|
translationEnv(&env),
|
|
block(block),
|
|
cn(cn)
|
|
{}
|
|
|
|
|
|
//
|
|
// Initialize a translator that will construct the control graph out of the given
|
|
// bytecode graph.
|
|
// envPool will be used for temporary allocation of TranslationEnvs and the data
|
|
// structures they contain; all of these can be deallocated when the BytecodeTranslator
|
|
// is done.
|
|
//
|
|
inline BytecodeTranslator::BytecodeTranslator(BytecodeGraph &bytecodeGraph, ControlGraph &controlGraph, Pool &envPool):
|
|
TranslationCommonEnv(envPool, controlGraph.pool, bytecodeGraph.nLocals, bytecodeGraph.stackSize),
|
|
bytecodeGraph(bytecodeGraph),
|
|
controlGraph(controlGraph)
|
|
{}
|
|
|
|
|
|
//
|
|
// Take note that we just completely generated code for a BasicBlock b
|
|
// that is one of the predecessors of BasicBlock block. If b jumps to
|
|
// BasicBlock block, then BasicBlock block's environment should have been
|
|
// adjusted accordingly by now.
|
|
// This method lets BasicBlock block keep track of how many other
|
|
// BasicBlocks remain that can jump to BasicBlock block and whose
|
|
// environments have not yet been merged into BasicBlock block.
|
|
//
|
|
inline void BytecodeTranslator::finishedOnePredecessor(BasicBlock &block)
|
|
{
|
|
assert(block.getNSeenPredecessors() != block.nPredecessors);
|
|
block.getNSeenPredecessors()++;
|
|
}
|
|
|
|
#endif
|