--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Fri Oct 04 14:19:56 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Tue Oct 08 07:08:27 2013 -0700
@@ -3053,7 +3053,11 @@
int offset = -1;
LIR_Opr counter_holder;
if (level == CompLevel_limited_profile) {
- address counters_adr = method->ensure_method_counters();
+ MethodCounters* counters_adr = method->ensure_method_counters();
+ if (counters_adr == NULL) {
+ bailout("method counters allocation failed");
+ return;
+ }
counter_holder = new_pointer_register();
__ move(LIR_OprFact::intptrConst(counters_adr), counter_holder);
offset = in_bytes(backedge ? MethodCounters::backedge_counter_offset() :
--- a/hotspot/src/share/vm/ci/ciEnv.cpp Fri Oct 04 14:19:56 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp Tue Oct 08 07:08:27 2013 -0700
@@ -1154,9 +1154,12 @@
GUARDED_VM_ENTRY(return _factory->get_unloaded_object_constant();)
}
-void ciEnv::dump_replay_data(outputStream* out) {
- VM_ENTRY_MARK;
- MutexLocker ml(Compile_lock);
+// ------------------------------------------------------------------
+// ciEnv::dump_replay_data*
+
+// Don't change thread state and acquire any locks.
+// Safe to call from VM error reporter.
+void ciEnv::dump_replay_data_unsafe(outputStream* out) {
ResourceMark rm;
#if INCLUDE_JVMTI
out->print_cr("JvmtiExport can_access_local_variables %d", _jvmti_can_access_local_variables);
@@ -1181,3 +1184,10 @@
entry_bci, comp_level);
out->flush();
}
+
+void ciEnv::dump_replay_data(outputStream* out) {
+ GUARDED_VM_ENTRY(
+ MutexLocker ml(Compile_lock);
+ dump_replay_data_unsafe(out);
+ )
+}
--- a/hotspot/src/share/vm/ci/ciEnv.hpp Fri Oct 04 14:19:56 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciEnv.hpp Tue Oct 08 07:08:27 2013 -0700
@@ -452,6 +452,7 @@
// Dump the compilation replay data for the ciEnv to the stream.
void dump_replay_data(outputStream* out);
+ void dump_replay_data_unsafe(outputStream* out);
};
#endif // SHARE_VM_CI_CIENV_HPP
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Fri Oct 04 14:19:56 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Tue Oct 08 07:08:27 2013 -0700
@@ -671,7 +671,6 @@
void ciInstanceKlass::dump_replay_data(outputStream* out) {
- ASSERT_IN_VM;
ResourceMark rm;
InstanceKlass* ik = get_instanceKlass();
--- a/hotspot/src/share/vm/ci/ciMethod.cpp Fri Oct 04 14:19:56 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp Tue Oct 08 07:08:27 2013 -0700
@@ -846,7 +846,9 @@
// Return true if allocation was successful or no MDO is required.
bool ciMethod::ensure_method_data(methodHandle h_m) {
EXCEPTION_CONTEXT;
- if (is_native() || is_abstract() || h_m()->is_accessor()) return true;
+ if (is_native() || is_abstract() || h_m()->is_accessor()) {
+ return true;
+ }
if (h_m()->method_data() == NULL) {
Method::build_interpreter_method_data(h_m, THREAD);
if (HAS_PENDING_EXCEPTION) {
@@ -903,22 +905,21 @@
// NULL otherwise.
ciMethodData* ciMethod::method_data_or_null() {
ciMethodData *md = method_data();
- if (md->is_empty()) return NULL;
+ if (md->is_empty()) {
+ return NULL;
+ }
return md;
}
// ------------------------------------------------------------------
// ciMethod::ensure_method_counters
//
-address ciMethod::ensure_method_counters() {
+MethodCounters* ciMethod::ensure_method_counters() {
check_is_loaded();
VM_ENTRY_MARK;
methodHandle mh(THREAD, get_Method());
- MethodCounters *counter = mh->method_counters();
- if (counter == NULL) {
- counter = Method::build_method_counters(mh(), CHECK_AND_CLEAR_NULL);
- }
- return (address)counter;
+ MethodCounters* method_counters = mh->get_method_counters(CHECK_NULL);
+ return method_counters;
}
// ------------------------------------------------------------------
@@ -1247,7 +1248,6 @@
#undef FETCH_FLAG_FROM_VM
void ciMethod::dump_replay_data(outputStream* st) {
- ASSERT_IN_VM;
ResourceMark rm;
Method* method = get_Method();
MethodCounters* mcs = method->method_counters();
--- a/hotspot/src/share/vm/ci/ciMethod.hpp Fri Oct 04 14:19:56 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciMethod.hpp Tue Oct 08 07:08:27 2013 -0700
@@ -265,7 +265,7 @@
bool is_klass_loaded(int refinfo_index, bool must_be_resolved) const;
bool check_call(int refinfo_index, bool is_static) const;
bool ensure_method_data(); // make sure it exists in the VM also
- address ensure_method_counters();
+ MethodCounters* ensure_method_counters();
int instructions_size();
int scale_count(int count, float prof_factor = 1.); // make MDO count commensurate with IIC
--- a/hotspot/src/share/vm/ci/ciMethodData.cpp Fri Oct 04 14:19:56 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciMethodData.cpp Tue Oct 08 07:08:27 2013 -0700
@@ -78,7 +78,9 @@
void ciMethodData::load_data() {
MethodData* mdo = get_MethodData();
- if (mdo == NULL) return;
+ if (mdo == NULL) {
+ return;
+ }
// To do: don't copy the data if it is not "ripe" -- require a minimum #
// of invocations.
@@ -373,7 +375,6 @@
}
void ciMethodData::dump_replay_data(outputStream* out) {
- ASSERT_IN_VM;
ResourceMark rm;
MethodData* mdo = get_MethodData();
Method* method = mdo->method();
--- a/hotspot/src/share/vm/ci/ciMethodData.hpp Fri Oct 04 14:19:56 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciMethodData.hpp Tue Oct 08 07:08:27 2013 -0700
@@ -232,8 +232,6 @@
public:
bool is_method_data() const { return true; }
- void set_mature() { _state = mature_state; }
-
bool is_empty() { return _state == empty_state; }
bool is_mature() { return _state == mature_state; }
--- a/hotspot/src/share/vm/ci/ciReplay.cpp Fri Oct 04 14:19:56 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciReplay.cpp Tue Oct 08 07:08:27 2013 -0700
@@ -965,14 +965,12 @@
tty->cr();
} else {
EXCEPTION_CONTEXT;
- MethodCounters* mcs = method->method_counters();
// m->_instructions_size = rec->instructions_size;
m->_instructions_size = -1;
m->_interpreter_invocation_count = rec->interpreter_invocation_count;
m->_interpreter_throwout_count = rec->interpreter_throwout_count;
- if (mcs == NULL) {
- mcs = Method::build_method_counters(method, CHECK_AND_CLEAR);
- }
+ MethodCounters* mcs = method->get_method_counters(CHECK_AND_CLEAR);
+ guarantee(mcs != NULL, "method counters allocation failed");
mcs->invocation_counter()->_counter = rec->invocation_counter;
mcs->backedge_counter()->_counter = rec->backedge_counter;
}
--- a/hotspot/src/share/vm/classfile/defaultMethods.cpp Fri Oct 04 14:19:56 2013 -0700
+++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp Tue Oct 08 07:08:27 2013 -0700
@@ -898,7 +898,6 @@
m->set_max_locals(params);
m->constMethod()->set_stackmap_data(NULL);
m->set_code(code_start);
- m->set_force_inline(true);
return m;
}
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Fri Oct 04 14:19:56 2013 -0700
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Tue Oct 08 07:08:27 2013 -0700
@@ -1953,6 +1953,10 @@
// Since code cache is full, immediately stop new compiles
if (CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation)) {
NMethodSweeper::log_sweep("disable_compiler");
+
+ // Switch to 'vm_state'. This ensures that possibly_sweep() can be called
+ // without having to consider the state in which the current thread is.
+ ThreadInVMfromUnknown in_vm;
NMethodSweeper::possibly_sweep();
}
} else {
--- a/hotspot/src/share/vm/oops/method.hpp Fri Oct 04 14:19:56 2013 -0700
+++ b/hotspot/src/share/vm/oops/method.hpp Tue Oct 08 07:08:27 2013 -0700
@@ -804,6 +804,7 @@
private:
void print_made_not_compilable(int comp_level, bool is_osr, bool report, const char* reason);
+ public:
MethodCounters* get_method_counters(TRAPS) {
if (_method_counters == NULL) {
build_method_counters(this, CHECK_AND_CLEAR_NULL);
@@ -811,7 +812,6 @@
return _method_counters;
}
- public:
bool is_not_c1_compilable() const { return access_flags().is_not_c1_compilable(); }
void set_not_c1_compilable() { _access_flags.set_not_c1_compilable(); }
void clear_not_c1_compilable() { _access_flags.clear_not_c1_compilable(); }
--- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp Fri Oct 04 14:19:56 2013 -0700
+++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp Tue Oct 08 07:08:27 2013 -0700
@@ -197,6 +197,7 @@
// negative filter: should callee NOT be inlined?
bool InlineTree::should_not_inline(ciMethod *callee_method,
ciMethod* caller_method,
+ JVMState* jvms,
WarmCallInfo* wci_result) {
const char* fail_msg = NULL;
@@ -226,7 +227,7 @@
// don't inline exception code unless the top method belongs to an
// exception class
if (callee_method->holder()->is_subclass_of(C->env()->Throwable_klass())) {
- ciMethod* top_method = caller_jvms() ? caller_jvms()->of_depth(1)->method() : method();
+ ciMethod* top_method = jvms->caller() != NULL ? jvms->caller()->of_depth(1)->method() : method();
if (!top_method->holder()->is_subclass_of(C->env()->Throwable_klass())) {
wci_result->set_profit(wci_result->profit() * 0.1);
}
@@ -328,7 +329,7 @@
// return true if ok
// Relocated from "InliningClosure::try_to_inline"
bool InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method,
- int caller_bci, ciCallProfile& profile,
+ int caller_bci, JVMState* jvms, ciCallProfile& profile,
WarmCallInfo* wci_result, bool& should_delay) {
// Old algorithm had funny accumulating BC-size counters
@@ -346,7 +347,7 @@
wci_result)) {
return false;
}
- if (should_not_inline(callee_method, caller_method, wci_result)) {
+ if (should_not_inline(callee_method, caller_method, jvms, wci_result)) {
return false;
}
@@ -397,24 +398,35 @@
}
// detect direct and indirect recursive inlining
- if (!callee_method->is_compiled_lambda_form()) {
+ {
// count the current method and the callee
- int inline_level = (method() == callee_method) ? 1 : 0;
- if (inline_level > MaxRecursiveInlineLevel) {
- set_msg("recursively inlining too deep");
- return false;
+ const bool is_compiled_lambda_form = callee_method->is_compiled_lambda_form();
+ int inline_level = 0;
+ if (!is_compiled_lambda_form) {
+ if (method() == callee_method) {
+ inline_level++;
+ }
}
// count callers of current method and callee
- JVMState* jvms = caller_jvms();
- while (jvms != NULL && jvms->has_method()) {
- if (jvms->method() == callee_method) {
- inline_level++;
- if (inline_level > MaxRecursiveInlineLevel) {
- set_msg("recursively inlining too deep");
- return false;
+ Node* callee_argument0 = is_compiled_lambda_form ? jvms->map()->argument(jvms, 0)->uncast() : NULL;
+ for (JVMState* j = jvms->caller(); j != NULL && j->has_method(); j = j->caller()) {
+ if (j->method() == callee_method) {
+ if (is_compiled_lambda_form) {
+ // Since compiled lambda forms are heavily reused we allow recursive inlining. If it is truly
+ // a recursion (using the same "receiver") we limit inlining otherwise we can easily blow the
+ // compiler stack.
+ Node* caller_argument0 = j->map()->argument(j, 0)->uncast();
+ if (caller_argument0 == callee_argument0) {
+ inline_level++;
+ }
+ } else {
+ inline_level++;
}
}
- jvms = jvms->caller();
+ }
+ if (inline_level > MaxRecursiveInlineLevel) {
+ set_msg("recursive inlining is too deep");
+ return false;
}
}
@@ -536,7 +548,7 @@
// Check if inlining policy says no.
WarmCallInfo wci = *(initial_wci);
bool success = try_to_inline(callee_method, caller_method, caller_bci,
- profile, &wci, should_delay);
+ jvms, profile, &wci, should_delay);
#ifndef PRODUCT
if (UseOldInlining && InlineWarmCalls
--- a/hotspot/src/share/vm/opto/graphKit.cpp Fri Oct 04 14:19:56 2013 -0700
+++ b/hotspot/src/share/vm/opto/graphKit.cpp Tue Oct 08 07:08:27 2013 -0700
@@ -2122,7 +2122,7 @@
// Null check oop. Set null-path control into Region in slot 3.
// Make a cast-not-nullness use the other not-null control. Return cast.
Node* GraphKit::null_check_oop(Node* value, Node* *null_control,
- bool never_see_null) {
+ bool never_see_null, bool safe_for_replace) {
// Initial NULL check taken path
(*null_control) = top();
Node* cast = null_check_common(value, T_OBJECT, false, null_control);
@@ -2140,6 +2140,9 @@
Deoptimization::Action_make_not_entrant);
(*null_control) = top(); // NULL path is dead
}
+ if ((*null_control) == top() && safe_for_replace) {
+ replace_in_map(value, cast);
+ }
// Cast away null-ness on the result
return cast;
@@ -2634,15 +2637,17 @@
C->set_has_split_ifs(true); // Has chance for split-if optimization
ciProfileData* data = NULL;
+ bool safe_for_replace = false;
if (java_bc() == Bytecodes::_instanceof) { // Only for the bytecode
data = method()->method_data()->bci_to_data(bci());
+ safe_for_replace = true;
}
bool never_see_null = (ProfileDynamicTypes // aggressive use of profile
&& seems_never_null(obj, data));
// Null check; get casted pointer; set region slot 3
Node* null_ctl = top();
- Node* not_null_obj = null_check_oop(obj, &null_ctl, never_see_null);
+ Node* not_null_obj = null_check_oop(obj, &null_ctl, never_see_null, safe_for_replace);
// If not_null_obj is dead, only null-path is taken
if (stopped()) { // Doing instance-of on a NULL?
@@ -2723,11 +2728,13 @@
}
ciProfileData* data = NULL;
+ bool safe_for_replace = false;
if (failure_control == NULL) { // use MDO in regular case only
assert(java_bc() == Bytecodes::_aastore ||
java_bc() == Bytecodes::_checkcast,
"interpreter profiles type checks only for these BCs");
data = method()->method_data()->bci_to_data(bci());
+ safe_for_replace = true;
}
// Make the merge point
@@ -2742,7 +2749,7 @@
// Null check; get casted pointer; set region slot 3
Node* null_ctl = top();
- Node* not_null_obj = null_check_oop(obj, &null_ctl, never_see_null);
+ Node* not_null_obj = null_check_oop(obj, &null_ctl, never_see_null, safe_for_replace);
// If not_null_obj is dead, only null-path is taken
if (stopped()) { // Doing instance-of on a NULL?
--- a/hotspot/src/share/vm/opto/graphKit.hpp Fri Oct 04 14:19:56 2013 -0700
+++ b/hotspot/src/share/vm/opto/graphKit.hpp Tue Oct 08 07:08:27 2013 -0700
@@ -378,8 +378,10 @@
// Return a cast-not-null node which depends on the not-null control.
// If never_see_null, use an uncommon trap (*null_control sees a top).
// The cast is not valid along the null path; keep a copy of the original.
+ // If safe_for_replace, then we can replace the value with the cast
+ // in the parsing map (the cast is guaranteed to dominate the map)
Node* null_check_oop(Node* value, Node* *null_control,
- bool never_see_null = false);
+ bool never_see_null = false, bool safe_for_replace = false);
// Check the null_seen bit.
bool seems_never_null(Node* obj, ciProfileData* data);
--- a/hotspot/src/share/vm/opto/parse.hpp Fri Oct 04 14:19:56 2013 -0700
+++ b/hotspot/src/share/vm/opto/parse.hpp Tue Oct 08 07:08:27 2013 -0700
@@ -73,6 +73,7 @@
bool try_to_inline(ciMethod* callee_method,
ciMethod* caller_method,
int caller_bci,
+ JVMState* jvms,
ciCallProfile& profile,
WarmCallInfo* wci_result,
bool& should_delay);
@@ -83,6 +84,7 @@
WarmCallInfo* wci_result);
bool should_not_inline(ciMethod* callee_method,
ciMethod* caller_method,
+ JVMState* jvms,
WarmCallInfo* wci_result);
void print_inlining(ciMethod* callee_method, int caller_bci,
bool success) const;
--- a/hotspot/src/share/vm/opto/parse2.cpp Fri Oct 04 14:19:56 2013 -0700
+++ b/hotspot/src/share/vm/opto/parse2.cpp Tue Oct 08 07:08:27 2013 -0700
@@ -268,7 +268,7 @@
return adjoinRange(value, value, dest, table_index);
}
- void print(ciEnv* env) {
+ void print() {
if (is_singleton())
tty->print(" {%d}=>%d", lo(), dest());
else if (lo() == min_jint)
@@ -471,8 +471,8 @@
// These are the switch destinations hanging off the jumpnode
int i = 0;
for (SwitchRange* r = lo; r <= hi; r++) {
- for (int j = r->lo(); j <= r->hi(); j++, i++) {
- Node* input = _gvn.transform(new (C) JumpProjNode(jtn, i, r->dest(), j - lowval));
+ for (int64 j = r->lo(); j <= r->hi(); j++, i++) {
+ Node* input = _gvn.transform(new (C) JumpProjNode(jtn, i, r->dest(), (int)(j - lowval)));
{
PreserveJVMState pjvms(this);
set_control(input);
@@ -632,7 +632,7 @@
}
tty->print(" ");
for( r = lo; r <= hi; r++ ) {
- r->print(env());
+ r->print();
}
tty->print_cr("");
}
--- a/hotspot/src/share/vm/opto/parseHelper.cpp Fri Oct 04 14:19:56 2013 -0700
+++ b/hotspot/src/share/vm/opto/parseHelper.cpp Tue Oct 08 07:08:27 2013 -0700
@@ -343,10 +343,14 @@
// Get the Method* node.
ciMethod* m = method();
- address counters_adr = m->ensure_method_counters();
+ MethodCounters* counters_adr = m->ensure_method_counters();
+ if (counters_adr == NULL) {
+ C->record_failure("method counters allocation failed");
+ return;
+ }
Node* ctrl = control();
- const TypePtr* adr_type = TypeRawPtr::make(counters_adr);
+ const TypePtr* adr_type = TypeRawPtr::make((address) counters_adr);
Node *counters_node = makecon(adr_type);
Node* adr_iic_node = basic_plus_adr(counters_node, counters_node,
MethodCounters::interpreter_invocation_counter_offset_in_bytes());
--- a/hotspot/src/share/vm/utilities/ostream.cpp Fri Oct 04 14:19:56 2013 -0700
+++ b/hotspot/src/share/vm/utilities/ostream.cpp Tue Oct 08 07:08:27 2013 -0700
@@ -465,7 +465,7 @@
}
// log_name comes from -XX:LogFile=log_name or -Xloggc:log_name
-// in log_name, %p => pipd1234 and
+// in log_name, %p => pid1234 and
// %t => YYYY-MM-DD_HH-MM-SS
static const char* make_log_name(const char* log_name, const char* force_directory) {
char timestr[32];
@@ -792,7 +792,7 @@
void defaultStream::init_log() {
// %%% Need a MutexLocker?
- const char* log_name = LogFile != NULL ? LogFile : "hotspot_pid%p.log";
+ const char* log_name = LogFile != NULL ? LogFile : "hotspot_%p.log";
const char* try_name = make_log_name(log_name, NULL);
fileStream* file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name);
if (!file->is_open()) {
--- a/hotspot/src/share/vm/utilities/vmError.cpp Fri Oct 04 14:19:56 2013 -0700
+++ b/hotspot/src/share/vm/utilities/vmError.cpp Tue Oct 08 07:08:27 2013 -0700
@@ -1050,7 +1050,7 @@
FILE* replay_data_file = os::open(fd, "w");
if (replay_data_file != NULL) {
fileStream replay_data_stream(replay_data_file, /*need_close=*/true);
- env->dump_replay_data(&replay_data_stream);
+ env->dump_replay_data_unsafe(&replay_data_stream);
out.print_raw("#\n# Compiler replay data is saved as:\n# ");
out.print_raw_cr(buffer);
} else {
--- a/hotspot/test/compiler/8013496/Test8013496.sh Fri Oct 04 14:19:56 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 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
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-#
-# @test
-# @bug 8013496
-# @summary Test checks that the order in which ReversedCodeCacheSize and
-# InitialCodeCacheSize are passed to the VM is irrelevant.
-# @run shell Test8013496.sh
-#
-#
-## some tests require path to find test source dir
-if [ "${TESTSRC}" = "" ]
-then
- TESTSRC=${PWD}
- echo "TESTSRC not set. Using "${TESTSRC}" as default"
-fi
-echo "TESTSRC=${TESTSRC}"
-## Adding common setup Variables for running shell tests.
-. ${TESTSRC}/../../test_env.sh
-set -x
-
-${TESTJAVA}/bin/java ${TESTVMOPTS} -XX:ReservedCodeCacheSize=2m -XX:InitialCodeCacheSize=500K -version > 1.out 2>&1
-${TESTJAVA}/bin/java ${TESTVMOPTS} -XX:InitialCodeCacheSize=500K -XX:ReservedCodeCacheSize=2m -version > 2.out 2>&1
-
-diff 1.out 2.out
-
-result=$?
-if [ $result -eq 0 ] ; then
- echo "Test Passed"
- exit 0
-else
- echo "Test Failed"
- exit 1
-fi
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/CheckReservedInitialCodeCacheSizeArgOrder.java Tue Oct 08 07:08:27 2013 -0700
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8013496
+ * @summary Test checks that the order in which ReversedCodeCacheSize and
+ * InitialCodeCacheSize are passed to the VM is irrelevant.
+ * @library /testlibrary
+ *
+ */
+import com.oracle.java.testlibrary.*;
+
+public class CheckReservedInitialCodeCacheSizeArgOrder {
+ public static void main(String[] args) throws Exception {
+ ProcessBuilder pb1, pb2;
+ OutputAnalyzer out1, out2;
+
+ pb1 = ProcessTools.createJavaProcessBuilder("-XX:InitialCodeCacheSize=4m", "-XX:ReservedCodeCacheSize=8m", "-version");
+ pb2 = ProcessTools.createJavaProcessBuilder("-XX:ReservedCodeCacheSize=8m", "-XX:InitialCodeCacheSize=4m", "-version");
+
+ out1 = new OutputAnalyzer(pb1.start());
+ out2 = new OutputAnalyzer(pb2.start());
+
+ // Check that the outputs are equal
+ if (out1.getStdout().compareTo(out2.getStdout()) != 0) {
+ throw new RuntimeException("Test failed");
+ }
+
+ out1.shouldHaveExitValue(0);
+ out2.shouldHaveExitValue(0);
+ }
+}