hotspot/src/share/vm/runtime/os.cpp
changeset 16428 1b55a8d558b8
parent 15475 73896d91270c
child 16434 67b70a1edf27
--- a/hotspot/src/share/vm/runtime/os.cpp	Tue Mar 19 13:44:26 2013 +0100
+++ b/hotspot/src/share/vm/runtime/os.cpp	Tue Mar 19 11:33:11 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -80,6 +80,8 @@
 julong os::free_bytes = 0;          // # of bytes freed
 #endif
 
+static juint cur_malloc_words = 0;  // current size for MallocMaxTestWords
+
 void os_init_globals() {
   // Called from init_globals().
   // See Threads::create_vm() in thread.cpp, and init.cpp.
@@ -570,6 +572,26 @@
 }
 #endif
 
+//
+// This function supports testing of the malloc out of memory
+// condition without really running the system out of memory.
+//
+static u_char* testMalloc(size_t alloc_size) {
+
+  if (MallocMaxTestWords > 0 &&
+      (cur_malloc_words + (alloc_size / BytesPerWord)) > MallocMaxTestWords) {
+    return NULL;
+  }
+
+  u_char* ptr = (u_char*)::malloc(alloc_size);
+
+  if (MallocMaxTestWords > 0 && (ptr != NULL)) {
+    Atomic::add(((jint) (alloc_size / BytesPerWord)),
+                (volatile jint *) &cur_malloc_words);
+  }
+  return ptr;
+}
+
 void* os::malloc(size_t size, MEMFLAGS memflags, address caller) {
   NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
   NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size));
@@ -579,11 +601,22 @@
     // if NULL is returned the calling functions assume out of memory.
     size = 1;
   }
-  if (size > size + space_before + space_after) { // Check for rollover.
+
+  const size_t alloc_size = size + space_before + space_after;
+
+  if (size > alloc_size) { // Check for rollover.
     return NULL;
   }
+
   NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
-  u_char* ptr = (u_char*)::malloc(size + space_before + space_after);
+
+  u_char* ptr;
+
+  if (MallocMaxTestWords > 0) {
+    ptr = testMalloc(alloc_size);
+  } else {
+    ptr = (u_char*)::malloc(alloc_size);
+  }
 
 #ifdef ASSERT
   if (ptr == NULL) return NULL;