293
294 inline const FlagAccessImpl* JVMFlagAccess::access_impl(const JVMFlag* flag) {
295 int type = flag->type();
296 int max = (int)(sizeof(flag_accesss)/sizeof(flag_accesss[0]));
297 assert(type >= 0 && type < max , "sanity");
298
299 return flag_accesss[type];
300 }
301
302 JVMFlag::Error JVMFlagAccess::set_impl(JVMFlag* flag, void* value, JVMFlagOrigin origin) {
303 if (flag->is_ccstr()) {
304 return set_ccstr(flag, (ccstr*)value, origin);
305 } else {
306 return access_impl(flag)->set(flag, value, origin);
307 }
308 }
309
310 JVMFlag::Error JVMFlagAccess::set_ccstr(JVMFlag* flag, ccstr* value, JVMFlagOrigin origin) {
311 if (flag == nullptr) return JVMFlag::INVALID_FLAG;
312 if (!flag->is_ccstr()) return JVMFlag::WRONG_FORMAT;
313 ccstr old_value = flag->get_ccstr();
314 trace_flag_changed<ccstr, EventStringFlagChanged>(flag, old_value, *value, origin);
315 char* new_value = nullptr;
316 if (*value != nullptr) {
317 new_value = os::strdup_check_oom(*value);
318 }
319 flag->set_ccstr(new_value);
320 if (!flag->is_default() && old_value != nullptr) {
321 // Old value is heap allocated so free it.
322 FREE_C_HEAP_ARRAY(char, old_value);
323 }
324 // Unlike the other APIs, the old value is NOT returned, so the caller won't need to free it.
325 // The callers typically don't care what the old value is.
326 // If the caller really wants to know the old value, read it (and make a copy if necessary)
327 // before calling this API.
328 *value = nullptr;
329 flag->set_origin(origin);
330 return JVMFlag::SUCCESS;
331 }
332
|
293
294 inline const FlagAccessImpl* JVMFlagAccess::access_impl(const JVMFlag* flag) {
295 int type = flag->type();
296 int max = (int)(sizeof(flag_accesss)/sizeof(flag_accesss[0]));
297 assert(type >= 0 && type < max , "sanity");
298
299 return flag_accesss[type];
300 }
301
302 JVMFlag::Error JVMFlagAccess::set_impl(JVMFlag* flag, void* value, JVMFlagOrigin origin) {
303 if (flag->is_ccstr()) {
304 return set_ccstr(flag, (ccstr*)value, origin);
305 } else {
306 return access_impl(flag)->set(flag, value, origin);
307 }
308 }
309
310 JVMFlag::Error JVMFlagAccess::set_ccstr(JVMFlag* flag, ccstr* value, JVMFlagOrigin origin) {
311 if (flag == nullptr) return JVMFlag::INVALID_FLAG;
312 if (!flag->is_ccstr()) return JVMFlag::WRONG_FORMAT;
313 const JVMTypedFlagLimit<ccstr>* constraint = (const JVMTypedFlagLimit<ccstr>*)JVMFlagLimit::get_constraint(flag);
314 if (constraint != nullptr && constraint->phase() <= JVMFlagLimit::validating_phase()) {
315 bool verbose = JVMFlagLimit::verbose_checks_needed() | (origin == JVMFlagOrigin::ERGONOMIC);
316 JVMFlag::Error err = ((JVMFlagConstraintFunc_ccstr)constraint->constraint_func())(*value, verbose);
317 if (err != JVMFlag::SUCCESS) {
318 if (origin == JVMFlagOrigin::ERGONOMIC) {
319 fatal("FLAG_SET_ERGO cannot be used to set an invalid value for %s", flag->name());
320 }
321 return err;
322 }
323 }
324 ccstr old_value = flag->get_ccstr();
325 trace_flag_changed<ccstr, EventStringFlagChanged>(flag, old_value, *value, origin);
326 char* new_value = nullptr;
327 if (*value != nullptr) {
328 new_value = os::strdup_check_oom(*value);
329 }
330 flag->set_ccstr(new_value);
331 if (!flag->is_default() && old_value != nullptr) {
332 // Old value is heap allocated so free it.
333 FREE_C_HEAP_ARRAY(char, old_value);
334 }
335 // Unlike the other APIs, the old value is NOT returned, so the caller won't need to free it.
336 // The callers typically don't care what the old value is.
337 // If the caller really wants to know the old value, read it (and make a copy if necessary)
338 // before calling this API.
339 *value = nullptr;
340 flag->set_origin(origin);
341 return JVMFlag::SUCCESS;
342 }
343
|