summaryrefslogtreecommitdiffstats
path: root/compiler
diff options
context:
space:
mode:
authorNicolas Geoffray <ngeoffray@google.com>2014-04-04 09:07:17 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2014-04-04 09:07:17 +0000
commit885e813edc121cd8392eb066981522424480253c (patch)
treec6baa84fa2586f23d4aa4607cde2f859a8c560f2 /compiler
parent6f31ce382777d82952d019908866ff28ef3bbc76 (diff)
parent2e7038ac5848468740d6a419434d3dde8c585a53 (diff)
downloadart-885e813edc121cd8392eb066981522424480253c.zip
art-885e813edc121cd8392eb066981522424480253c.tar.gz
art-885e813edc121cd8392eb066981522424480253c.tar.bz2
Merge "Add support for new-instance and invoke-direct."
Diffstat (limited to 'compiler')
-rw-r--r--compiler/optimizing/builder.cc15
-rw-r--r--compiler/optimizing/code_generator_arm.cc34
-rw-r--r--compiler/optimizing/code_generator_x86.cc33
-rw-r--r--compiler/optimizing/nodes.h27
4 files changed, 100 insertions, 9 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index 0554876..d90405a 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -193,7 +193,8 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_
break;
}
- case Instruction::INVOKE_STATIC: {
+ case Instruction::INVOKE_STATIC:
+ case Instruction::INVOKE_DIRECT: {
uint32_t method_idx = instruction.VRegB_35c();
const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx);
uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
@@ -204,6 +205,7 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_
return false;
}
+ // Treat invoke-direct like static calls for now.
HInvokeStatic* invoke = new (arena_) HInvokeStatic(
arena_, number_of_arguments, dex_offset, method_idx);
@@ -221,7 +223,8 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_
break;
}
- case Instruction::INVOKE_STATIC_RANGE: {
+ case Instruction::INVOKE_STATIC_RANGE:
+ case Instruction::INVOKE_DIRECT_RANGE: {
uint32_t method_idx = instruction.VRegB_3rc();
const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx);
uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
@@ -232,6 +235,7 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_
return false;
}
+ // Treat invoke-direct like static calls for now.
HInvokeStatic* invoke = new (arena_) HInvokeStatic(
arena_, number_of_arguments, dex_offset, method_idx);
int32_t register_index = instruction.VRegC();
@@ -277,6 +281,13 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_
break;
}
+ case Instruction::NEW_INSTANCE: {
+ current_block_->AddInstruction(
+ new (arena_) HNewInstance(dex_offset, instruction.VRegB_21c()));
+ UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
+ break;
+ }
+
case Instruction::NOP:
break;
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 09d6f7b..0aeeef7 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -185,7 +185,7 @@ void InstructionCodeGeneratorARM::VisitReturn(HReturn* ret) {
}
static constexpr Register kParameterCoreRegisters[] = { R1, R2, R3 };
-static constexpr int kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters);
+static constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters);
class InvokeStaticCallingConvention : public CallingConvention<Register> {
public:
@@ -287,5 +287,37 @@ void InstructionCodeGeneratorARM::VisitAdd(HAdd* add) {
}
}
+static constexpr Register kRuntimeParameterCoreRegisters[] = { R0, R1 };
+static constexpr size_t kRuntimeParameterCoreRegistersLength =
+ arraysize(kRuntimeParameterCoreRegisters);
+
+class InvokeRuntimeCallingConvention : public CallingConvention<Register> {
+ public:
+ InvokeRuntimeCallingConvention()
+ : CallingConvention(kRuntimeParameterCoreRegisters,
+ kRuntimeParameterCoreRegistersLength) {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(InvokeRuntimeCallingConvention);
+};
+
+void LocationsBuilderARM::VisitNewInstance(HNewInstance* instruction) {
+ LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction);
+ locations->SetOut(Location(R0));
+ instruction->SetLocations(locations);
+}
+
+void InstructionCodeGeneratorARM::VisitNewInstance(HNewInstance* instruction) {
+ InvokeRuntimeCallingConvention calling_convention;
+ LoadCurrentMethod(calling_convention.GetRegisterAt(1));
+ __ LoadImmediate(calling_convention.GetRegisterAt(0), instruction->GetTypeIndex());
+
+ int32_t offset = QUICK_ENTRYPOINT_OFFSET(kWordSize, pAllocObjectWithAccessCheck).Int32Value();
+ __ ldr(LR, Address(TR, offset));
+ __ blx(LR);
+
+ codegen_->RecordPcInfo(instruction->GetDexPc());
+}
+
} // namespace arm
} // namespace art
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 7b0a087..882541b 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -188,7 +188,7 @@ void InstructionCodeGeneratorX86::VisitReturn(HReturn* ret) {
}
static constexpr Register kParameterCoreRegisters[] = { ECX, EDX, EBX };
-static constexpr int kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters);
+static constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters);
class InvokeStaticCallingConvention : public CallingConvention<Register> {
public:
@@ -199,6 +199,20 @@ class InvokeStaticCallingConvention : public CallingConvention<Register> {
DISALLOW_COPY_AND_ASSIGN(InvokeStaticCallingConvention);
};
+static constexpr Register kRuntimeParameterCoreRegisters[] = { EAX, ECX, EDX };
+static constexpr size_t kRuntimeParameterCoreRegistersLength =
+ arraysize(kRuntimeParameterCoreRegisters);
+
+class InvokeRuntimeCallingConvention : public CallingConvention<Register> {
+ public:
+ InvokeRuntimeCallingConvention()
+ : CallingConvention(kRuntimeParameterCoreRegisters,
+ kRuntimeParameterCoreRegistersLength) {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(InvokeRuntimeCallingConvention);
+};
+
void LocationsBuilderX86::VisitPushArgument(HPushArgument* argument) {
LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(argument);
InvokeStaticCallingConvention calling_convention;
@@ -284,5 +298,22 @@ void InstructionCodeGeneratorX86::VisitAdd(HAdd* add) {
}
}
+void LocationsBuilderX86::VisitNewInstance(HNewInstance* instruction) {
+ LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction);
+ locations->SetOut(Location(EAX));
+ instruction->SetLocations(locations);
+}
+
+void InstructionCodeGeneratorX86::VisitNewInstance(HNewInstance* instruction) {
+ InvokeRuntimeCallingConvention calling_convention;
+ LoadCurrentMethod(calling_convention.GetRegisterAt(1));
+ __ movl(calling_convention.GetRegisterAt(0),
+ Immediate(instruction->GetTypeIndex()));
+
+ __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kWordSize, pAllocObjectWithAccessCheck)));
+
+ codegen_->RecordPcInfo(instruction->GetDexPc());
+}
+
} // namespace x86
} // namespace art
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 2b21905..830d0c7 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -201,6 +201,7 @@ class HBasicBlock : public ArenaObject {
M(InvokeStatic) \
M(LoadLocal) \
M(Local) \
+ M(NewInstance) \
M(PushArgument) \
M(Return) \
M(ReturnVoid) \
@@ -593,7 +594,7 @@ class HIntConstant : public HTemplateInstruction<0> {
class HInvoke : public HInstruction {
public:
- HInvoke(ArenaAllocator* arena, uint32_t number_of_arguments, int32_t dex_pc)
+ HInvoke(ArenaAllocator* arena, uint32_t number_of_arguments, uint32_t dex_pc)
: inputs_(arena, number_of_arguments),
dex_pc_(dex_pc) {
inputs_.SetSize(number_of_arguments);
@@ -606,11 +607,11 @@ class HInvoke : public HInstruction {
inputs_.Put(index, argument);
}
- int32_t GetDexPc() const { return dex_pc_; }
+ uint32_t GetDexPc() const { return dex_pc_; }
protected:
GrowableArray<HInstruction*> inputs_;
- const int32_t dex_pc_;
+ const uint32_t dex_pc_;
private:
DISALLOW_COPY_AND_ASSIGN(HInvoke);
@@ -620,8 +621,8 @@ class HInvokeStatic : public HInvoke {
public:
HInvokeStatic(ArenaAllocator* arena,
uint32_t number_of_arguments,
- int32_t dex_pc,
- int32_t index_in_dex_cache)
+ uint32_t dex_pc,
+ uint32_t index_in_dex_cache)
: HInvoke(arena, number_of_arguments, dex_pc), index_in_dex_cache_(index_in_dex_cache) {}
uint32_t GetIndexInDexCache() const { return index_in_dex_cache_; }
@@ -634,6 +635,22 @@ class HInvokeStatic : public HInvoke {
DISALLOW_COPY_AND_ASSIGN(HInvokeStatic);
};
+class HNewInstance : public HTemplateInstruction<0> {
+ public:
+ HNewInstance(uint32_t dex_pc, uint16_t type_index) : dex_pc_(dex_pc), type_index_(type_index) {}
+
+ uint32_t GetDexPc() const { return dex_pc_; }
+ uint16_t GetTypeIndex() const { return type_index_; }
+
+ DECLARE_INSTRUCTION(NewInstance)
+
+ private:
+ const uint32_t dex_pc_;
+ const uint16_t type_index_;
+
+ DISALLOW_COPY_AND_ASSIGN(HNewInstance);
+};
+
// HPushArgument nodes are inserted after the evaluation of an argument
// of a call. Their mere purpose is to ease the code generator's work.
class HPushArgument : public HTemplateInstruction<1> {