summaryrefslogtreecommitdiffstats
path: root/runtime/interpreter
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2014-10-08 15:35:22 -0700
committerIan Rogers <irogers@google.com>2014-10-08 16:00:31 -0700
commit832336b3c9eb892045a8de1bb12c9361112ca3c5 (patch)
tree0e8696869a28ee0dee34d130b586b1bf6f072d6e /runtime/interpreter
parentf1f05d303988a5c071c87b760056be8358276c94 (diff)
downloadart-832336b3c9eb892045a8de1bb12c9361112ca3c5.zip
art-832336b3c9eb892045a8de1bb12c9361112ca3c5.tar.gz
art-832336b3c9eb892045a8de1bb12c9361112ca3c5.tar.bz2
Don't copy fill array data to quick literal pool.
Currently quick copies the fill array data from the dex file to the literal pool. It then has to go through hoops to pass this PC relative address down to out-of-line code. Instead, pass the offset of the table to the out-of-line code and use the CodeItem data associated with the ArtMethod. This reduces the size of oat code while greatly simplifying it. Unify the FillArrayData implementation in quick, portable and the interpreters. Change-Id: I9c6971cf46285fbf197856627368c0185fdc98ca
Diffstat (limited to 'runtime/interpreter')
-rw-r--r--runtime/interpreter/interpreter_goto_table_impl.cc30
-rw-r--r--runtime/interpreter/interpreter_switch_impl.cc20
2 files changed, 11 insertions, 39 deletions
diff --git a/runtime/interpreter/interpreter_goto_table_impl.cc b/runtime/interpreter/interpreter_goto_table_impl.cc
index 5c8a6c6..db7c452 100644
--- a/runtime/interpreter/interpreter_goto_table_impl.cc
+++ b/runtime/interpreter/interpreter_goto_table_impl.cc
@@ -573,30 +573,14 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem*
HANDLE_INSTRUCTION_START(FILL_ARRAY_DATA) {
Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
- if (UNLIKELY(obj == NULL)) {
- ThrowNullPointerException(NULL, "null array in FILL_ARRAY_DATA");
- HANDLE_PENDING_EXCEPTION();
- } else {
- Array* array = obj->AsArray();
- DCHECK(array->IsArrayInstance() && !array->IsObjectArray());
- const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
- const Instruction::ArrayDataPayload* payload =
- reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
- if (UNLIKELY(static_cast<int32_t>(payload->element_count) > array->GetLength())) {
- self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(),
- "Ljava/lang/ArrayIndexOutOfBoundsException;",
- "failed FILL_ARRAY_DATA; length=%d, index=%d",
- array->GetLength(), payload->element_count);
- HANDLE_PENDING_EXCEPTION();
- } else {
- if (transaction_active) {
- RecordArrayElementsInTransaction(array, payload->element_count);
- }
- uint32_t size_in_bytes = payload->element_count * payload->element_width;
- memcpy(array->GetRawData(payload->element_width, 0), payload->data, size_in_bytes);
- ADVANCE(3);
- }
+ const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
+ const Instruction::ArrayDataPayload* payload =
+ reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
+ bool success = FillArrayData(obj, payload);
+ if (transaction_active && success) {
+ RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
}
+ POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
}
HANDLE_INSTRUCTION_END();
diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc
index c6cef6a..fe0af27 100644
--- a/runtime/interpreter/interpreter_switch_impl.cc
+++ b/runtime/interpreter/interpreter_switch_impl.cc
@@ -484,30 +484,18 @@ JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem
}
case Instruction::FILL_ARRAY_DATA: {
PREAMBLE();
- Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
- if (UNLIKELY(obj == NULL)) {
- ThrowNullPointerException(NULL, "null array in FILL_ARRAY_DATA");
- HANDLE_PENDING_EXCEPTION();
- break;
- }
- Array* array = obj->AsArray();
- DCHECK(array->IsArrayInstance() && !array->IsObjectArray());
const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
const Instruction::ArrayDataPayload* payload =
reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
- if (UNLIKELY(static_cast<int32_t>(payload->element_count) > array->GetLength())) {
- self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(),
- "Ljava/lang/ArrayIndexOutOfBoundsException;",
- "failed FILL_ARRAY_DATA; length=%d, index=%d",
- array->GetLength(), payload->element_count);
+ Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
+ bool success = FillArrayData(obj, payload);
+ if (!success) {
HANDLE_PENDING_EXCEPTION();
break;
}
if (transaction_active) {
- RecordArrayElementsInTransaction(array, payload->element_count);
+ RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
}
- uint32_t size_in_bytes = payload->element_count * payload->element_width;
- memcpy(array->GetRawData(payload->element_width, 0), payload->data, size_in_bytes);
inst = inst->Next_3xx();
break;
}