65 _usage_threshold = new ThresholdSupport(support_usage_threshold, support_usage_threshold);
66 // gc usage threshold supports only high threshold
67 _gc_usage_threshold = new ThresholdSupport(support_gc_threshold, support_gc_threshold);
68 }
69
70 void MemoryPool::add_manager(MemoryManager* mgr) {
71 assert(_num_managers < MemoryPool::max_num_managers, "_num_managers exceeds the max");
72 if (_num_managers < MemoryPool::max_num_managers) {
73 _managers[_num_managers] = mgr;
74 _num_managers++;
75 }
76 }
77
78
79 // Returns an instanceHandle of a MemoryPool object.
80 // It creates a MemoryPool instance when the first time
81 // this function is called.
82 instanceOop MemoryPool::get_memory_pool_instance(TRAPS) {
83 // Must do an acquire so as to force ordering of subsequent
84 // loads from anything _memory_pool_obj points to or implies.
85 instanceOop pool_obj = (instanceOop)OrderAccess::load_ptr_acquire(&_memory_pool_obj);
86 if (pool_obj == NULL) {
87 // It's ok for more than one thread to execute the code up to the locked region.
88 // Extra pool instances will just be gc'ed.
89 InstanceKlass* ik = Management::sun_management_ManagementFactoryHelper_klass(CHECK_NULL);
90
91 Handle pool_name = java_lang_String::create_from_str(_name, CHECK_NULL);
92 jlong usage_threshold_value = (_usage_threshold->is_high_threshold_supported() ? 0 : -1L);
93 jlong gc_usage_threshold_value = (_gc_usage_threshold->is_high_threshold_supported() ? 0 : -1L);
94
95 JavaValue result(T_OBJECT);
96 JavaCallArguments args;
97 args.push_oop(pool_name); // Argument 1
98 args.push_int((int) is_heap()); // Argument 2
99
100 Symbol* method_name = vmSymbols::createMemoryPool_name();
101 Symbol* signature = vmSymbols::createMemoryPool_signature();
102
103 args.push_long(usage_threshold_value); // Argument 3
104 args.push_long(gc_usage_threshold_value); // Argument 4
105
106 JavaCalls::call_static(&result,
107 ik,
108 method_name,
109 signature,
110 &args,
111 CHECK_NULL);
112
113 instanceOop p = (instanceOop) result.get_jobject();
114 instanceHandle pool(THREAD, p);
115
116 {
117 // Get lock since another thread may have create the instance
118 MutexLocker ml(Management_lock);
119
120 // Check if another thread has created the pool. We reload
121 // _memory_pool_obj here because some other thread may have
122 // initialized it while we were executing the code before the lock.
123 //
124 // The lock has done an acquire, so the load can't float above it,
125 // but we need to do a load_acquire as above.
126 pool_obj = (instanceOop)OrderAccess::load_ptr_acquire(&_memory_pool_obj);
127 if (pool_obj != NULL) {
128 return pool_obj;
129 }
130
131 // Get the address of the object we created via call_special.
132 pool_obj = pool();
133
134 // Use store barrier to make sure the memory accesses associated
135 // with creating the pool are visible before publishing its address.
136 // The unlock will publish the store to _memory_pool_obj because
137 // it does a release first.
138 OrderAccess::release_store_ptr(&_memory_pool_obj, pool_obj);
139 }
140 }
141
142 return pool_obj;
143 }
144
145 inline static size_t get_max_value(size_t val1, size_t val2) {
146 return (val1 > val2 ? val1 : val2);
147 }
148
149 void MemoryPool::record_peak_memory_usage() {
150 // Caller in JDK is responsible for synchronization -
151 // acquire the lock for this memory pool before calling VM
152 MemoryUsage usage = get_memory_usage();
153 size_t peak_used = get_max_value(usage.used(), _peak_usage.used());
154 size_t peak_committed = get_max_value(usage.committed(), _peak_usage.committed());
155 size_t peak_max_size = get_max_value(usage.max_size(), _peak_usage.max_size());
156
157 _peak_usage = MemoryUsage(initial_size(), peak_used, peak_committed, peak_max_size);
158 }
|
65 _usage_threshold = new ThresholdSupport(support_usage_threshold, support_usage_threshold);
66 // gc usage threshold supports only high threshold
67 _gc_usage_threshold = new ThresholdSupport(support_gc_threshold, support_gc_threshold);
68 }
69
70 void MemoryPool::add_manager(MemoryManager* mgr) {
71 assert(_num_managers < MemoryPool::max_num_managers, "_num_managers exceeds the max");
72 if (_num_managers < MemoryPool::max_num_managers) {
73 _managers[_num_managers] = mgr;
74 _num_managers++;
75 }
76 }
77
78
79 // Returns an instanceHandle of a MemoryPool object.
80 // It creates a MemoryPool instance when the first time
81 // this function is called.
82 instanceOop MemoryPool::get_memory_pool_instance(TRAPS) {
83 // Must do an acquire so as to force ordering of subsequent
84 // loads from anything _memory_pool_obj points to or implies.
85 instanceOop pool_obj = OrderAccess::load_acquire(&_memory_pool_obj);
86 if (pool_obj == NULL) {
87 // It's ok for more than one thread to execute the code up to the locked region.
88 // Extra pool instances will just be gc'ed.
89 InstanceKlass* ik = Management::sun_management_ManagementFactoryHelper_klass(CHECK_NULL);
90
91 Handle pool_name = java_lang_String::create_from_str(_name, CHECK_NULL);
92 jlong usage_threshold_value = (_usage_threshold->is_high_threshold_supported() ? 0 : -1L);
93 jlong gc_usage_threshold_value = (_gc_usage_threshold->is_high_threshold_supported() ? 0 : -1L);
94
95 JavaValue result(T_OBJECT);
96 JavaCallArguments args;
97 args.push_oop(pool_name); // Argument 1
98 args.push_int((int) is_heap()); // Argument 2
99
100 Symbol* method_name = vmSymbols::createMemoryPool_name();
101 Symbol* signature = vmSymbols::createMemoryPool_signature();
102
103 args.push_long(usage_threshold_value); // Argument 3
104 args.push_long(gc_usage_threshold_value); // Argument 4
105
106 JavaCalls::call_static(&result,
107 ik,
108 method_name,
109 signature,
110 &args,
111 CHECK_NULL);
112
113 instanceOop p = (instanceOop) result.get_jobject();
114 instanceHandle pool(THREAD, p);
115
116 {
117 // Get lock since another thread may have create the instance
118 MutexLocker ml(Management_lock);
119
120 // Check if another thread has created the pool. We reload
121 // _memory_pool_obj here because some other thread may have
122 // initialized it while we were executing the code before the lock.
123 //
124 // The lock has done an acquire, so the load can't float above it,
125 // but we need to do a load_acquire as above.
126 pool_obj = OrderAccess::load_acquire(&_memory_pool_obj);
127 if (pool_obj != NULL) {
128 return pool_obj;
129 }
130
131 // Get the address of the object we created via call_special.
132 pool_obj = pool();
133
134 // Use store barrier to make sure the memory accesses associated
135 // with creating the pool are visible before publishing its address.
136 // The unlock will publish the store to _memory_pool_obj because
137 // it does a release first.
138 OrderAccess::release_store(&_memory_pool_obj, pool_obj);
139 }
140 }
141
142 return pool_obj;
143 }
144
145 inline static size_t get_max_value(size_t val1, size_t val2) {
146 return (val1 > val2 ? val1 : val2);
147 }
148
149 void MemoryPool::record_peak_memory_usage() {
150 // Caller in JDK is responsible for synchronization -
151 // acquire the lock for this memory pool before calling VM
152 MemoryUsage usage = get_memory_usage();
153 size_t peak_used = get_max_value(usage.used(), _peak_usage.used());
154 size_t peak_committed = get_max_value(usage.committed(), _peak_usage.committed());
155 size_t peak_max_size = get_max_value(usage.max_size(), _peak_usage.max_size());
156
157 _peak_usage = MemoryUsage(initial_size(), peak_used, peak_committed, peak_max_size);
158 }
|