blob: a7a4c52851002d3b91347ce90997943cd1d362ae [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Intel, Mikhail Y. Fursov
*/
#ifndef _IA32_GC_MAP_H_
#define _IA32_GC_MAP_H_
#include "Stl.h"
#include "MemoryManager.h"
#include "Ia32IRManager.h"
#include "Ia32StackInfo.h"
#include "Ia32BCMap.h"
#ifdef _DEBUG
#define GCMAP_TRACK_IDS
#endif
namespace Jitrino
{
namespace Ia32 {
class GCSafePointsInfo;
class GCSafePoint;
class GCSafePointOpnd;
class StackInfo;
class GCMap {
typedef StlVector<GCSafePoint*> GCSafePoints;
public:
GCMap(MemoryManager& mm);
void registerInsts(IRManager& irm);
POINTER_SIZE_INT getByteSize() const ;
static POINTER_SIZE_INT readByteSize(const U_8* input);
void write(U_8*);
const GCSafePointsInfo* getGCSafePointsInfo() const {return offsetsInfo;}
static const POINTER_SIZE_INT* findGCSafePointStart(const POINTER_SIZE_INT* image, POINTER_SIZE_INT ip);
static void checkObject(TypeManager& tm, const void* p);
private:
void processBasicBlock(IRManager& irm, const Node* block);
void registerGCSafePoint(IRManager& irm, const BitSet& ls, Inst* inst);
void registerHardwareExceptionPoint(Inst* inst);
bool isHardwareExceptionPoint(const Inst* inst) const;
MemoryManager& mm;
GCSafePoints gcSafePoints;
GCSafePointsInfo* offsetsInfo;
};
class GCSafePoint {
friend class GCMap;
typedef StlVector<GCSafePointOpnd*> GCOpnds;
public:
GCSafePoint(MemoryManager& mm, POINTER_SIZE_INT _ip):gcOpnds(mm), ip(_ip) {
#ifdef GCMAP_TRACK_IDS
instId = 0;
hardwareExceptionPoint = false;
#endif
}
GCSafePoint(MemoryManager& mm, const POINTER_SIZE_INT* image);
POINTER_SIZE_INT getUint32Size() const;
void write(POINTER_SIZE_INT* image) const;
U_32 getNumOpnds() const {return (U_32)gcOpnds.size();}
static POINTER_SIZE_INT getIP(const POINTER_SIZE_INT* image);
void enumerate(GCInterface* gcInterface, const JitFrameContext* c, const StackInfo& stackInfo) const;
private:
//return address in memory where opnd value is saved
POINTER_SIZE_INT getOpndSaveAddr(const JitFrameContext* ctx, const StackInfo& sInfo,const GCSafePointOpnd* gcOpnd) const;
GCOpnds gcOpnds;
POINTER_SIZE_INT ip;
#ifdef GCMAP_TRACK_IDS
POINTER_SIZE_INT instId;
bool hardwareExceptionPoint;
public:
bool isHardwareExceptionPoint() const {return hardwareExceptionPoint;}
#endif
};
class GCSafePointOpnd {
friend class GCSafePoint;
static const U_32 OBJ_MASK = 0x1;
static const U_32 REG_MASK = 0x2;
#ifdef _EM64T_
static const U_32 COMPRESSED_MASK = 0x4;
#endif
#ifdef GCMAP_TRACK_IDS
// flags + val + mptrOffset + firstId
static const U_32 IMAGE_SIZE_UINT32 = 4; //do not use sizeof due to the potential struct layout problems
#else
// flags + val + mptrOffset
static const POINTER_SIZE_INT IMAGE_SIZE_UINT32 = 3;
#endif
public:
#ifdef _EM64T_
GCSafePointOpnd(bool isObject, bool isOnRegister, I_32 _val, I_32 _mptrOffset, bool isCompressed=false) : val(_val), mptrOffset(_mptrOffset) {
flags = flags | (isCompressed ? COMPRESSED_MASK: 0);
#else
GCSafePointOpnd(bool isObject, bool isOnRegister, I_32 _val, I_32 _mptrOffset) : val(_val), mptrOffset(_mptrOffset) {
#endif
flags = isObject ? OBJ_MASK : 0;
flags = flags | (isOnRegister ? REG_MASK: 0);
#ifdef GCMAP_TRACK_IDS
firstId = 0;
#endif
}
bool isObject() const {return (flags & OBJ_MASK)!=0;}
bool isMPtr() const {return !isObject();}
bool isOnRegister() const { return (flags & REG_MASK)!=0;}
bool isOnStack() const {return !isOnRegister();}
#ifdef _EM64T_
bool isCompressed() const { return (flags & COMPRESSED_MASK)!=0;}
#endif
RegName getRegName() const { assert(isOnRegister()); return RegName(val);}
I_32 getDistFromInstESP() const { assert(isOnStack()); return val;}
I_32 getMPtrOffset() const {return mptrOffset;}
void getMPtrOffset(int newOffset) {mptrOffset = newOffset;}
#ifdef GCMAP_TRACK_IDS
U_32 firstId;
#endif
private:
GCSafePointOpnd(U_32 _flags, I_32 _val, I_32 _mptrOffset) : flags(_flags), val(_val), mptrOffset(_mptrOffset) {}
//first bit is location, second is type
U_32 flags;
//opnd placement ->Register or offset
I_32 val;
I_32 mptrOffset;
};
class GCMapCreator : public SessionAction {
void runImpl();
U_32 getNeedInfo()const{ return NeedInfo_LivenessInfo;}
U_32 getSideEffects() {return Log::isEnabled();}
bool isIRDumpEnabled(){ return true;}
};
class InfoBlockWriter : public SessionAction {
void runImpl();
U_32 getNeedInfo()const{ return 0; }
U_32 getSideEffects()const{ return 0; }
bool isIRDumpEnabled(){ return false; }
};
}} //namespace
#endif /* _IA32_GC_MAP_H_ */