Mercurial > hg > truffle
annotate src/share/vm/memory/allocation.cpp @ 20543:e7d0505c8a30
8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso
author | tschatzl |
---|---|
date | Fri, 10 Oct 2014 15:51:58 +0200 |
parents | 833b0f92429a |
children | 7848fc12602b |
rev | line source |
---|---|
0 | 1 /* |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17935
diff
changeset
|
2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "memory/allocation.hpp" | |
27 #include "memory/allocation.inline.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
28 #include "memory/genCollectedHeap.hpp" |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
29 #include "memory/metaspaceShared.hpp" |
1972 | 30 #include "memory/resourceArea.hpp" |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
31 #include "memory/universe.hpp" |
6197 | 32 #include "runtime/atomic.hpp" |
1972 | 33 #include "runtime/os.hpp" |
34 #include "runtime/task.hpp" | |
35 #include "runtime/threadCritical.hpp" | |
6197 | 36 #include "services/memTracker.hpp" |
1972 | 37 #include "utilities/ostream.hpp" |
6197 | 38 |
1972 | 39 #ifdef TARGET_OS_FAMILY_linux |
40 # include "os_linux.inline.hpp" | |
41 #endif | |
42 #ifdef TARGET_OS_FAMILY_solaris | |
43 # include "os_solaris.inline.hpp" | |
44 #endif | |
45 #ifdef TARGET_OS_FAMILY_windows | |
46 # include "os_windows.inline.hpp" | |
47 #endif | |
14411 | 48 #ifdef TARGET_OS_FAMILY_aix |
49 # include "os_aix.inline.hpp" | |
50 #endif | |
3960 | 51 #ifdef TARGET_OS_FAMILY_bsd |
52 # include "os_bsd.inline.hpp" | |
53 #endif | |
0 | 54 |
12146
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
11095
diff
changeset
|
55 void* StackObj::operator new(size_t size) throw() { ShouldNotCallThis(); return 0; } |
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
11095
diff
changeset
|
56 void StackObj::operator delete(void* p) { ShouldNotCallThis(); } |
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
11095
diff
changeset
|
57 void* StackObj::operator new [](size_t size) throw() { ShouldNotCallThis(); return 0; } |
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
11095
diff
changeset
|
58 void StackObj::operator delete [](void* p) { ShouldNotCallThis(); } |
10271
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
59 |
12146
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
11095
diff
changeset
|
60 void* _ValueObj::operator new(size_t size) throw() { ShouldNotCallThis(); return 0; } |
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
11095
diff
changeset
|
61 void _ValueObj::operator delete(void* p) { ShouldNotCallThis(); } |
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
11095
diff
changeset
|
62 void* _ValueObj::operator new [](size_t size) throw() { ShouldNotCallThis(); return 0; } |
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
11095
diff
changeset
|
63 void _ValueObj::operator delete [](void* p) { ShouldNotCallThis(); } |
0 | 64 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
65 void* MetaspaceObj::operator new(size_t size, ClassLoaderData* loader_data, |
10376
a1ebd310d5c1
8014912: Restore PrintSharedSpaces functionality after NPG
iklam
parents:
10271
diff
changeset
|
66 size_t word_size, bool read_only, |
12146
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
11095
diff
changeset
|
67 MetaspaceObj::Type type, TRAPS) throw() { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
68 // Klass has it's own operator new |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
69 return Metaspace::allocate(loader_data, word_size, read_only, |
10376
a1ebd310d5c1
8014912: Restore PrintSharedSpaces functionality after NPG
iklam
parents:
10271
diff
changeset
|
70 type, CHECK_NULL); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
71 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
72 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
73 bool MetaspaceObj::is_shared() const { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
74 return MetaspaceShared::is_in_shared_space(this); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
75 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
76 |
7176
59c790074993
8003635: NPG: AsynchGetCallTrace broken by Method* virtual call
coleenp
parents:
6882
diff
changeset
|
77 bool MetaspaceObj::is_metaspace_object() const { |
17935
7384f6a12fc1
8038212: Method::is_valid_method() check has performance regression impact for stackwalking
coleenp
parents:
17799
diff
changeset
|
78 return Metaspace::contains((void*)this); |
7176
59c790074993
8003635: NPG: AsynchGetCallTrace broken by Method* virtual call
coleenp
parents:
6882
diff
changeset
|
79 } |
59c790074993
8003635: NPG: AsynchGetCallTrace broken by Method* virtual call
coleenp
parents:
6882
diff
changeset
|
80 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
81 void MetaspaceObj::print_address_on(outputStream* st) const { |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17935
diff
changeset
|
82 st->print(" {" INTPTR_FORMAT "}", p2i(this)); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
83 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
84 |
12146
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
11095
diff
changeset
|
85 void* ResourceObj::operator new(size_t size, allocation_type type, MEMFLAGS flags) throw() { |
0 | 86 address res; |
87 switch (type) { | |
88 case C_HEAP: | |
6197 | 89 res = (address)AllocateHeap(size, flags, CALLER_PC); |
1685 | 90 DEBUG_ONLY(set_allocation_type(res, C_HEAP);) |
0 | 91 break; |
92 case RESOURCE_AREA: | |
1688
2dfd013a7465
6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents:
1685
diff
changeset
|
93 // new(size) sets allocation type RESOURCE_AREA. |
0 | 94 res = (address)operator new(size); |
95 break; | |
96 default: | |
97 ShouldNotReachHere(); | |
98 } | |
99 return res; | |
100 } | |
101 | |
12146
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
11095
diff
changeset
|
102 void* ResourceObj::operator new [](size_t size, allocation_type type, MEMFLAGS flags) throw() { |
10271
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
103 return (address) operator new(size, type, flags); |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
104 } |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
105 |
6872
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
106 void* ResourceObj::operator new(size_t size, const std::nothrow_t& nothrow_constant, |
12146
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
11095
diff
changeset
|
107 allocation_type type, MEMFLAGS flags) throw() { |
6872
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
108 //should only call this with std::nothrow, use other operator new() otherwise |
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
109 address res; |
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
110 switch (type) { |
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
111 case C_HEAP: |
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
112 res = (address)AllocateHeap(size, flags, CALLER_PC, AllocFailStrategy::RETURN_NULL); |
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
113 DEBUG_ONLY(if (res!= NULL) set_allocation_type(res, C_HEAP);) |
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
114 break; |
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
115 case RESOURCE_AREA: |
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
116 // new(size) sets allocation type RESOURCE_AREA. |
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
117 res = (address)operator new(size, std::nothrow); |
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
118 break; |
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
119 default: |
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
120 ShouldNotReachHere(); |
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
121 } |
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
122 return res; |
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
123 } |
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
124 |
10271
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
125 void* ResourceObj::operator new [](size_t size, const std::nothrow_t& nothrow_constant, |
12146
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
11095
diff
changeset
|
126 allocation_type type, MEMFLAGS flags) throw() { |
10271
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
127 return (address)operator new(size, nothrow_constant, type, flags); |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
128 } |
6872
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
129 |
0 | 130 void ResourceObj::operator delete(void* p) { |
131 assert(((ResourceObj *)p)->allocated_on_C_heap(), | |
132 "delete only allowed for C_HEAP objects"); | |
2015
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
133 DEBUG_ONLY(((ResourceObj *)p)->_allocation_t[0] = (uintptr_t)badHeapOopVal;) |
0 | 134 FreeHeap(p); |
135 } | |
136 | |
10271
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
137 void ResourceObj::operator delete [](void* p) { |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
138 operator delete(p); |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
139 } |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
140 |
1685 | 141 #ifdef ASSERT |
142 void ResourceObj::set_allocation_type(address res, allocation_type type) { | |
143 // Set allocation type in the resource object | |
144 uintptr_t allocation = (uintptr_t)res; | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17935
diff
changeset
|
145 assert((allocation & allocation_mask) == 0, err_msg("address should be aligned to 4 bytes at least: " INTPTR_FORMAT, p2i(res))); |
1685 | 146 assert(type <= allocation_mask, "incorrect allocation type"); |
2015
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
147 ResourceObj* resobj = (ResourceObj *)res; |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
148 resobj->_allocation_t[0] = ~(allocation + type); |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
149 if (type != STACK_OR_EMBEDDED) { |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
150 // Called from operator new() and CollectionSetChooser(), |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
151 // set verification value. |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
152 resobj->_allocation_t[1] = (uintptr_t)&(resobj->_allocation_t[1]) + type; |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
153 } |
1685 | 154 } |
155 | |
1688
2dfd013a7465
6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents:
1685
diff
changeset
|
156 ResourceObj::allocation_type ResourceObj::get_allocation_type() const { |
2015
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
157 assert(~(_allocation_t[0] | allocation_mask) == (uintptr_t)this, "lost resource object"); |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
158 return (allocation_type)((~_allocation_t[0]) & allocation_mask); |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
159 } |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
160 |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
161 bool ResourceObj::is_type_set() const { |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
162 allocation_type type = (allocation_type)(_allocation_t[1] & allocation_mask); |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
163 return get_allocation_type() == type && |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
164 (_allocation_t[1] - type) == (uintptr_t)(&_allocation_t[1]); |
1685 | 165 } |
166 | |
1688
2dfd013a7465
6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents:
1685
diff
changeset
|
167 ResourceObj::ResourceObj() { // default constructor |
2015
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
168 if (~(_allocation_t[0] | allocation_mask) != (uintptr_t)this) { |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
169 // Operator new() is not called for allocations |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
170 // on stack and for embedded objects. |
1685 | 171 set_allocation_type((address)this, STACK_OR_EMBEDDED); |
2015
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
172 } else if (allocated_on_stack()) { // STACK_OR_EMBEDDED |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
173 // For some reason we got a value which resembles |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
174 // an embedded or stack object (operator new() does not |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
175 // set such type). Keep it since it is valid value |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
176 // (even if it was garbage). |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
177 // Ignore garbage in other fields. |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
178 } else if (is_type_set()) { |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
179 // Operator new() was called and type was set. |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
180 assert(!allocated_on_stack(), |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
181 err_msg("not embedded or stack, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")", |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17935
diff
changeset
|
182 p2i(this), get_allocation_type(), _allocation_t[0], _allocation_t[1])); |
1685 | 183 } else { |
2015
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
184 // Operator new() was not called. |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
185 // Assume that it is embedded or stack object. |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
186 set_allocation_type((address)this, STACK_OR_EMBEDDED); |
1685 | 187 } |
2015
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
188 _allocation_t[1] = 0; // Zap verification value |
1685 | 189 } |
190 | |
1688
2dfd013a7465
6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents:
1685
diff
changeset
|
191 ResourceObj::ResourceObj(const ResourceObj& r) { // default copy constructor |
1685 | 192 // Used in ClassFileParser::parse_constant_pool_entries() for ClassFileStream. |
2015
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
193 // Note: garbage may resembles valid value. |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
194 assert(~(_allocation_t[0] | allocation_mask) != (uintptr_t)this || !is_type_set(), |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
195 err_msg("embedded or stack only, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")", |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17935
diff
changeset
|
196 p2i(this), get_allocation_type(), _allocation_t[0], _allocation_t[1])); |
1685 | 197 set_allocation_type((address)this, STACK_OR_EMBEDDED); |
2015
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
198 _allocation_t[1] = 0; // Zap verification value |
1685 | 199 } |
200 | |
201 ResourceObj& ResourceObj::operator=(const ResourceObj& r) { // default copy assignment | |
202 // Used in InlineTree::ok_to_inline() for WarmCallInfo. | |
2015
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
203 assert(allocated_on_stack(), |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
204 err_msg("copy only into local, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")", |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17935
diff
changeset
|
205 p2i(this), get_allocation_type(), _allocation_t[0], _allocation_t[1])); |
2015
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
206 // Keep current _allocation_t value; |
1685 | 207 return *this; |
208 } | |
209 | |
210 ResourceObj::~ResourceObj() { | |
1688
2dfd013a7465
6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents:
1685
diff
changeset
|
211 // allocated_on_C_heap() also checks that encoded (in _allocation) address == this. |
2015
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
212 if (!allocated_on_C_heap()) { // ResourceObj::delete() will zap _allocation for C_heap. |
79d8657be916
6993125: runThese crashes with assert(Thread::current()->on_local_stack((address)this))
kvn
parents:
1972
diff
changeset
|
213 _allocation_t[0] = (uintptr_t)badHeapOopVal; // zap type |
1685 | 214 } |
215 } | |
216 #endif // ASSERT | |
217 | |
218 | |
0 | 219 void trace_heap_malloc(size_t size, const char* name, void* p) { |
220 // A lock is not needed here - tty uses a lock internally | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17935
diff
changeset
|
221 tty->print_cr("Heap malloc " INTPTR_FORMAT " " SIZE_FORMAT " %s", p2i(p), size, name == NULL ? "" : name); |
0 | 222 } |
223 | |
224 | |
225 void trace_heap_free(void* p) { | |
226 // A lock is not needed here - tty uses a lock internally | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17935
diff
changeset
|
227 tty->print_cr("Heap free " INTPTR_FORMAT, p2i(p)); |
0 | 228 } |
229 | |
230 //-------------------------------------------------------------------------------------- | |
231 // ChunkPool implementation | |
232 | |
233 // MT-safe pool of chunks to reduce malloc/free thrashing | |
234 // NB: not using Mutex because pools are used before Threads are initialized | |
6197 | 235 class ChunkPool: public CHeapObj<mtInternal> { |
0 | 236 Chunk* _first; // first cached Chunk; its first word points to next chunk |
237 size_t _num_chunks; // number of unused chunks in pool | |
238 size_t _num_used; // number of chunks currently checked out | |
239 const size_t _size; // size of each chunk (must be uniform) | |
240 | |
11095 | 241 // Our four static pools |
0 | 242 static ChunkPool* _large_pool; |
243 static ChunkPool* _medium_pool; | |
244 static ChunkPool* _small_pool; | |
11095 | 245 static ChunkPool* _tiny_pool; |
0 | 246 |
247 // return first element or null | |
248 void* get_first() { | |
249 Chunk* c = _first; | |
250 if (_first) { | |
251 _first = _first->next(); | |
252 _num_chunks--; | |
253 } | |
254 return c; | |
255 } | |
256 | |
257 public: | |
258 // All chunks in a ChunkPool has the same size | |
259 ChunkPool(size_t size) : _size(size) { _first = NULL; _num_chunks = _num_used = 0; } | |
260 | |
261 // Allocate a new chunk from the pool (might expand the pool) | |
11009
f75faf51e8c4
7158805: Better rewriting of nested subroutine calls
hseigel
parents:
7176
diff
changeset
|
262 _NOINLINE_ void* allocate(size_t bytes, AllocFailType alloc_failmode) { |
0 | 263 assert(bytes == _size, "bad size"); |
264 void* p = NULL; | |
6197 | 265 // No VM lock can be taken inside ThreadCritical lock, so os::malloc |
266 // should be done outside ThreadCritical lock due to NMT | |
0 | 267 { ThreadCritical tc; |
268 _num_used++; | |
269 p = get_first(); | |
270 } | |
6197 | 271 if (p == NULL) p = os::malloc(bytes, mtChunk, CURRENT_PC); |
11009
f75faf51e8c4
7158805: Better rewriting of nested subroutine calls
hseigel
parents:
7176
diff
changeset
|
272 if (p == NULL && alloc_failmode == AllocFailStrategy::EXIT_OOM) { |
10161
746b070f5022
8011661: Insufficient memory message says "malloc" when sometimes it should say "mmap"
ccheung
parents:
10135
diff
changeset
|
273 vm_exit_out_of_memory(bytes, OOM_MALLOC_ERROR, "ChunkPool::allocate"); |
11009
f75faf51e8c4
7158805: Better rewriting of nested subroutine calls
hseigel
parents:
7176
diff
changeset
|
274 } |
0 | 275 return p; |
276 } | |
277 | |
278 // Return a chunk to the pool | |
279 void free(Chunk* chunk) { | |
280 assert(chunk->length() + Chunk::aligned_overhead_size() == _size, "bad size"); | |
281 ThreadCritical tc; | |
282 _num_used--; | |
283 | |
284 // Add chunk to list | |
285 chunk->set_next(_first); | |
286 _first = chunk; | |
287 _num_chunks++; | |
288 } | |
289 | |
290 // Prune the pool | |
291 void free_all_but(size_t n) { | |
6197 | 292 Chunk* cur = NULL; |
293 Chunk* next; | |
294 { | |
0 | 295 // if we have more than n chunks, free all of them |
296 ThreadCritical tc; | |
297 if (_num_chunks > n) { | |
298 // free chunks at end of queue, for better locality | |
6197 | 299 cur = _first; |
0 | 300 for (size_t i = 0; i < (n - 1) && cur != NULL; i++) cur = cur->next(); |
301 | |
302 if (cur != NULL) { | |
6197 | 303 next = cur->next(); |
0 | 304 cur->set_next(NULL); |
305 cur = next; | |
306 | |
6197 | 307 _num_chunks = n; |
308 } | |
309 } | |
310 } | |
311 | |
312 // Free all remaining chunks, outside of ThreadCritical | |
313 // to avoid deadlock with NMT | |
0 | 314 while(cur != NULL) { |
315 next = cur->next(); | |
6197 | 316 os::free(cur, mtChunk); |
0 | 317 cur = next; |
318 } | |
319 } | |
320 | |
321 // Accessors to preallocated pool's | |
322 static ChunkPool* large_pool() { assert(_large_pool != NULL, "must be initialized"); return _large_pool; } | |
323 static ChunkPool* medium_pool() { assert(_medium_pool != NULL, "must be initialized"); return _medium_pool; } | |
324 static ChunkPool* small_pool() { assert(_small_pool != NULL, "must be initialized"); return _small_pool; } | |
11095 | 325 static ChunkPool* tiny_pool() { assert(_tiny_pool != NULL, "must be initialized"); return _tiny_pool; } |
0 | 326 |
327 static void initialize() { | |
328 _large_pool = new ChunkPool(Chunk::size + Chunk::aligned_overhead_size()); | |
329 _medium_pool = new ChunkPool(Chunk::medium_size + Chunk::aligned_overhead_size()); | |
330 _small_pool = new ChunkPool(Chunk::init_size + Chunk::aligned_overhead_size()); | |
11095 | 331 _tiny_pool = new ChunkPool(Chunk::tiny_size + Chunk::aligned_overhead_size()); |
0 | 332 } |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
333 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
334 static void clean() { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
335 enum { BlocksToKeep = 5 }; |
11095 | 336 _tiny_pool->free_all_but(BlocksToKeep); |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
337 _small_pool->free_all_but(BlocksToKeep); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
338 _medium_pool->free_all_but(BlocksToKeep); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
339 _large_pool->free_all_but(BlocksToKeep); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
340 } |
0 | 341 }; |
342 | |
343 ChunkPool* ChunkPool::_large_pool = NULL; | |
344 ChunkPool* ChunkPool::_medium_pool = NULL; | |
345 ChunkPool* ChunkPool::_small_pool = NULL; | |
11095 | 346 ChunkPool* ChunkPool::_tiny_pool = NULL; |
0 | 347 |
348 void chunkpool_init() { | |
349 ChunkPool::initialize(); | |
350 } | |
351 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
352 void |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
353 Chunk::clean_chunk_pool() { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
354 ChunkPool::clean(); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
355 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
356 |
0 | 357 |
358 //-------------------------------------------------------------------------------------- | |
359 // ChunkPoolCleaner implementation | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
360 // |
0 | 361 |
362 class ChunkPoolCleaner : public PeriodicTask { | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
363 enum { CleaningInterval = 5000 }; // cleaning interval in ms |
0 | 364 |
365 public: | |
366 ChunkPoolCleaner() : PeriodicTask(CleaningInterval) {} | |
367 void task() { | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
368 ChunkPool::clean(); |
0 | 369 } |
370 }; | |
371 | |
372 //-------------------------------------------------------------------------------------- | |
373 // Chunk implementation | |
374 | |
12146
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
11095
diff
changeset
|
375 void* Chunk::operator new (size_t requested_size, AllocFailType alloc_failmode, size_t length) throw() { |
0 | 376 // requested_size is equal to sizeof(Chunk) but in order for the arena |
377 // allocations to come out aligned as expected the size must be aligned | |
10271
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
378 // to expected arena alignment. |
0 | 379 // expect requested_size but if sizeof(Chunk) doesn't match isn't proper size we must align it. |
380 assert(ARENA_ALIGN(requested_size) == aligned_overhead_size(), "Bad alignment"); | |
381 size_t bytes = ARENA_ALIGN(requested_size) + length; | |
382 switch (length) { | |
11009
f75faf51e8c4
7158805: Better rewriting of nested subroutine calls
hseigel
parents:
7176
diff
changeset
|
383 case Chunk::size: return ChunkPool::large_pool()->allocate(bytes, alloc_failmode); |
f75faf51e8c4
7158805: Better rewriting of nested subroutine calls
hseigel
parents:
7176
diff
changeset
|
384 case Chunk::medium_size: return ChunkPool::medium_pool()->allocate(bytes, alloc_failmode); |
f75faf51e8c4
7158805: Better rewriting of nested subroutine calls
hseigel
parents:
7176
diff
changeset
|
385 case Chunk::init_size: return ChunkPool::small_pool()->allocate(bytes, alloc_failmode); |
11095 | 386 case Chunk::tiny_size: return ChunkPool::tiny_pool()->allocate(bytes, alloc_failmode); |
0 | 387 default: { |
11009
f75faf51e8c4
7158805: Better rewriting of nested subroutine calls
hseigel
parents:
7176
diff
changeset
|
388 void* p = os::malloc(bytes, mtChunk, CALLER_PC); |
f75faf51e8c4
7158805: Better rewriting of nested subroutine calls
hseigel
parents:
7176
diff
changeset
|
389 if (p == NULL && alloc_failmode == AllocFailStrategy::EXIT_OOM) { |
10161
746b070f5022
8011661: Insufficient memory message says "malloc" when sometimes it should say "mmap"
ccheung
parents:
10135
diff
changeset
|
390 vm_exit_out_of_memory(bytes, OOM_MALLOC_ERROR, "Chunk::new"); |
11009
f75faf51e8c4
7158805: Better rewriting of nested subroutine calls
hseigel
parents:
7176
diff
changeset
|
391 } |
0 | 392 return p; |
393 } | |
394 } | |
395 } | |
396 | |
397 void Chunk::operator delete(void* p) { | |
398 Chunk* c = (Chunk*)p; | |
399 switch (c->length()) { | |
400 case Chunk::size: ChunkPool::large_pool()->free(c); break; | |
401 case Chunk::medium_size: ChunkPool::medium_pool()->free(c); break; | |
402 case Chunk::init_size: ChunkPool::small_pool()->free(c); break; | |
11095 | 403 case Chunk::tiny_size: ChunkPool::tiny_pool()->free(c); break; |
6197 | 404 default: os::free(c, mtChunk); |
0 | 405 } |
406 } | |
407 | |
408 Chunk::Chunk(size_t length) : _len(length) { | |
409 _next = NULL; // Chain on the linked list | |
410 } | |
411 | |
412 | |
413 void Chunk::chop() { | |
414 Chunk *k = this; | |
415 while( k ) { | |
416 Chunk *tmp = k->next(); | |
417 // clear out this chunk (to detect allocation bugs) | |
418 if (ZapResourceArea) memset(k->bottom(), badResourceValue, k->length()); | |
419 delete k; // Free chunk (was malloc'd) | |
420 k = tmp; | |
421 } | |
422 } | |
423 | |
424 void Chunk::next_chop() { | |
425 _next->chop(); | |
426 _next = NULL; | |
427 } | |
428 | |
429 | |
430 void Chunk::start_chunk_pool_cleaner_task() { | |
431 #ifdef ASSERT | |
432 static bool task_created = false; | |
433 assert(!task_created, "should not start chuck pool cleaner twice"); | |
434 task_created = true; | |
435 #endif | |
436 ChunkPoolCleaner* cleaner = new ChunkPoolCleaner(); | |
437 cleaner->enroll(); | |
438 } | |
439 | |
440 //------------------------------Arena------------------------------------------ | |
20360 | 441 Arena::Arena(MEMFLAGS flag, size_t init_size) : _flags(flag), _size_in_bytes(0) { |
0 | 442 size_t round_size = (sizeof (char *)) - 1; |
443 init_size = (init_size+round_size) & ~round_size; | |
11009
f75faf51e8c4
7158805: Better rewriting of nested subroutine calls
hseigel
parents:
7176
diff
changeset
|
444 _first = _chunk = new (AllocFailStrategy::EXIT_OOM, init_size) Chunk(init_size); |
0 | 445 _hwm = _chunk->bottom(); // Save the cached hwm, max |
446 _max = _chunk->top(); | |
20360 | 447 MemTracker::record_new_arena(flag); |
0 | 448 set_size_in_bytes(init_size); |
449 } | |
450 | |
20360 | 451 Arena::Arena(MEMFLAGS flag) : _flags(flag), _size_in_bytes(0) { |
11009
f75faf51e8c4
7158805: Better rewriting of nested subroutine calls
hseigel
parents:
7176
diff
changeset
|
452 _first = _chunk = new (AllocFailStrategy::EXIT_OOM, Chunk::init_size) Chunk(Chunk::init_size); |
0 | 453 _hwm = _chunk->bottom(); // Save the cached hwm, max |
454 _max = _chunk->top(); | |
20360 | 455 MemTracker::record_new_arena(flag); |
0 | 456 set_size_in_bytes(Chunk::init_size); |
457 } | |
458 | |
459 Arena *Arena::move_contents(Arena *copy) { | |
460 copy->destruct_contents(); | |
461 copy->_chunk = _chunk; | |
462 copy->_hwm = _hwm; | |
463 copy->_max = _max; | |
464 copy->_first = _first; | |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6872
diff
changeset
|
465 |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6872
diff
changeset
|
466 // workaround rare racing condition, which could double count |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6872
diff
changeset
|
467 // the arena size by native memory tracking |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6872
diff
changeset
|
468 size_t size = size_in_bytes(); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6872
diff
changeset
|
469 set_size_in_bytes(0); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6872
diff
changeset
|
470 copy->set_size_in_bytes(size); |
0 | 471 // Destroy original arena |
472 reset(); | |
473 return copy; // Return Arena with contents | |
474 } | |
475 | |
476 Arena::~Arena() { | |
477 destruct_contents(); | |
20360 | 478 MemTracker::record_arena_free(_flags); |
6197 | 479 } |
480 | |
12146
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
11095
diff
changeset
|
481 void* Arena::operator new(size_t size) throw() { |
6197 | 482 assert(false, "Use dynamic memory type binding"); |
483 return NULL; | |
484 } | |
485 | |
12146
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
11095
diff
changeset
|
486 void* Arena::operator new (size_t size, const std::nothrow_t& nothrow_constant) throw() { |
6197 | 487 assert(false, "Use dynamic memory type binding"); |
488 return NULL; | |
489 } | |
490 | |
491 // dynamic memory type binding | |
12146
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
11095
diff
changeset
|
492 void* Arena::operator new(size_t size, MEMFLAGS flags) throw() { |
6197 | 493 #ifdef ASSERT |
20360 | 494 void* p = (void*)AllocateHeap(size, flags, CALLER_PC); |
6197 | 495 if (PrintMallocFree) trace_heap_malloc(size, "Arena-new", p); |
496 return p; | |
497 #else | |
20360 | 498 return (void *) AllocateHeap(size, flags, CALLER_PC); |
6197 | 499 #endif |
500 } | |
501 | |
12146
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
11095
diff
changeset
|
502 void* Arena::operator new(size_t size, const std::nothrow_t& nothrow_constant, MEMFLAGS flags) throw() { |
6197 | 503 #ifdef ASSERT |
20360 | 504 void* p = os::malloc(size, flags, CALLER_PC); |
6197 | 505 if (PrintMallocFree) trace_heap_malloc(size, "Arena-new", p); |
506 return p; | |
507 #else | |
20360 | 508 return os::malloc(size, flags, CALLER_PC); |
6197 | 509 #endif |
510 } | |
511 | |
512 void Arena::operator delete(void* p) { | |
513 FreeHeap(p); | |
0 | 514 } |
515 | |
516 // Destroy this arenas contents and reset to empty | |
517 void Arena::destruct_contents() { | |
518 if (UseMallocOnly && _first != NULL) { | |
519 char* end = _first->next() ? _first->top() : _hwm; | |
520 free_malloced_objects(_first, _first->bottom(), end, _hwm); | |
521 } | |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6872
diff
changeset
|
522 // reset size before chop to avoid a rare racing condition |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6872
diff
changeset
|
523 // that can have total arena memory exceed total chunk memory |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6872
diff
changeset
|
524 set_size_in_bytes(0); |
0 | 525 _first->chop(); |
526 reset(); | |
527 } | |
528 | |
6197 | 529 // This is high traffic method, but many calls actually don't |
530 // change the size | |
531 void Arena::set_size_in_bytes(size_t size) { | |
532 if (_size_in_bytes != size) { | |
20360 | 533 long delta = (long)(size - size_in_bytes()); |
6197 | 534 _size_in_bytes = size; |
20360 | 535 MemTracker::record_arena_size_change(delta, _flags); |
6197 | 536 } |
537 } | |
0 | 538 |
539 // Total of all Chunks in arena | |
540 size_t Arena::used() const { | |
541 size_t sum = _chunk->length() - (_max-_hwm); // Size leftover in this Chunk | |
542 register Chunk *k = _first; | |
543 while( k != _chunk) { // Whilst have Chunks in a row | |
544 sum += k->length(); // Total size of this Chunk | |
545 k = k->next(); // Bump along to next Chunk | |
546 } | |
547 return sum; // Return total consumed space. | |
548 } | |
549 | |
2307
4a9604cd7c5f
6878713: Verifier heap corruption, relating to backward jsrs
kamg
parents:
2250
diff
changeset
|
550 void Arena::signal_out_of_memory(size_t sz, const char* whence) const { |
10161
746b070f5022
8011661: Insufficient memory message says "malloc" when sometimes it should say "mmap"
ccheung
parents:
10135
diff
changeset
|
551 vm_exit_out_of_memory(sz, OOM_MALLOC_ERROR, whence); |
2307
4a9604cd7c5f
6878713: Verifier heap corruption, relating to backward jsrs
kamg
parents:
2250
diff
changeset
|
552 } |
0 | 553 |
554 // Grow a new Chunk | |
6872
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
555 void* Arena::grow(size_t x, AllocFailType alloc_failmode) { |
0 | 556 // Get minimal required size. Either real big, or even bigger for giant objs |
557 size_t len = MAX2(x, (size_t) Chunk::size); | |
558 | |
559 Chunk *k = _chunk; // Get filled-up chunk address | |
11009
f75faf51e8c4
7158805: Better rewriting of nested subroutine calls
hseigel
parents:
7176
diff
changeset
|
560 _chunk = new (alloc_failmode, len) Chunk(len); |
0 | 561 |
2307
4a9604cd7c5f
6878713: Verifier heap corruption, relating to backward jsrs
kamg
parents:
2250
diff
changeset
|
562 if (_chunk == NULL) { |
17952
09619752c16d
8043086: Hotspot is expected to report OOM which is occurred String.intern(), but crashes in JDK8u5
poonam
parents:
17937
diff
changeset
|
563 _chunk = k; // restore the previous value of _chunk |
6872
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
564 return NULL; |
2307
4a9604cd7c5f
6878713: Verifier heap corruption, relating to backward jsrs
kamg
parents:
2250
diff
changeset
|
565 } |
0 | 566 if (k) k->set_next(_chunk); // Append new chunk to end of linked list |
567 else _first = _chunk; | |
568 _hwm = _chunk->bottom(); // Save the cached hwm, max | |
569 _max = _chunk->top(); | |
570 set_size_in_bytes(size_in_bytes() + len); | |
571 void* result = _hwm; | |
572 _hwm += x; | |
573 return result; | |
574 } | |
575 | |
576 | |
577 | |
578 // Reallocate storage in Arena. | |
6872
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
579 void *Arena::Arealloc(void* old_ptr, size_t old_size, size_t new_size, AllocFailType alloc_failmode) { |
0 | 580 assert(new_size >= 0, "bad size"); |
581 if (new_size == 0) return NULL; | |
582 #ifdef ASSERT | |
583 if (UseMallocOnly) { | |
584 // always allocate a new object (otherwise we'll free this one twice) | |
6872
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
585 char* copy = (char*)Amalloc(new_size, alloc_failmode); |
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
586 if (copy == NULL) { |
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
587 return NULL; |
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
588 } |
0 | 589 size_t n = MIN2(old_size, new_size); |
590 if (n > 0) memcpy(copy, old_ptr, n); | |
591 Afree(old_ptr,old_size); // Mostly done to keep stats accurate | |
592 return copy; | |
593 } | |
594 #endif | |
595 char *c_old = (char*)old_ptr; // Handy name | |
596 // Stupid fast special case | |
597 if( new_size <= old_size ) { // Shrink in-place | |
598 if( c_old+old_size == _hwm) // Attempt to free the excess bytes | |
599 _hwm = c_old+new_size; // Adjust hwm | |
600 return c_old; | |
601 } | |
602 | |
603 // make sure that new_size is legal | |
604 size_t corrected_new_size = ARENA_ALIGN(new_size); | |
605 | |
606 // See if we can resize in-place | |
607 if( (c_old+old_size == _hwm) && // Adjusting recent thing | |
608 (c_old+corrected_new_size <= _max) ) { // Still fits where it sits | |
609 _hwm = c_old+corrected_new_size; // Adjust hwm | |
610 return c_old; // Return old pointer | |
611 } | |
612 | |
613 // Oops, got to relocate guts | |
6872
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
614 void *new_ptr = Amalloc(new_size, alloc_failmode); |
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
615 if (new_ptr == NULL) { |
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
616 return NULL; |
7b5885dadbdc
8000617: It should be possible to allocate memory without the VM dying.
nloodin
parents:
6725
diff
changeset
|
617 } |
0 | 618 memcpy( new_ptr, c_old, old_size ); |
619 Afree(c_old,old_size); // Mostly done to keep stats accurate | |
620 return new_ptr; | |
621 } | |
622 | |
623 | |
624 // Determine if pointer belongs to this Arena or not. | |
625 bool Arena::contains( const void *ptr ) const { | |
626 #ifdef ASSERT | |
627 if (UseMallocOnly) { | |
628 // really slow, but not easy to make fast | |
629 if (_chunk == NULL) return false; | |
630 char** bottom = (char**)_chunk->bottom(); | |
631 for (char** p = (char**)_hwm - 1; p >= bottom; p--) { | |
632 if (*p == ptr) return true; | |
633 } | |
634 for (Chunk *c = _first; c != NULL; c = c->next()) { | |
635 if (c == _chunk) continue; // current chunk has been processed | |
636 char** bottom = (char**)c->bottom(); | |
637 for (char** p = (char**)c->top() - 1; p >= bottom; p--) { | |
638 if (*p == ptr) return true; | |
639 } | |
640 } | |
641 return false; | |
642 } | |
643 #endif | |
644 if( (void*)_chunk->bottom() <= ptr && ptr < (void*)_hwm ) | |
645 return true; // Check for in this chunk | |
646 for (Chunk *c = _first; c; c = c->next()) { | |
647 if (c == _chunk) continue; // current chunk has been processed | |
648 if ((void*)c->bottom() <= ptr && ptr < (void*)c->top()) { | |
649 return true; // Check for every chunk in Arena | |
650 } | |
651 } | |
652 return false; // Not in any Chunk, so not in Arena | |
653 } | |
654 | |
655 | |
656 #ifdef ASSERT | |
657 void* Arena::malloc(size_t size) { | |
658 assert(UseMallocOnly, "shouldn't call"); | |
659 // use malloc, but save pointer in res. area for later freeing | |
660 char** save = (char**)internal_malloc_4(sizeof(char*)); | |
6197 | 661 return (*save = (char*)os::malloc(size, mtChunk)); |
0 | 662 } |
663 | |
664 // for debugging with UseMallocOnly | |
665 void* Arena::internal_malloc_4(size_t x) { | |
666 assert( (x&(sizeof(char*)-1)) == 0, "misaligned size" ); | |
2307
4a9604cd7c5f
6878713: Verifier heap corruption, relating to backward jsrs
kamg
parents:
2250
diff
changeset
|
667 check_for_overflow(x, "Arena::internal_malloc_4"); |
0 | 668 if (_hwm + x > _max) { |
669 return grow(x); | |
670 } else { | |
671 char *old = _hwm; | |
672 _hwm += x; | |
673 return old; | |
674 } | |
675 } | |
676 #endif | |
677 | |
678 | |
679 //-------------------------------------------------------------------------------------- | |
680 // Non-product code | |
681 | |
682 #ifndef PRODUCT | |
683 // The global operator new should never be called since it will usually indicate | |
684 // a memory leak. Use CHeapObj as the base class of such objects to make it explicit | |
685 // that they're allocated on the C heap. | |
686 // Commented out in product version to avoid conflicts with third-party C++ native code. | |
10271
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
687 // On certain platforms, such as Mac OS X (Darwin), in debug version, new is being called |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
688 // from jdk source and causing data corruption. Such as |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
689 // Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
690 // define ALLOW_OPERATOR_NEW_USAGE for platform on which global operator new allowed. |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
691 // |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
692 #ifndef ALLOW_OPERATOR_NEW_USAGE |
12146
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
11095
diff
changeset
|
693 void* operator new(size_t size) throw() { |
10271
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
694 assert(false, "Should not call global operator new"); |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
695 return 0; |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
696 } |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
697 |
12146
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
11095
diff
changeset
|
698 void* operator new [](size_t size) throw() { |
10271
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
699 assert(false, "Should not call global operator new[]"); |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
700 return 0; |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
701 } |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
702 |
12146
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
11095
diff
changeset
|
703 void* operator new(size_t size, const std::nothrow_t& nothrow_constant) throw() { |
10271
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
704 assert(false, "Should not call global operator new"); |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
705 return 0; |
0 | 706 } |
10271
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
707 |
12146
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
11095
diff
changeset
|
708 void* operator new [](size_t size, std::nothrow_t& nothrow_constant) throw() { |
10271
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
709 assert(false, "Should not call global operator new[]"); |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
710 return 0; |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
711 } |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
712 |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
713 void operator delete(void* p) { |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
714 assert(false, "Should not call global delete"); |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
715 } |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
716 |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
717 void operator delete [](void* p) { |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
718 assert(false, "Should not call global delete []"); |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
719 } |
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10161
diff
changeset
|
720 #endif // ALLOW_OPERATOR_NEW_USAGE |
0 | 721 |
722 void AllocatedObj::print() const { print_on(tty); } | |
723 void AllocatedObj::print_value() const { print_value_on(tty); } | |
724 | |
725 void AllocatedObj::print_on(outputStream* st) const { | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17935
diff
changeset
|
726 st->print_cr("AllocatedObj(" INTPTR_FORMAT ")", p2i(this)); |
0 | 727 } |
728 | |
729 void AllocatedObj::print_value_on(outputStream* st) const { | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17935
diff
changeset
|
730 st->print("AllocatedObj(" INTPTR_FORMAT ")", p2i(this)); |
0 | 731 } |
732 | |
2250 | 733 julong Arena::_bytes_allocated = 0; |
734 | |
735 void Arena::inc_bytes_allocated(size_t x) { inc_stat_counter(&_bytes_allocated, x); } | |
0 | 736 |
737 AllocStats::AllocStats() { | |
2250 | 738 start_mallocs = os::num_mallocs; |
739 start_frees = os::num_frees; | |
0 | 740 start_malloc_bytes = os::alloc_bytes; |
2250 | 741 start_mfree_bytes = os::free_bytes; |
742 start_res_bytes = Arena::_bytes_allocated; | |
0 | 743 } |
744 | |
2250 | 745 julong AllocStats::num_mallocs() { return os::num_mallocs - start_mallocs; } |
746 julong AllocStats::alloc_bytes() { return os::alloc_bytes - start_malloc_bytes; } | |
747 julong AllocStats::num_frees() { return os::num_frees - start_frees; } | |
748 julong AllocStats::free_bytes() { return os::free_bytes - start_mfree_bytes; } | |
749 julong AllocStats::resource_bytes() { return Arena::_bytes_allocated - start_res_bytes; } | |
0 | 750 void AllocStats::print() { |
2250 | 751 tty->print_cr(UINT64_FORMAT " mallocs (" UINT64_FORMAT "MB), " |
752 UINT64_FORMAT" frees (" UINT64_FORMAT "MB), " UINT64_FORMAT "MB resrc", | |
753 num_mallocs(), alloc_bytes()/M, num_frees(), free_bytes()/M, resource_bytes()/M); | |
0 | 754 } |
755 | |
756 | |
757 // debugging code | |
758 inline void Arena::free_all(char** start, char** end) { | |
759 for (char** p = start; p < end; p++) if (*p) os::free(*p); | |
760 } | |
761 | |
762 void Arena::free_malloced_objects(Chunk* chunk, char* hwm, char* max, char* hwm2) { | |
763 assert(UseMallocOnly, "should not call"); | |
764 // free all objects malloced since resource mark was created; resource area | |
765 // contains their addresses | |
766 if (chunk->next()) { | |
767 // this chunk is full, and some others too | |
768 for (Chunk* c = chunk->next(); c != NULL; c = c->next()) { | |
769 char* top = c->top(); | |
770 if (c->next() == NULL) { | |
771 top = hwm2; // last junk is only used up to hwm2 | |
772 assert(c->contains(hwm2), "bad hwm2"); | |
773 } | |
774 free_all((char**)c->bottom(), (char**)top); | |
775 } | |
776 assert(chunk->contains(hwm), "bad hwm"); | |
777 assert(chunk->contains(max), "bad max"); | |
778 free_all((char**)hwm, (char**)max); | |
779 } else { | |
780 // this chunk was partially used | |
781 assert(chunk->contains(hwm), "bad hwm"); | |
782 assert(chunk->contains(hwm2), "bad hwm2"); | |
783 free_all((char**)hwm, (char**)hwm2); | |
784 } | |
785 } | |
786 | |
787 | |
788 ReallocMark::ReallocMark() { | |
789 #ifdef ASSERT | |
790 Thread *thread = ThreadLocalStorage::get_thread_slow(); | |
791 _nesting = thread->resource_area()->nesting(); | |
792 #endif | |
793 } | |
794 | |
795 void ReallocMark::check() { | |
796 #ifdef ASSERT | |
797 if (_nesting != Thread::current()->resource_area()->nesting()) { | |
798 fatal("allocation bug: array could grow within nested ResourceMark"); | |
799 } | |
800 #endif | |
801 } | |
802 | |
803 #endif // Non-product |