summaryrefslogtreecommitdiffstats
path: root/runtime/interpreter
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2015-06-18 16:48:52 -0700
committerMathieu Chartier <mathieuc@google.com>2015-06-18 17:00:56 -0700
commit6e82168bcb339b162f8fac1034a1153eec421eae (patch)
tree282cb85d8c290f31e366ffb1c6d913ffeef3c82f /runtime/interpreter
parentdfc5db6a6deea37c217e29e810e757945dae8586 (diff)
downloadart-6e82168bcb339b162f8fac1034a1153eec421eae.zip
art-6e82168bcb339b162f8fac1034a1153eec421eae.tar.gz
art-6e82168bcb339b162f8fac1034a1153eec421eae.tar.bz2
Fix moving GC bug in DoFilledNewArray
Previously we read from componentClass after allocating the array. Bug: 21783443 (cherry picked from commit 52ea33b10370d60d4ce877aec529626537b7813b) Change-Id: I5283982edab479434e27416509e1436b4176fe01
Diffstat (limited to 'runtime/interpreter')
-rw-r--r--runtime/interpreter/interpreter_common.cc38
1 files changed, 20 insertions, 18 deletions
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 86a79ce..a245890 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -704,30 +704,31 @@ bool DoFilledNewArray(const Instruction* inst, const ShadowFrame& shadow_frame,
return false;
}
uint16_t type_idx = is_range ? inst->VRegB_3rc() : inst->VRegB_35c();
- Class* arrayClass = ResolveVerifyAndClinit(type_idx, shadow_frame.GetMethod(),
- self, false, do_access_check);
- if (UNLIKELY(arrayClass == nullptr)) {
+ Class* array_class = ResolveVerifyAndClinit(type_idx, shadow_frame.GetMethod(),
+ self, false, do_access_check);
+ if (UNLIKELY(array_class == nullptr)) {
DCHECK(self->IsExceptionPending());
return false;
}
- CHECK(arrayClass->IsArrayClass());
- Class* componentClass = arrayClass->GetComponentType();
- if (UNLIKELY(componentClass->IsPrimitive() && !componentClass->IsPrimitiveInt())) {
- if (componentClass->IsPrimitiveLong() || componentClass->IsPrimitiveDouble()) {
+ CHECK(array_class->IsArrayClass());
+ Class* component_class = array_class->GetComponentType();
+ const bool is_primitive_int_component = component_class->IsPrimitiveInt();
+ if (UNLIKELY(component_class->IsPrimitive() && !is_primitive_int_component)) {
+ if (component_class->IsPrimitiveLong() || component_class->IsPrimitiveDouble()) {
ThrowRuntimeException("Bad filled array request for type %s",
- PrettyDescriptor(componentClass).c_str());
+ PrettyDescriptor(component_class).c_str());
} else {
self->ThrowNewExceptionF("Ljava/lang/InternalError;",
"Found type %s; filled-new-array not implemented for anything but 'int'",
- PrettyDescriptor(componentClass).c_str());
+ PrettyDescriptor(component_class).c_str());
}
return false;
}
- Object* newArray = Array::Alloc<true>(self, arrayClass, length,
- arrayClass->GetComponentSizeShift(),
- Runtime::Current()->GetHeap()->GetCurrentAllocator());
- if (UNLIKELY(newArray == nullptr)) {
- DCHECK(self->IsExceptionPending());
+ Object* new_array = Array::Alloc<true>(self, array_class, length,
+ array_class->GetComponentSizeShift(),
+ Runtime::Current()->GetHeap()->GetCurrentAllocator());
+ if (UNLIKELY(new_array == nullptr)) {
+ self->AssertPendingOOMException();
return false;
}
uint32_t arg[5]; // only used in filled-new-array.
@@ -737,17 +738,18 @@ bool DoFilledNewArray(const Instruction* inst, const ShadowFrame& shadow_frame,
} else {
inst->GetVarArgs(arg);
}
- const bool is_primitive_int_component = componentClass->IsPrimitiveInt();
for (int32_t i = 0; i < length; ++i) {
size_t src_reg = is_range ? vregC + i : arg[i];
if (is_primitive_int_component) {
- newArray->AsIntArray()->SetWithoutChecks<transaction_active>(i, shadow_frame.GetVReg(src_reg));
+ new_array->AsIntArray()->SetWithoutChecks<transaction_active>(
+ i, shadow_frame.GetVReg(src_reg));
} else {
- newArray->AsObjectArray<Object>()->SetWithoutChecks<transaction_active>(i, shadow_frame.GetVRegReference(src_reg));
+ new_array->AsObjectArray<Object>()->SetWithoutChecks<transaction_active>(
+ i, shadow_frame.GetVRegReference(src_reg));
}
}
- result->SetL(newArray);
+ result->SetL(new_array);
return true;
}