Merge "Fix the weird state transitions in verification." into dalvik-dev
diff --git a/src/heap.cc b/src/heap.cc
index 98552a7..eae772f 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -353,7 +353,7 @@
ptr = space->AllocWithGrowth(size);
if (ptr != NULL) {
//size_t new_footprint = dvmHeapSourceGetIdealFootprint();
- size_t new_footprint = space->MaxAllowedFootprint();
+ size_t new_footprint = space->GetMaxAllowedFootprint();
// TODO: may want to grow a little bit more so that the amount of
// free space is equal to the old free space + the
// utilization slop for the new allocation.
@@ -497,8 +497,8 @@
* 3. Soft footprint: external allocation + spaces footprint + active space footprint
* 4. Overhead: soft footprint excluding active.
*
- * Layout: (Below might be incontiguous, but are lumped together to depict size.)
- * |---for external allocation---|---spaces footprint ("heap1")---|----active space footprint----|
+ * Layout: (The spaces below might not be contiguous, but are lumped together to depict size.)
+ * |----------------------spaces footprint--------- --------------|----active space footprint----|
* |--active space allocated--|
* |--------------------soft footprint (include active)--------------------------------------|
* |----------------soft footprint excluding active---------------|
@@ -520,26 +520,14 @@
max_allowed_footprint = Heap::maximum_size_;
}
- SetSoftLimit(max_allowed_footprint);
+ alloc_space_->SetMaxAllowedFootprint(max_allowed_footprint);
}
-void Heap::SetSoftLimit(size_t soft_limit)
-{
- // Compare against the actual footprint, rather than the
- // max_allowed, because the heap may not have grown all the
- // way to the allowed size yet.
- //
- size_t current_space_size = mspace_footprint(alloc_space_->mspace_);
- if (soft_limit < current_space_size) {
- // Don't let the space grow any more, and impose a soft limit.
- mspace_set_max_allowed_footprint(alloc_space_->mspace_, current_space_size);
- } else {
- // Let the heap grow to the requested max
- mspace_set_max_allowed_footprint(alloc_space_->mspace_, soft_limit);
- }
-}
-
-static const size_t kHeapIdealFree = 1024 * 1024 * 2;
+// kHeapIdealFree is the ideal maximum free size, when we grow the heap for
+// utlization.
+static const size_t kHeapIdealFree = 2 * MB;
+// kHeapMinFree guarantees that you always have at least 512 KB free, when
+// you grow for utilization, regardless of target utilization ratio.
static const size_t kHeapMinFree = kHeapIdealFree / 4;
// Given the current contents of the active space, increase the allowed
diff --git a/src/heap.h b/src/heap.h
index d847a87..c25803f 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -92,8 +92,9 @@
static void SetTargetHeapUtilization(float target) {
target_utilization_ = target;
}
+ // Sets the maximum number of bytes that the heap is allowed to allocate
+ // from the system. Clamps to the appropriate maximum value.
static void SetIdealFootprint(size_t max_allowed_footprint);
- static void SetSoftLimit(size_t soft_limit);
// Blocks the caller until the garbage collector becomes idle.
static void WaitForConcurrentGcToComplete();
diff --git a/src/object_test.cc b/src/object_test.cc
index c13a19d..6979b75 100644
--- a/src/object_test.cc
+++ b/src/object_test.cc
@@ -162,29 +162,6 @@
TestPrimitiveArray<ShortArray>(class_linker_);
}
-extern "C" Object* artAllocObjectFromCode(uint32_t type_idx, Method* method);
-TEST_F(ObjectTest, AllocObjectFromCode) {
- // pretend we are trying to call 'new String' from Object.toString
- Class* java_lang_Object = class_linker_->FindSystemClass("Ljava/lang/Object;");
- Method* toString = java_lang_Object->FindVirtualMethod("toString", "()Ljava/lang/String;");
- uint32_t type_idx = FindTypeIdxByDescriptor(*java_lang_dex_file_.get(), "Ljava/lang/String;");
- Object* string = artAllocObjectFromCode(type_idx, toString);
- EXPECT_TRUE(string->IsString());
-}
-
-extern "C" Array* artAllocArrayFromCode(uint32_t type_idx, Method* method, int32_t component_count);
-TEST_F(ObjectTest, AllocArrayFromCode) {
- // pretend we are trying to call 'new char[3]' from String.toCharArray
- Class* java_lang_String = class_linker_->FindSystemClass("Ljava/lang/String;");
- Method* toCharArray = java_lang_String->FindVirtualMethod("toCharArray", "()[C");
- uint32_t type_idx = FindTypeIdxByDescriptor(*java_lang_dex_file_.get(), "[C");
- Object* array = artAllocArrayFromCode(type_idx, toCharArray, 3);
- EXPECT_TRUE(array->IsArrayInstance());
- EXPECT_EQ(3, array->AsArray()->GetLength());
- EXPECT_TRUE(array->GetClass()->IsArrayClass());
- EXPECT_TRUE(array->GetClass()->GetComponentType()->IsPrimitive());
-}
-
extern "C" Array* artCheckAndAllocArrayFromCode(uint32_t type_idx, Method* method,
int32_t component_count);
TEST_F(ObjectTest, CheckAndAllocArrayFromCode) {
diff --git a/src/runtime_support.cc b/src/runtime_support.cc
index 2bcd7d9..49191b7 100644
--- a/src/runtime_support.cc
+++ b/src/runtime_support.cc
@@ -414,17 +414,22 @@
// Given the context of a calling Method, use its DexCache to resolve a type to a Class. If it
// cannot be resolved, throw an error. If it can, use it to create an instance.
-extern "C" Object* artAllocObjectFromCode(uint32_t type_idx, Method* method) {
+extern "C" Object* artAllocObjectFromCode(uint32_t type_idx, Method* method, Thread* self, Method** sp) {
+ // Place a special frame at the TOS that will save all callee saves
+ Runtime* runtime = Runtime::Current();
+ *sp = runtime->GetCalleeSaveMethod();
+ self->SetTopOfStack(sp, 0);
+
Class* klass = method->GetDexCacheResolvedTypes()->Get(type_idx);
if (klass == NULL) {
- klass = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method);
+ klass = runtime->GetClassLinker()->ResolveType(type_idx, method);
if (klass == NULL) {
- DCHECK(Thread::Current()->IsExceptionPending());
+ DCHECK(self->IsExceptionPending());
return NULL; // Failure
}
}
- if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(klass, true)) {
- DCHECK(Thread::Current()->IsExceptionPending());
+ if (!runtime->GetClassLinker()->EnsureInitialized(klass, true)) {
+ DCHECK(self->IsExceptionPending());
return NULL; // Failure
}
return klass->AllocObject();
@@ -465,7 +470,12 @@
// Given the context of a calling Method, use its DexCache to resolve a type to an array Class. If
// it cannot be resolved, throw an error. If it can, use it to create an array.
-extern "C" Array* artAllocArrayFromCode(uint32_t type_idx, Method* method, int32_t component_count) {
+extern "C" Array* artAllocArrayFromCode(uint32_t type_idx, Method* method, int32_t component_count, Thread* self, Method** sp) {
+ // Place a special frame at the TOS that will save all callee saves
+ Runtime* runtime = Runtime::Current();
+ *sp = runtime->GetCalleeSaveMethod();
+ self->SetTopOfStack(sp, 0);
+
if (component_count < 0) {
Thread::Current()->ThrowNewExceptionF("Ljava/lang/NegativeArraySizeException;", "%d",
component_count);
diff --git a/src/runtime_support_asm.S b/src/runtime_support_asm.S
index 7d4c906..0e73d83 100644
--- a/src/runtime_support_asm.S
+++ b/src/runtime_support_asm.S
@@ -245,13 +245,13 @@
* Called by managed code to allocate an object
*/
art_alloc_object_from_code:
- str sp, [R9, #THREAD_TOP_OF_MANAGED_STACK_OFFSET] @ record top of stack and pc in case of
- str lr, [R9, #THREAD_TOP_OF_MANAGED_STACK_PC_OFFSET] @ walking stack
- stmdb sp!, {lr} @ Save LR
- sub sp, #12 @ Align stack
- bl artAllocObjectFromCode @ (uint32_t type_idx, Method* method)
- add sp, #12
- ldmia sp!, {lr} @ restore LR
+ SETUP_CALLEE_SAVE_FRAME
+ mov r2, r9 @ pass Thread::Current
+ mov r3, sp @ pass SP
+ bl artAllocObjectFromCode @ (uint32_t type_idx, Method* method, Thread*, SP)
+ add sp, #16
+ vpop {s0-s31}
+ pop {r1-r11, lr}
cmp r0, #0 @ success if result is non-null
movne pc, lr @ return on success
@ set up for throwing exception
@@ -266,13 +266,13 @@
* Called by managed code to allocate an array
*/
art_alloc_array_from_code:
- str sp, [R9, #THREAD_TOP_OF_MANAGED_STACK_OFFSET] @ record top of stack and pc in case of
- str lr, [R9, #THREAD_TOP_OF_MANAGED_STACK_PC_OFFSET] @ walking stack
- stmdb sp!, {lr} @ Save LR
- sub sp, #12 @ Align stack
- bl artAllocArrayFromCode @ (uint32_t type_idx, Method* method, int32_t component_count)
- add sp, #12
- ldmia sp!, {lr} @ restore LR
+ SETUP_CALLEE_SAVE_FRAME
+ mov r3, r9 @ pass Thread::Current
+ str sp, [sp, #0] @ pass SP
+ bl artAllocArrayFromCode @ (uint32_t type_idx, Method* method, int32_t component_count, Thread*, SP)
+ add sp, #16
+ vpop {s0-s31}
+ pop {r1-r11, lr}
cmp r0, #0 @ success if result is non-null
movne pc, lr @ return on success
@ set up for throwing exception
diff --git a/src/space.cc b/src/space.cc
index 1852b0d..1b887d8 100644
--- a/src/space.cc
+++ b/src/space.cc
@@ -203,11 +203,29 @@
mspace_walk_free_pages(mspace_, DontNeed, &num_bytes_released);
}
-size_t Space::MaxAllowedFootprint() {
+size_t Space::GetMaxAllowedFootprint() {
DCHECK(mspace_ != NULL);
return mspace_max_allowed_footprint(mspace_);
}
+void Space::SetMaxAllowedFootprint(size_t limit)
+{
+ DCHECK(mspace_ != NULL);
+
+ // Compare against the actual footprint, rather than the
+ // max_allowed, because the heap may not have grown all the
+ // way to the allowed size yet.
+ //
+ size_t current_space_size = mspace_footprint(mspace_);
+ if (limit < current_space_size) {
+ // Don't let the space grow any more.
+ mspace_set_max_allowed_footprint(mspace_, current_space_size);
+ } else {
+ // Let the heap grow to the requested limit.
+ mspace_set_max_allowed_footprint(mspace_, limit);
+ }
+}
+
void Space::Grow(size_t new_size) {
UNIMPLEMENTED(FATAL);
}
diff --git a/src/space.h b/src/space.h
index 83c94a0..758d80c 100644
--- a/src/space.h
+++ b/src/space.h
@@ -36,7 +36,8 @@
void Trim();
- size_t MaxAllowedFootprint();
+ size_t GetMaxAllowedFootprint();
+ void SetMaxAllowedFootprint(size_t limit);
void Grow(size_t num_bytes);
@@ -102,8 +103,6 @@
byte* limit_;
- friend class Heap;
-
DISALLOW_COPY_AND_ASSIGN(Space);
};