summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/codegen/MethodBitcode.cc16
-rw-r--r--src/compiler_llvm/art_module.ll1
-rw-r--r--src/compiler_llvm/dalvik_reg.cc24
-rw-r--r--src/compiler_llvm/dalvik_reg.h3
-rw-r--r--src/compiler_llvm/gbc_expander.cc50
-rw-r--r--src/compiler_llvm/ir_builder.cc5
-rw-r--r--src/compiler_llvm/ir_builder.h2
-rw-r--r--src/compiler_llvm/jni_compiler.cc2
-rw-r--r--src/compiler_llvm/method_compiler.cc50
-rw-r--r--src/compiler_llvm/method_compiler.h3
-rw-r--r--src/greenland/intrinsic_func_list.def9
-rw-r--r--src/stack.cc5
12 files changed, 133 insertions, 37 deletions
diff --git a/src/compiler/codegen/MethodBitcode.cc b/src/compiler/codegen/MethodBitcode.cc
index f3ebf09ab1..1e81458dca 100644
--- a/src/compiler/codegen/MethodBitcode.cc
+++ b/src/compiler/codegen/MethodBitcode.cc
@@ -61,6 +61,17 @@ void defineValue(CompilationUnit* cUnit, llvm::Value* val, int sReg)
llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(placeholder);
DCHECK(inst != NULL);
inst->eraseFromParent();
+
+ // Set vreg for debugging
+ if (!cUnit->compiler->IsDebuggingSupported()) {
+ greenland::IntrinsicHelper::IntrinsicId id =
+ greenland::IntrinsicHelper::SetVReg;
+ llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
+ int vReg = SRegToVReg(cUnit, sReg);
+ llvm::Value* tableSlot = cUnit->irb->getInt32(vReg);
+ llvm::Value* args[] = { tableSlot, val };
+ cUnit->irb->CreateCall(func, args);
+ }
}
llvm::Type* llvmTypeFromLocRec(CompilationUnit* cUnit, RegLocation loc)
@@ -1837,7 +1848,9 @@ bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
greenland::IntrinsicHelper::AllocaShadowFrame;
llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
- cUnit->irb->CreateCall(func, entries);
+ llvm::Value* dalvikRegs = cUnit->irb->getInt32(cUnit->numDalvikRegisters);
+ llvm::Value* args[] = { entries, dalvikRegs };
+ cUnit->irb->CreateCall(func, args);
} else if (bb->blockType == kExitBlock) {
/*
* Because of the differences between how MIR/LIR and llvm handle exit
@@ -2998,6 +3011,7 @@ bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
case greenland::IntrinsicHelper::AllocaShadowFrame:
case greenland::IntrinsicHelper::SetShadowFrameEntry:
case greenland::IntrinsicHelper::PopShadowFrame:
+ case greenland::IntrinsicHelper::SetVReg:
// Ignore shadow frame stuff for quick compiler
break;
case greenland::IntrinsicHelper::CopyInt:
diff --git a/src/compiler_llvm/art_module.ll b/src/compiler_llvm/art_module.ll
index 3c3c90bfe0..1c04dc836c 100644
--- a/src/compiler_llvm/art_module.ll
+++ b/src/compiler_llvm/art_module.ll
@@ -26,6 +26,7 @@
, i32 ; Line number for stack backtrace
, i32 ; Number of references
; [0 x %JavaObject*] ; References
+ ; [0 x i32] ; VRegs
}
declare void @__art_type_list(%JavaObject*, %ShadowFrame*)
diff --git a/src/compiler_llvm/dalvik_reg.cc b/src/compiler_llvm/dalvik_reg.cc
index c3263ae951..dc73e75333 100644
--- a/src/compiler_llvm/dalvik_reg.cc
+++ b/src/compiler_llvm/dalvik_reg.cc
@@ -27,9 +27,9 @@ using namespace art::compiler_llvm;
// Dalvik Register
//----------------------------------------------------------------------------
-DalvikReg::DalvikReg(MethodCompiler& method_compiler, const std::string& name)
+DalvikReg::DalvikReg(MethodCompiler& method_compiler, const std::string& name, llvm::Value* vreg)
: method_compiler_(&method_compiler), irb_(method_compiler.GetIRBuilder()),
- reg_name_(name), reg_32_(NULL), reg_64_(NULL), reg_obj_(NULL) {
+ reg_name_(name), reg_32_(NULL), reg_64_(NULL), reg_obj_(NULL), vreg_(vreg) {
}
@@ -118,10 +118,6 @@ llvm::Value* DalvikReg::GetValue(JType jty, JTypeSpace space) {
return NULL;
}
break;
-
- default:
- LOG(FATAL) << "Couldn't GetValue of JType " << jty;
- return NULL;
}
if (jty == kFloat || jty == kDouble) {
@@ -141,13 +137,13 @@ void DalvikReg::SetValue(JType jty, JTypeSpace space, llvm::Value* value) {
switch (space) {
case kReg:
case kField:
- irb_.CreateStore(value, GetAddr(jty), kTBAARegister);
- return;
+ break;
case kAccurate:
case kArray:
switch (jty) {
case kVoid:
+ LOG(FATAL) << "Dalvik register with void type has no value";
break;
case kBoolean:
@@ -155,7 +151,7 @@ void DalvikReg::SetValue(JType jty, JTypeSpace space, llvm::Value* value) {
// NOTE: In accurate type space, we have to zero extend boolean from
// i1 to i32, and char from i16 to i32. In array type space, we have
// to zero extend boolean from i8 to i32, and char from i16 to i32.
- irb_.CreateStore(RegCat1ZExt(value), GetAddr(jty), kTBAARegister);
+ value = RegCat1ZExt(value);
break;
case kByte:
@@ -163,7 +159,7 @@ void DalvikReg::SetValue(JType jty, JTypeSpace space, llvm::Value* value) {
// NOTE: In accurate type space, we have to signed extend byte from
// i8 to i32, and short from i16 to i32. In array type space, we have
// to sign extend byte from i8 to i32, and short from i16 to i32.
- irb_.CreateStore(RegCat1SExt(value), GetAddr(jty), kTBAARegister);
+ value = RegCat1SExt(value);
break;
case kInt:
@@ -171,13 +167,19 @@ void DalvikReg::SetValue(JType jty, JTypeSpace space, llvm::Value* value) {
case kFloat:
case kDouble:
case kObject:
- irb_.CreateStore(value, GetAddr(jty), kTBAARegister);
break;
default:
LOG(FATAL) << "Unknown java type: " << jty;
}
}
+
+ irb_.CreateStore(value, GetAddr(jty), kTBAARegister);
+ if (vreg_ != NULL) {
+ irb_.CreateStore(value,
+ irb_.CreateBitCast(vreg_, value->getType()->getPointerTo()),
+ kTBAAShadowFrame);
+ }
}
diff --git a/src/compiler_llvm/dalvik_reg.h b/src/compiler_llvm/dalvik_reg.h
index f9507710bb..ac0f421e75 100644
--- a/src/compiler_llvm/dalvik_reg.h
+++ b/src/compiler_llvm/dalvik_reg.h
@@ -39,7 +39,7 @@ class DalvikReg {
static char GetRegCategoryNamePrefix(RegCategory reg_cat);
- DalvikReg(MethodCompiler& method_compiler, const std::string& name);
+ DalvikReg(MethodCompiler& method_compiler, const std::string& name, llvm::Value* vreg);
~DalvikReg();
@@ -70,6 +70,7 @@ class DalvikReg {
llvm::Value* reg_32_;
llvm::Value* reg_64_;
llvm::Value* reg_obj_;
+ llvm::Value* vreg_;
};
} // namespace compiler_llvm
diff --git a/src/compiler_llvm/gbc_expander.cc b/src/compiler_llvm/gbc_expander.cc
index 18cef411c3..c0943978d0 100644
--- a/src/compiler_llvm/gbc_expander.cc
+++ b/src/compiler_llvm/gbc_expander.cc
@@ -60,7 +60,6 @@ class GBCExpanderPass : public llvm::FunctionPass {
private:
llvm::AllocaInst* shadow_frame_;
llvm::Value* old_shadow_frame_;
- uint16_t num_shadow_frame_refs_;
private:
art::Compiler* compiler_;
@@ -217,10 +216,12 @@ class GBCExpanderPass : public llvm::FunctionPass {
llvm::Value* Expand_DivRem(llvm::CallInst& call_inst, bool is_div, JType op_jty);
- void Expand_AllocaShadowFrame(llvm::Value* num_entry_value);
+ void Expand_AllocaShadowFrame(llvm::Value* num_entry_value, llvm::Value* num_vregs_value);
void Expand_SetShadowFrameEntry(llvm::Value* obj, llvm::Value* entry_idx);
+ void Expand_SetVReg(llvm::Value* entry_idx, llvm::Value* obj);
+
void Expand_PopShadowFrame();
void Expand_UpdateDexPC(llvm::Value* dex_pc_value);
@@ -326,7 +327,7 @@ class GBCExpanderPass : public llvm::FunctionPass {
GBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb)
: llvm::FunctionPass(ID), intrinsic_helper_(intrinsic_helper), irb_(irb),
context_(irb.getContext()), rtb_(irb.Runtime()),
- shadow_frame_(NULL), old_shadow_frame_(NULL), num_shadow_frame_refs_(0),
+ shadow_frame_(NULL), old_shadow_frame_(NULL),
compiler_(NULL), dex_file_(NULL), code_item_(NULL),
oat_compilation_unit_(NULL), method_idx_(-1u), func_(NULL),
changed_(false)
@@ -336,7 +337,7 @@ class GBCExpanderPass : public llvm::FunctionPass {
art::Compiler* compiler, art::OatCompilationUnit* oat_compilation_unit)
: llvm::FunctionPass(ID), intrinsic_helper_(intrinsic_helper), irb_(irb),
context_(irb.getContext()), rtb_(irb.Runtime()),
- shadow_frame_(NULL), old_shadow_frame_(NULL), num_shadow_frame_refs_(0),
+ shadow_frame_(NULL), old_shadow_frame_(NULL),
compiler_(compiler),
dex_file_(oat_compilation_unit->GetDexFile()),
code_item_(oat_compilation_unit->GetCodeItem()),
@@ -366,7 +367,6 @@ bool GBCExpanderPass::runOnFunction(llvm::Function& func) {
// Setup rewrite context
shadow_frame_ = NULL;
old_shadow_frame_ = NULL;
- num_shadow_frame_refs_ = 0;
func_ = &func;
changed_ = false; // Assume unchanged
@@ -1092,14 +1092,17 @@ llvm::Value* GBCExpanderPass::Expand_DivRem(llvm::CallInst& call_inst,
return result;
}
-void GBCExpanderPass::Expand_AllocaShadowFrame(llvm::Value* num_entry_value) {
+void GBCExpanderPass::Expand_AllocaShadowFrame(llvm::Value* num_entry_value,
+ llvm::Value* num_vregs_value) {
// Most of the codes refer to MethodCompiler::EmitPrologueAllocShadowFrame and
// MethodCompiler::EmitPushShadowFrame
- num_shadow_frame_refs_ =
+ uint16_t num_shadow_frame_refs =
llvm::cast<llvm::ConstantInt>(num_entry_value)->getZExtValue();
+ uint16_t num_vregs =
+ llvm::cast<llvm::ConstantInt>(num_vregs_value)->getZExtValue();
llvm::StructType* shadow_frame_type =
- irb_.getShadowFrameTy(num_shadow_frame_refs_);
+ irb_.getShadowFrameTy(num_shadow_frame_refs, num_vregs);
shadow_frame_ = irb_.CreateAlloca(shadow_frame_type);
@@ -1126,14 +1129,15 @@ void GBCExpanderPass::Expand_AllocaShadowFrame(llvm::Value* num_entry_value) {
llvm::Value* result = rtb_.EmitPushShadowFrame(shadow_frame_upcast,
method_object_addr,
- num_shadow_frame_refs_,
- 0);
+ num_shadow_frame_refs,
+ num_vregs);
irb_.CreateStore(result, old_shadow_frame_, kTBAARegister);
return;
}
+// TODO: We will remove ShadowFrameEntry later, so I just copy/paste from ShadowFrameEntry.
void GBCExpanderPass::Expand_SetShadowFrameEntry(llvm::Value* obj,
llvm::Value* entry_idx) {
DCHECK(shadow_frame_ != NULL);
@@ -1154,6 +1158,24 @@ void GBCExpanderPass::Expand_SetShadowFrameEntry(llvm::Value* obj,
return;
}
+void GBCExpanderPass::Expand_SetVReg(llvm::Value* entry_idx,
+ llvm::Value* value) {
+ DCHECK(shadow_frame_ != NULL);
+
+ llvm::Value* gep_index[] = {
+ irb_.getInt32(0), // No pointer displacement
+ irb_.getInt32(2), // VRegs
+ entry_idx // Pointer field
+ };
+
+ llvm::Value* vreg_addr = irb_.CreateGEP(shadow_frame_, gep_index);
+
+ irb_.CreateStore(value,
+ irb_.CreateBitCast(vreg_addr, value->getType()->getPointerTo()),
+ kTBAAShadowFrame);
+ return;
+}
+
void GBCExpanderPass::Expand_PopShadowFrame() {
#if defined(ART_USE_PORTABLE_COMPILER)
if (old_shadow_frame_ == NULL) {
@@ -3455,7 +3477,8 @@ GBCExpanderPass::ExpandIntrinsic(IntrinsicHelper::IntrinsicId intr_id,
//==- Shadow Frame -----------------------------------------------------==//
case IntrinsicHelper::AllocaShadowFrame: {
- Expand_AllocaShadowFrame(call_inst.getArgOperand(0));
+ Expand_AllocaShadowFrame(call_inst.getArgOperand(0),
+ call_inst.getArgOperand(1));
return NULL;
}
case IntrinsicHelper::SetShadowFrameEntry: {
@@ -3463,6 +3486,11 @@ GBCExpanderPass::ExpandIntrinsic(IntrinsicHelper::IntrinsicId intr_id,
call_inst.getArgOperand(1));
return NULL;
}
+ case IntrinsicHelper::SetVReg: {
+ Expand_SetVReg(call_inst.getArgOperand(0),
+ call_inst.getArgOperand(1));
+ return NULL;
+ }
case IntrinsicHelper::PopShadowFrame: {
Expand_PopShadowFrame();
return NULL;
diff --git a/src/compiler_llvm/ir_builder.cc b/src/compiler_llvm/ir_builder.cc
index 8ee4f3ede8..b271002df4 100644
--- a/src/compiler_llvm/ir_builder.cc
+++ b/src/compiler_llvm/ir_builder.cc
@@ -151,8 +151,8 @@ llvm::Type* IRBuilder::getJTypeInArraySpace(JType jty) {
}
-llvm::StructType* IRBuilder::getShadowFrameTy(uint32_t sirt_size) {
- std::string name(StringPrintf("ShadowFrame%u", sirt_size));
+llvm::StructType* IRBuilder::getShadowFrameTy(uint32_t sirt_size, uint32_t vreg_size) {
+ std::string name(StringPrintf("ShadowFrame%u_vreg%u", sirt_size, vreg_size));
// Try to find the existing struct type definition
if (llvm::Type* type = module_->getTypeByName(name)) {
@@ -164,6 +164,7 @@ llvm::StructType* IRBuilder::getShadowFrameTy(uint32_t sirt_size) {
llvm::Type* elem_types[] = {
art_frame_type_,
llvm::ArrayType::get(jobject_type_, sirt_size),
+ llvm::ArrayType::get(getInt32Ty(), vreg_size),
};
return llvm::StructType::create(elem_types, name);
diff --git a/src/compiler_llvm/ir_builder.h b/src/compiler_llvm/ir_builder.h
index 5df9831abc..cc0bc8e801 100644
--- a/src/compiler_llvm/ir_builder.h
+++ b/src/compiler_llvm/ir_builder.h
@@ -315,7 +315,7 @@ class IRBuilder : public LLVMIRBuilder {
return getJLongTy();
}
- llvm::StructType* getShadowFrameTy(uint32_t sirt_size);
+ llvm::StructType* getShadowFrameTy(uint32_t sirt_size, uint32_t vreg_size);
//--------------------------------------------------------------------------
diff --git a/src/compiler_llvm/jni_compiler.cc b/src/compiler_llvm/jni_compiler.cc
index 7001ec3051..d5a7869d00 100644
--- a/src/compiler_llvm/jni_compiler.cc
+++ b/src/compiler_llvm/jni_compiler.cc
@@ -101,7 +101,7 @@ CompiledMethod* JniCompiler::Compile() {
}
// Shadow stack
- llvm::StructType* shadow_frame_type = irb_.getShadowFrameTy(sirt_size);
+ llvm::StructType* shadow_frame_type = irb_.getShadowFrameTy(sirt_size, 0);
llvm::AllocaInst* shadow_frame_ = irb_.CreateAlloca(shadow_frame_type);
// Store the dex pc
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index fea0c72a75..f09553cf06 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -175,7 +175,7 @@ void MethodCompiler::EmitPrologue() {
#if !defined(NDEBUG)
name = StringPrintf("%u", r);
#endif
- regs_[r] = new DalvikReg(*this, name);
+ regs_[r] = new DalvikReg(*this, name, GetVRegEntry(r));
// Cache shadow frame entry address
shadow_frame_entries_[r] = GetShadowFrameEntry(r);
@@ -185,7 +185,7 @@ void MethodCompiler::EmitPrologue() {
#if !defined(NDEBUG)
name = "_res";
#endif
- retval_reg_.reset(new DalvikReg(*this, name));
+ retval_reg_.reset(new DalvikReg(*this, name, NULL));
// Store argument to dalvik register
irb_.SetInsertPoint(basic_block_reg_arg_init_);
@@ -284,7 +284,8 @@ void MethodCompiler::EmitPrologueAllocShadowFrame() {
}
}
- llvm::StructType* shadow_frame_type = irb_.getShadowFrameTy(num_shadow_frame_refs_);
+ llvm::StructType* shadow_frame_type = irb_.getShadowFrameTy(num_shadow_frame_refs_,
+ code_item_->registers_size_);
shadow_frame_ = irb_.CreateAlloca(shadow_frame_type);
// Alloca a pointer to old shadow frame
@@ -3802,6 +3803,43 @@ llvm::Value* MethodCompiler::GetShadowFrameEntry(uint32_t reg_idx) {
}
+// TODO: We will remove ShadowFrameEntry later, so I just copy/paste from ShadowFrameEntry.
+llvm::Value* MethodCompiler::GetVRegEntry(uint32_t reg_idx) {
+ if (!compiler_->IsDebuggingSupported()) {
+ return NULL;
+ }
+
+ if (!method_info_.need_shadow_frame_entry) {
+ return NULL;
+ }
+
+ std::string reg_name;
+
+#if !defined(NDEBUG)
+ StringAppendF(&reg_name, "v%u", reg_idx);
+#endif
+
+ // Save current IR builder insert point
+ llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP();
+
+ irb_.SetInsertPoint(basic_block_shadow_frame_);
+
+ llvm::Value* gep_index[] = {
+ irb_.getInt32(0), // No pointer displacement
+ irb_.getInt32(2), // VRegs
+ irb_.getInt32(reg_idx) // Pointer field
+ };
+
+ llvm::Value* reg_addr = irb_.CreateGEP(shadow_frame_, gep_index, reg_name);
+
+ // Restore IRBuilder insert point
+ irb_.restoreIP(irb_ip_original);
+
+ DCHECK_NE(reg_addr, static_cast<llvm::Value*>(NULL));
+ return reg_addr;
+}
+
+
void MethodCompiler::EmitPushShadowFrame(bool is_inline) {
if (!method_info_.need_shadow_frame) {
return;
@@ -3819,11 +3857,13 @@ void MethodCompiler::EmitPushShadowFrame(bool is_inline) {
llvm::Value* result;
if (is_inline) {
result = irb_.Runtime().EmitPushShadowFrame(shadow_frame_upcast, method_object_addr,
- num_shadow_frame_refs_, 0);
+ num_shadow_frame_refs_,
+ code_item_->registers_size_);
} else {
DCHECK(num_shadow_frame_refs_ == 0);
result = irb_.Runtime().EmitPushShadowFrameNoInline(shadow_frame_upcast, method_object_addr,
- num_shadow_frame_refs_, 0);
+ num_shadow_frame_refs_,
+ code_item_->registers_size_);
}
irb_.CreateStore(result, old_shadow_frame_, kTBAARegister);
}
diff --git a/src/compiler_llvm/method_compiler.h b/src/compiler_llvm/method_compiler.h
index 0b6fcfd79d..02c3d6a476 100644
--- a/src/compiler_llvm/method_compiler.h
+++ b/src/compiler_llvm/method_compiler.h
@@ -90,6 +90,8 @@ class MethodCompiler {
llvm::Value* GetShadowFrameEntry(uint32_t reg_idx);
+ llvm::Value* GetVRegEntry(uint32_t reg_idx);
+
private:
void CreateFunction();
@@ -460,6 +462,7 @@ class MethodCompiler {
std::vector<DalvikReg*> regs_;
std::vector<llvm::Value*> shadow_frame_entries_;
+ std::vector<llvm::Value*> vregs_;
std::vector<int32_t> reg_to_shadow_frame_index_;
UniquePtr<DalvikReg> retval_reg_;
diff --git a/src/greenland/intrinsic_func_list.def b/src/greenland/intrinsic_func_list.def
index 8ea69fedf1..57faf4c9fc 100644
--- a/src/greenland/intrinsic_func_list.def
+++ b/src/greenland/intrinsic_func_list.def
@@ -1546,7 +1546,7 @@ _EVAL_DEF_INTRINSICS_FUNC(AllocaShadowFrame,
dex_lang_alloca_shadow_frame,
kAttrNoThrow,
kVoidTy,
- _EXPAND_ARG1(kInt32ConstantTy))
+ _EXPAND_ARG2(kInt32ConstantTy, kInt32ConstantTy))
// void dex_lang_set_shadow_frame_entry(JavaObject* obj, int entry_idx)
_EVAL_DEF_INTRINSICS_FUNC(SetShadowFrameEntry,
@@ -1555,6 +1555,13 @@ _EVAL_DEF_INTRINSICS_FUNC(SetShadowFrameEntry,
kVoidTy,
_EXPAND_ARG2(kJavaObjectTy, kInt32ConstantTy))
+// void dex_lang_set_vreg(int entry_idx, ...)
+_EVAL_DEF_INTRINSICS_FUNC(SetVReg,
+ dex_lang_set_vreg,
+ kAttrNoThrow,
+ kVoidTy,
+ _EXPAND_ARG2(kInt32ConstantTy, kVarArgTy))
+
// void dex_lang_pop_shadow_frame()
_EVAL_DEF_INTRINSICS_FUNC(PopShadowFrame,
dex_lang_pop_shadow_frame,
diff --git a/src/stack.cc b/src/stack.cc
index b244975af7..8a741c6150 100644
--- a/src/stack.cc
+++ b/src/stack.cc
@@ -66,9 +66,9 @@ size_t StackVisitor::GetNativePcOffset() const {
uint32_t StackVisitor::GetVReg(AbstractMethod* m, int vreg) const {
+ DCHECK(m == GetMethod());
if (cur_quick_frame_ != NULL) {
DCHECK(context_ != NULL); // You can't reliably read registers without a context.
- DCHECK(m == GetMethod());
uint32_t core_spills = m->GetCoreSpillMask();
const VmapTable vmap_table(m->GetVmapTableRaw());
uint32_t vmap_offset;
@@ -95,8 +95,7 @@ uint32_t StackVisitor::GetVReg(AbstractMethod* m, int vreg) const {
return GetVReg(cur_quick_frame_, code_item, core_spills, fp_spills, frame_size, vreg);
}
} else {
- LOG(FATAL) << "Unimplemented - shadow frame GetVReg";
- return 0; // Keep GCC happy.
+ return cur_shadow_frame_->GetVReg(vreg);
}
}