Merge
This commit is contained in:
commit
56e8f83652
@ -1065,7 +1065,7 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(const Register
|
||||
const int slop_factor = 2*wordSize;
|
||||
|
||||
const int fixed_size = ((sizeof(BytecodeInterpreter) + slop_factor) >> LogBytesPerWord) + // what is the slop factor?
|
||||
//6815692//Method::extra_stack_words() + // extra push slots for MH adapters
|
||||
Method::extra_stack_entries() + // extra stack for jsr 292
|
||||
frame::memory_parameter_word_sp_offset + // register save area + param window
|
||||
(native ? frame::interpreter_frame_extra_outgoing_argument_words : 0); // JNI, class
|
||||
|
||||
@ -1221,9 +1221,7 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(const Register
|
||||
// Full size expression stack
|
||||
__ ld_ptr(constMethod, O3);
|
||||
__ lduh(O3, in_bytes(ConstMethod::max_stack_offset()), O3);
|
||||
guarantee(!EnableInvokeDynamic, "no support yet for java.lang.invoke.MethodHandle"); //6815692
|
||||
//6815692//if (EnableInvokeDynamic)
|
||||
//6815692// __ inc(O3, Method::extra_stack_entries());
|
||||
__ inc(O3, Method::extra_stack_entries());
|
||||
__ sll(O3, LogBytesPerWord, O3);
|
||||
__ sub(O2, O3, O3);
|
||||
// __ sub(O3, wordSize, O3); // so prepush doesn't look out of bounds
|
||||
@ -2084,9 +2082,7 @@ static int size_activation_helper(int callee_extra_locals, int max_stack, int mo
|
||||
|
||||
const int fixed_size = sizeof(BytecodeInterpreter)/wordSize + // interpreter state object
|
||||
frame::memory_parameter_word_sp_offset; // register save area + param window
|
||||
const int extra_stack = 0; //6815692//Method::extra_stack_entries();
|
||||
return (round_to(max_stack +
|
||||
extra_stack +
|
||||
slop_factor +
|
||||
fixed_size +
|
||||
monitor_size +
|
||||
@ -2173,8 +2169,7 @@ void BytecodeInterpreter::layout_interpreterState(interpreterState to_fill,
|
||||
// Need +1 here because stack_base points to the word just above the first expr stack entry
|
||||
// and stack_limit is supposed to point to the word just below the last expr stack entry.
|
||||
// See generate_compute_interpreter_state.
|
||||
int extra_stack = 0; //6815692//Method::extra_stack_entries();
|
||||
to_fill->_stack_limit = stack_base - (method->max_stack() + 1 + extra_stack);
|
||||
to_fill->_stack_limit = stack_base - (method->max_stack() + 1);
|
||||
to_fill->_monitor_base = (BasicObjectLock*) monitor_base;
|
||||
|
||||
// sparc specific
|
||||
|
@ -521,7 +521,7 @@ void InterpreterMacroAssembler::empty_expression_stack() {
|
||||
// Compute max expression stack+register save area
|
||||
ld_ptr(Lmethod, in_bytes(Method::const_offset()), Gframe_size);
|
||||
lduh(Gframe_size, in_bytes(ConstMethod::max_stack_offset()), Gframe_size); // Load max stack.
|
||||
add( Gframe_size, frame::memory_parameter_word_sp_offset, Gframe_size );
|
||||
add(Gframe_size, frame::memory_parameter_word_sp_offset+Method::extra_stack_entries(), Gframe_size );
|
||||
|
||||
//
|
||||
// now set up a stack frame with the size computed above
|
||||
|
@ -507,7 +507,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
|
||||
|
||||
const int extra_space =
|
||||
rounded_vm_local_words + // frame local scratch space
|
||||
//6815692//Method::extra_stack_words() + // extra push slots for MH adapters
|
||||
Method::extra_stack_entries() + // extra stack for jsr 292
|
||||
frame::memory_parameter_word_sp_offset + // register save area
|
||||
(native_call ? frame::interpreter_frame_extra_outgoing_argument_words : 0);
|
||||
|
||||
@ -1558,7 +1558,6 @@ static int size_activation_helper(int callee_extra_locals, int max_stack, int mo
|
||||
round_to(callee_extra_locals * Interpreter::stackElementWords, WordsPerLong);
|
||||
const int max_stack_words = max_stack * Interpreter::stackElementWords;
|
||||
return (round_to((max_stack_words
|
||||
//6815692//+ Method::extra_stack_words()
|
||||
+ rounded_vm_local_words
|
||||
+ frame::memory_parameter_word_sp_offset), WordsPerLong)
|
||||
// already rounded
|
||||
|
@ -539,12 +539,11 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(const Register
|
||||
|
||||
// compute full expression stack limit
|
||||
|
||||
const int extra_stack = 0; //6815692//Method::extra_stack_words();
|
||||
__ movptr(rdx, Address(rbx, Method::const_offset()));
|
||||
__ load_unsigned_short(rdx, Address(rdx, ConstMethod::max_stack_offset())); // get size of expression stack in words
|
||||
__ negptr(rdx); // so we can subtract in next step
|
||||
// Allocate expression stack
|
||||
__ lea(rsp, Address(rsp, rdx, Address::times_ptr, -extra_stack));
|
||||
__ lea(rsp, Address(rsp, rdx, Address::times_ptr, -Method::extra_stack_words()));
|
||||
__ movptr(STATE(_stack_limit), rsp);
|
||||
}
|
||||
|
||||
@ -692,10 +691,9 @@ void InterpreterGenerator::generate_stack_overflow_check(void) {
|
||||
// Always give one monitor to allow us to start interp if sync method.
|
||||
// Any additional monitors need a check when moving the expression stack
|
||||
const int one_monitor = frame::interpreter_frame_monitor_size() * wordSize;
|
||||
const int extra_stack = 0; //6815692//Method::extra_stack_entries();
|
||||
__ movptr(rax, Address(rbx, Method::const_offset()));
|
||||
__ load_unsigned_short(rax, Address(rax, ConstMethod::max_stack_offset())); // get size of expression stack in words
|
||||
__ lea(rax, Address(noreg, rax, Interpreter::stackElementScale(), extra_stack + one_monitor));
|
||||
__ lea(rax, Address(noreg, rax, Interpreter::stackElementScale(), one_monitor+Method::extra_stack_words()));
|
||||
__ lea(rax, Address(rax, rdx, Interpreter::stackElementScale(), overhead_size));
|
||||
|
||||
#ifdef ASSERT
|
||||
@ -2265,8 +2263,7 @@ int AbstractInterpreter::size_top_interpreter_activation(Method* method) {
|
||||
const int overhead_size = sizeof(BytecodeInterpreter)/wordSize +
|
||||
( frame::sender_sp_offset - frame::link_offset) + 2;
|
||||
|
||||
const int extra_stack = 0; //6815692//Method::extra_stack_entries();
|
||||
const int method_stack = (method->max_locals() + method->max_stack() + extra_stack) *
|
||||
const int method_stack = (method->max_locals() + method->max_stack()) *
|
||||
Interpreter::stackElementWords;
|
||||
return overhead_size + method_stack + stub_code;
|
||||
}
|
||||
@ -2331,8 +2328,7 @@ void BytecodeInterpreter::layout_interpreterState(interpreterState to_fill,
|
||||
// Need +1 here because stack_base points to the word just above the first expr stack entry
|
||||
// and stack_limit is supposed to point to the word just below the last expr stack entry.
|
||||
// See generate_compute_interpreter_state.
|
||||
int extra_stack = 0; //6815692//Method::extra_stack_entries();
|
||||
to_fill->_stack_limit = stack_base - (method->max_stack() + extra_stack + 1);
|
||||
to_fill->_stack_limit = stack_base - (method->max_stack() + 1);
|
||||
to_fill->_monitor_base = (BasicObjectLock*) monitor_base;
|
||||
|
||||
to_fill->_self_link = to_fill;
|
||||
@ -2380,8 +2376,7 @@ int AbstractInterpreter::layout_activation(Method* method,
|
||||
monitor_size);
|
||||
|
||||
// Now with full size expression stack
|
||||
int extra_stack = 0; //6815692//Method::extra_stack_entries();
|
||||
int full_frame_size = short_frame_size + (method->max_stack() + extra_stack) * BytesPerWord;
|
||||
int full_frame_size = short_frame_size + method->max_stack() * BytesPerWord;
|
||||
|
||||
// and now with only live portion of the expression stack
|
||||
short_frame_size = short_frame_size + tempcount * BytesPerWord;
|
||||
|
@ -1565,8 +1565,7 @@ int AbstractInterpreter::size_top_interpreter_activation(Method* method) {
|
||||
// be sure to change this if you add/subtract anything to/from the overhead area
|
||||
const int overhead_size = -frame::interpreter_frame_initial_sp_offset;
|
||||
|
||||
const int extra_stack = Method::extra_stack_entries();
|
||||
const int method_stack = (method->max_locals() + method->max_stack() + extra_stack) *
|
||||
const int method_stack = (method->max_locals() + method->max_stack()) *
|
||||
Interpreter::stackElementWords;
|
||||
return overhead_size + method_stack + stub_code;
|
||||
}
|
||||
|
@ -1574,8 +1574,7 @@ int AbstractInterpreter::size_top_interpreter_activation(Method* method) {
|
||||
-(frame::interpreter_frame_initial_sp_offset) + entry_size;
|
||||
|
||||
const int stub_code = frame::entry_frame_after_call_words;
|
||||
const int extra_stack = Method::extra_stack_entries();
|
||||
const int method_stack = (method->max_locals() + method->max_stack() + extra_stack) *
|
||||
const int method_stack = (method->max_locals() + method->max_stack()) *
|
||||
Interpreter::stackElementWords;
|
||||
return (overhead_size + method_stack + stub_code);
|
||||
}
|
||||
|
@ -29,8 +29,8 @@
|
||||
static FILE *errfile = stderr;
|
||||
|
||||
//--------------------------- utility functions -----------------------------
|
||||
inline char toUpper(char lower) {
|
||||
return (('a' <= lower && lower <= 'z') ? (lower + ('A'-'a')) : lower);
|
||||
inline char toUpper(char lower) {
|
||||
return (('a' <= lower && lower <= 'z') ? ((char) (lower + ('A'-'a'))) : lower);
|
||||
}
|
||||
char *toUpper(const char *str) {
|
||||
char *upper = new char[strlen(str)+1];
|
||||
|
@ -64,18 +64,18 @@ void Dict::init() {
|
||||
int i;
|
||||
|
||||
// Precompute table of null character hashes
|
||||
if( !initflag ) { // Not initializated yet?
|
||||
xsum[0] = (1<<shft[0])+1; // Initialize
|
||||
if (!initflag) { // Not initializated yet?
|
||||
xsum[0] = (short) ((1 << shft[0]) + 1); // Initialize
|
||||
for( i = 1; i < MAXID; i++) {
|
||||
xsum[i] = (1<<shft[i])+1+xsum[i-1];
|
||||
xsum[i] = (short) ((1 << shft[i]) + 1 + xsum[i-1]);
|
||||
}
|
||||
initflag = 1; // Never again
|
||||
}
|
||||
|
||||
_size = 16; // Size is a power of 2
|
||||
_cnt = 0; // Dictionary is empty
|
||||
_bin = (bucket*)_arena->Amalloc_4(sizeof(bucket)*_size);
|
||||
memset(_bin,0,sizeof(bucket)*_size);
|
||||
_bin = (bucket*)_arena->Amalloc_4(sizeof(bucket) * _size);
|
||||
memset(_bin, 0, sizeof(bucket) * _size);
|
||||
}
|
||||
|
||||
//------------------------------~Dict------------------------------------------
|
||||
@ -287,11 +287,11 @@ int hashstr(const void *t) {
|
||||
register int sum = 0;
|
||||
register const char *s = (const char *)t;
|
||||
|
||||
while( ((c = s[k]) != '\0') && (k < MAXID-1) ) { // Get characters till nul
|
||||
c = (c<<1)+1; // Characters are always odd!
|
||||
sum += c + (c<<shft[k++]); // Universal hash function
|
||||
while (((c = s[k]) != '\0') && (k < MAXID-1)) { // Get characters till nul
|
||||
c = (char) ((c << 1) + 1); // Characters are always odd!
|
||||
sum += c + (c << shft[k++]); // Universal hash function
|
||||
}
|
||||
assert( k < (MAXID), "Exceeded maximum name length");
|
||||
assert(k < (MAXID), "Exceeded maximum name length");
|
||||
return (int)((sum+xsum[k]) >> 1); // Hash key, un-modulo'd table size
|
||||
}
|
||||
|
||||
|
@ -796,11 +796,11 @@ uint InstructForm::num_opnds() {
|
||||
return num_opnds;
|
||||
}
|
||||
|
||||
const char *InstructForm::opnd_ident(int idx) {
|
||||
const char* InstructForm::opnd_ident(int idx) {
|
||||
return _components.at(idx)->_name;
|
||||
}
|
||||
|
||||
const char *InstructForm::unique_opnd_ident(int idx) {
|
||||
const char* InstructForm::unique_opnd_ident(uint idx) {
|
||||
uint i;
|
||||
for (i = 1; i < num_opnds(); ++i) {
|
||||
if (unique_opnds_idx(i) == idx) {
|
||||
@ -1315,36 +1315,36 @@ void InstructForm::rep_var_format(FILE *fp, const char *rep_var) {
|
||||
// Seach through operands to determine parameters unique positions.
|
||||
void InstructForm::set_unique_opnds() {
|
||||
uint* uniq_idx = NULL;
|
||||
int nopnds = num_opnds();
|
||||
uint nopnds = num_opnds();
|
||||
uint num_uniq = nopnds;
|
||||
int i;
|
||||
uint i;
|
||||
_uniq_idx_length = 0;
|
||||
if ( nopnds > 0 ) {
|
||||
if (nopnds > 0) {
|
||||
// Allocate index array. Worst case we're mapping from each
|
||||
// component back to an index and any DEF always goes at 0 so the
|
||||
// length of the array has to be the number of components + 1.
|
||||
_uniq_idx_length = _components.count() + 1;
|
||||
uniq_idx = (uint*) malloc(sizeof(uint)*(_uniq_idx_length));
|
||||
for( i = 0; i < _uniq_idx_length; i++ ) {
|
||||
uniq_idx = (uint*) malloc(sizeof(uint) * _uniq_idx_length);
|
||||
for (i = 0; i < _uniq_idx_length; i++) {
|
||||
uniq_idx[i] = i;
|
||||
}
|
||||
}
|
||||
// Do it only if there is a match rule and no expand rule. With an
|
||||
// expand rule it is done by creating new mach node in Expand()
|
||||
// method.
|
||||
if ( nopnds > 0 && _matrule != NULL && _exprule == NULL ) {
|
||||
if (nopnds > 0 && _matrule != NULL && _exprule == NULL) {
|
||||
const char *name;
|
||||
uint count;
|
||||
bool has_dupl_use = false;
|
||||
|
||||
_parameters.reset();
|
||||
while( (name = _parameters.iter()) != NULL ) {
|
||||
while ((name = _parameters.iter()) != NULL) {
|
||||
count = 0;
|
||||
int position = 0;
|
||||
int uniq_position = 0;
|
||||
uint position = 0;
|
||||
uint uniq_position = 0;
|
||||
_components.reset();
|
||||
Component *comp = NULL;
|
||||
if( sets_result() ) {
|
||||
if (sets_result()) {
|
||||
comp = _components.iter();
|
||||
position++;
|
||||
}
|
||||
@ -1352,11 +1352,11 @@ void InstructForm::set_unique_opnds() {
|
||||
for (; (comp = _components.iter()) != NULL; ++position) {
|
||||
// When the first component is not a DEF,
|
||||
// leave space for the result operand!
|
||||
if ( position==0 && (! comp->isa(Component::DEF)) ) {
|
||||
if (position==0 && (!comp->isa(Component::DEF))) {
|
||||
++position;
|
||||
}
|
||||
if( strcmp(name, comp->_name)==0 ) {
|
||||
if( ++count > 1 ) {
|
||||
if (strcmp(name, comp->_name) == 0) {
|
||||
if (++count > 1) {
|
||||
assert(position < _uniq_idx_length, "out of bounds");
|
||||
uniq_idx[position] = uniq_position;
|
||||
has_dupl_use = true;
|
||||
@ -1364,22 +1364,25 @@ void InstructForm::set_unique_opnds() {
|
||||
uniq_position = position;
|
||||
}
|
||||
}
|
||||
if( comp->isa(Component::DEF)
|
||||
&& comp->isa(Component::USE) ) {
|
||||
if (comp->isa(Component::DEF) && comp->isa(Component::USE)) {
|
||||
++position;
|
||||
if( position != 1 )
|
||||
if (position != 1)
|
||||
--position; // only use two slots for the 1st USE_DEF
|
||||
}
|
||||
}
|
||||
}
|
||||
if( has_dupl_use ) {
|
||||
for( i = 1; i < nopnds; i++ )
|
||||
if( i != uniq_idx[i] )
|
||||
if (has_dupl_use) {
|
||||
for (i = 1; i < nopnds; i++) {
|
||||
if (i != uniq_idx[i]) {
|
||||
break;
|
||||
int j = i;
|
||||
for( ; i < nopnds; i++ )
|
||||
if( i == uniq_idx[i] )
|
||||
}
|
||||
}
|
||||
uint j = i;
|
||||
for (; i < nopnds; i++) {
|
||||
if (i == uniq_idx[i]) {
|
||||
uniq_idx[i] = j++;
|
||||
}
|
||||
}
|
||||
num_uniq = j;
|
||||
}
|
||||
}
|
||||
@ -2216,21 +2219,27 @@ RegClass* OperandForm::get_RegClass() const {
|
||||
|
||||
|
||||
bool OperandForm::is_bound_register() const {
|
||||
RegClass *reg_class = get_RegClass();
|
||||
if (reg_class == NULL) return false;
|
||||
RegClass* reg_class = get_RegClass();
|
||||
if (reg_class == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char * name = ideal_type(globalAD->globalNames());
|
||||
if (name == NULL) return false;
|
||||
const char* name = ideal_type(globalAD->globalNames());
|
||||
if (name == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int size = 0;
|
||||
if (strcmp(name,"RegFlags")==0) size = 1;
|
||||
if (strcmp(name,"RegI")==0) size = 1;
|
||||
if (strcmp(name,"RegF")==0) size = 1;
|
||||
if (strcmp(name,"RegD")==0) size = 2;
|
||||
if (strcmp(name,"RegL")==0) size = 2;
|
||||
if (strcmp(name,"RegN")==0) size = 1;
|
||||
if (strcmp(name,"RegP")==0) size = globalAD->get_preproc_def("_LP64") ? 2 : 1;
|
||||
if (size == 0) return false;
|
||||
uint size = 0;
|
||||
if (strcmp(name, "RegFlags") == 0) size = 1;
|
||||
if (strcmp(name, "RegI") == 0) size = 1;
|
||||
if (strcmp(name, "RegF") == 0) size = 1;
|
||||
if (strcmp(name, "RegD") == 0) size = 2;
|
||||
if (strcmp(name, "RegL") == 0) size = 2;
|
||||
if (strcmp(name, "RegN") == 0) size = 1;
|
||||
if (strcmp(name, "RegP") == 0) size = globalAD->get_preproc_def("_LP64") ? 2 : 1;
|
||||
if (size == 0) {
|
||||
return false;
|
||||
}
|
||||
return size == reg_class->size();
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ public:
|
||||
const char *_ins_pipe; // Instruction Scheduling description class
|
||||
|
||||
uint *_uniq_idx; // Indexes of unique operands
|
||||
int _uniq_idx_length; // Length of _uniq_idx array
|
||||
uint _uniq_idx_length; // Length of _uniq_idx array
|
||||
uint _num_uniq; // Number of unique operands
|
||||
ComponentList _components; // List of Components matches MachNode's
|
||||
// operand structure
|
||||
@ -272,14 +272,14 @@ public:
|
||||
void set_unique_opnds();
|
||||
uint num_unique_opnds() { return _num_uniq; }
|
||||
uint unique_opnds_idx(int idx) {
|
||||
if( _uniq_idx != NULL && idx > 0 ) {
|
||||
assert(idx < _uniq_idx_length, "out of bounds");
|
||||
return _uniq_idx[idx];
|
||||
} else {
|
||||
return idx;
|
||||
}
|
||||
if (_uniq_idx != NULL && idx > 0) {
|
||||
assert((uint)idx < _uniq_idx_length, "out of bounds");
|
||||
return _uniq_idx[idx];
|
||||
} else {
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
const char *unique_opnd_ident(int idx); // Name of operand at unique idx.
|
||||
const char *unique_opnd_ident(uint idx); // Name of operand at unique idx.
|
||||
|
||||
// Operands which are only KILLs aren't part of the input array and
|
||||
// require special handling in some cases. Their position in this
|
||||
|
@ -463,8 +463,9 @@ static int pipeline_res_mask_initializer(
|
||||
uint resources_used_exclusively = 0;
|
||||
|
||||
for (pipeclass->_resUsage.reset();
|
||||
(piperesource = (const PipeClassResourceForm *)pipeclass->_resUsage.iter()) != NULL; )
|
||||
(piperesource = (const PipeClassResourceForm*)pipeclass->_resUsage.iter()) != NULL; ) {
|
||||
element_count++;
|
||||
}
|
||||
|
||||
// Pre-compute the string length
|
||||
int templen;
|
||||
@ -482,8 +483,8 @@ static int pipeline_res_mask_initializer(
|
||||
for (i = rescount; i > 0; i /= 10)
|
||||
maskdigit++;
|
||||
|
||||
static const char * pipeline_use_cycle_mask = "Pipeline_Use_Cycle_Mask";
|
||||
static const char * pipeline_use_element = "Pipeline_Use_Element";
|
||||
static const char* pipeline_use_cycle_mask = "Pipeline_Use_Cycle_Mask";
|
||||
static const char* pipeline_use_element = "Pipeline_Use_Element";
|
||||
|
||||
templen = 1 +
|
||||
(int)(strlen(pipeline_use_cycle_mask) + (int)strlen(pipeline_use_element) +
|
||||
@ -496,11 +497,12 @@ static int pipeline_res_mask_initializer(
|
||||
templen = 0;
|
||||
|
||||
for (pipeclass->_resUsage.reset();
|
||||
(piperesource = (const PipeClassResourceForm *)pipeclass->_resUsage.iter()) != NULL; ) {
|
||||
(piperesource = (const PipeClassResourceForm*)pipeclass->_resUsage.iter()) != NULL; ) {
|
||||
int used_mask = pipeline->_resdict[piperesource->_resource]->is_resource()->mask();
|
||||
|
||||
if (!used_mask)
|
||||
if (!used_mask) {
|
||||
fprintf(stderr, "*** used_mask is 0 ***\n");
|
||||
}
|
||||
|
||||
resources_used |= used_mask;
|
||||
|
||||
@ -509,8 +511,9 @@ static int pipeline_res_mask_initializer(
|
||||
for (lb = 0; (used_mask & (1 << lb)) == 0; lb++);
|
||||
for (ub = 31; (used_mask & (1 << ub)) == 0; ub--);
|
||||
|
||||
if (lb == ub)
|
||||
if (lb == ub) {
|
||||
resources_used_exclusively |= used_mask;
|
||||
}
|
||||
|
||||
int formatlen =
|
||||
sprintf(&resource_mask[templen], " %s(0x%0*x, %*d, %*d, %s %s(",
|
||||
@ -526,7 +529,7 @@ static int pipeline_res_mask_initializer(
|
||||
|
||||
int cycles = piperesource->_cycles;
|
||||
uint stage = pipeline->_stages.index(piperesource->_stage);
|
||||
if (NameList::Not_in_list == stage) {
|
||||
if ((uint)NameList::Not_in_list == stage) {
|
||||
fprintf(stderr,
|
||||
"pipeline_res_mask_initializer: "
|
||||
"semantic error: "
|
||||
@ -534,8 +537,8 @@ static int pipeline_res_mask_initializer(
|
||||
piperesource->_stage);
|
||||
exit(1);
|
||||
}
|
||||
uint upper_limit = stage+cycles-1;
|
||||
uint lower_limit = stage-1;
|
||||
uint upper_limit = stage + cycles - 1;
|
||||
uint lower_limit = stage - 1;
|
||||
uint upper_idx = upper_limit >> 5;
|
||||
uint lower_idx = lower_limit >> 5;
|
||||
uint upper_position = upper_limit & 0x1f;
|
||||
@ -543,7 +546,7 @@ static int pipeline_res_mask_initializer(
|
||||
|
||||
uint mask = (((uint)1) << upper_position) - 1;
|
||||
|
||||
while ( upper_idx > lower_idx ) {
|
||||
while (upper_idx > lower_idx) {
|
||||
res_mask[upper_idx--] |= mask;
|
||||
mask = (uint)-1;
|
||||
}
|
||||
@ -565,8 +568,9 @@ static int pipeline_res_mask_initializer(
|
||||
}
|
||||
|
||||
resource_mask[templen] = 0;
|
||||
if (last_comma)
|
||||
if (last_comma) {
|
||||
last_comma[0] = ' ';
|
||||
}
|
||||
|
||||
// See if the same string is in the table
|
||||
int ndx = pipeline_res_mask.index(resource_mask);
|
||||
@ -580,7 +584,7 @@ static int pipeline_res_mask_initializer(
|
||||
fprintf(fp_cpp, "static const Pipeline_Use_Element pipeline_res_mask_%03d[%d] = {\n%s};\n\n",
|
||||
ndx+1, element_count, resource_mask);
|
||||
|
||||
char * args = new char [9 + 2*masklen + maskdigit];
|
||||
char* args = new char [9 + 2*masklen + maskdigit];
|
||||
|
||||
sprintf(args, "0x%0*x, 0x%0*x, %*d",
|
||||
masklen, resources_used,
|
||||
@ -589,8 +593,9 @@ static int pipeline_res_mask_initializer(
|
||||
|
||||
pipeline_res_args.addName(args);
|
||||
}
|
||||
else
|
||||
else {
|
||||
delete [] resource_mask;
|
||||
}
|
||||
|
||||
delete [] res_mask;
|
||||
//delete [] res_masks;
|
||||
@ -1787,7 +1792,7 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
|
||||
// Skip first unique operands.
|
||||
for( i = 1; i < cur_num_opnds; i++ ) {
|
||||
comp = node->_components.iter();
|
||||
if( (int)i != node->unique_opnds_idx(i) ) {
|
||||
if (i != node->unique_opnds_idx(i)) {
|
||||
break;
|
||||
}
|
||||
new_num_opnds++;
|
||||
@ -1795,7 +1800,7 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
|
||||
// Replace not unique operands with next unique operands.
|
||||
for( ; i < cur_num_opnds; i++ ) {
|
||||
comp = node->_components.iter();
|
||||
int j = node->unique_opnds_idx(i);
|
||||
uint j = node->unique_opnds_idx(i);
|
||||
// unique_opnds_idx(i) is unique if unique_opnds_idx(j) is not unique.
|
||||
if( j != node->unique_opnds_idx(j) ) {
|
||||
fprintf(fp," set_opnd_array(%d, opnd_array(%d)->clone(C)); // %s\n",
|
||||
|
@ -1976,11 +1976,10 @@ void nmethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map
|
||||
if (!method()->is_native()) {
|
||||
SimpleScopeDesc ssd(this, fr.pc());
|
||||
Bytecode_invoke call(ssd.method(), ssd.bci());
|
||||
// compiled invokedynamic call sites have an implicit receiver at
|
||||
// resolution time, so make sure it gets GC'ed.
|
||||
bool has_receiver = !call.is_invokestatic();
|
||||
bool has_receiver = call.has_receiver();
|
||||
bool has_appendix = call.has_appendix();
|
||||
Symbol* signature = call.signature();
|
||||
fr.oops_compiled_arguments_do(signature, has_receiver, reg_map, f);
|
||||
fr.oops_compiled_arguments_do(signature, has_receiver, has_appendix, reg_map, f);
|
||||
}
|
||||
#endif // !SHARK
|
||||
}
|
||||
|
@ -1642,42 +1642,37 @@ void CompileBroker::compiler_thread_loop() {
|
||||
// Set up state required by +LogCompilation.
|
||||
void CompileBroker::init_compiler_thread_log() {
|
||||
CompilerThread* thread = CompilerThread::current();
|
||||
char fileBuf[4*K];
|
||||
char file_name[4*K];
|
||||
FILE* fp = NULL;
|
||||
char* file = NULL;
|
||||
intx thread_id = os::current_thread_id();
|
||||
for (int try_temp_dir = 1; try_temp_dir >= 0; try_temp_dir--) {
|
||||
const char* dir = (try_temp_dir ? os::get_temp_directory() : NULL);
|
||||
if (dir == NULL) {
|
||||
jio_snprintf(fileBuf, sizeof(fileBuf), "hs_c" UINTX_FORMAT "_pid%u.log",
|
||||
jio_snprintf(file_name, sizeof(file_name), "hs_c" UINTX_FORMAT "_pid%u.log",
|
||||
thread_id, os::current_process_id());
|
||||
} else {
|
||||
jio_snprintf(fileBuf, sizeof(fileBuf),
|
||||
jio_snprintf(file_name, sizeof(file_name),
|
||||
"%s%shs_c" UINTX_FORMAT "_pid%u.log", dir,
|
||||
os::file_separator(), thread_id, os::current_process_id());
|
||||
}
|
||||
fp = fopen(fileBuf, "at");
|
||||
|
||||
fp = fopen(file_name, "at");
|
||||
if (fp != NULL) {
|
||||
file = NEW_C_HEAP_ARRAY(char, strlen(fileBuf)+1, mtCompiler);
|
||||
strcpy(file, fileBuf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fp == NULL) {
|
||||
warning("Cannot open log file: %s", fileBuf);
|
||||
} else {
|
||||
if (LogCompilation && Verbose)
|
||||
tty->print_cr("Opening compilation log %s", file);
|
||||
CompileLog* log = new(ResourceObj::C_HEAP, mtCompiler) CompileLog(file, fp, thread_id);
|
||||
thread->init_log(log);
|
||||
|
||||
if (xtty != NULL) {
|
||||
ttyLocker ttyl;
|
||||
|
||||
// Record any per thread log files
|
||||
xtty->elem("thread_logfile thread='%d' filename='%s'", thread_id, file);
|
||||
if (LogCompilation && Verbose) {
|
||||
tty->print_cr("Opening compilation log %s", file_name);
|
||||
}
|
||||
CompileLog* log = new(ResourceObj::C_HEAP, mtCompiler) CompileLog(file_name, fp, thread_id);
|
||||
thread->init_log(log);
|
||||
|
||||
if (xtty != NULL) {
|
||||
ttyLocker ttyl;
|
||||
// Record any per thread log files
|
||||
xtty->elem("thread_logfile thread='%d' filename='%s'", thread_id, file_name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
warning("Cannot open log file: %s", file_name);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
@ -34,17 +34,18 @@ CompileLog* CompileLog::_first = NULL;
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// CompileLog::CompileLog
|
||||
CompileLog::CompileLog(const char* file, FILE* fp, intx thread_id)
|
||||
CompileLog::CompileLog(const char* file_name, FILE* fp, intx thread_id)
|
||||
: _context(_context_buffer, sizeof(_context_buffer))
|
||||
{
|
||||
initialize(new(ResourceObj::C_HEAP, mtCompiler) fileStream(fp));
|
||||
_file = file;
|
||||
initialize(new(ResourceObj::C_HEAP, mtCompiler) fileStream(fp, true));
|
||||
_file_end = 0;
|
||||
_thread_id = thread_id;
|
||||
|
||||
_identities_limit = 0;
|
||||
_identities_capacity = 400;
|
||||
_identities = NEW_C_HEAP_ARRAY(char, _identities_capacity, mtCompiler);
|
||||
_file = NEW_C_HEAP_ARRAY(char, strlen(file_name)+1, mtCompiler);
|
||||
strcpy((char*)_file, file_name);
|
||||
|
||||
// link into the global list
|
||||
{ MutexLocker locker(CompileTaskAlloc_lock);
|
||||
@ -57,6 +58,7 @@ CompileLog::~CompileLog() {
|
||||
delete _out;
|
||||
_out = NULL;
|
||||
FREE_C_HEAP_ARRAY(char, _identities, mtCompiler);
|
||||
FREE_C_HEAP_ARRAY(char, _file, mtCompiler);
|
||||
}
|
||||
|
||||
|
||||
@ -188,7 +190,8 @@ void CompileLog::finish_log_on_error(outputStream* file, char* buf, int buflen)
|
||||
if (called_exit) return;
|
||||
called_exit = true;
|
||||
|
||||
for (CompileLog* log = _first; log != NULL; log = log->_next) {
|
||||
CompileLog* log = _first;
|
||||
while (log != NULL) {
|
||||
log->flush();
|
||||
const char* partial_file = log->file();
|
||||
int partial_fd = open(partial_file, O_RDONLY);
|
||||
@ -267,7 +270,11 @@ void CompileLog::finish_log_on_error(outputStream* file, char* buf, int buflen)
|
||||
close(partial_fd);
|
||||
unlink(partial_file);
|
||||
}
|
||||
CompileLog* next_log = log->_next;
|
||||
delete log;
|
||||
log = next_log;
|
||||
}
|
||||
_first = NULL;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
@ -57,7 +57,7 @@ class CompileLog : public xmlStream {
|
||||
void va_tag(bool push, const char* format, va_list ap);
|
||||
|
||||
public:
|
||||
CompileLog(const char* file, FILE* fp, intx thread_id);
|
||||
CompileLog(const char* file_name, FILE* fp, intx thread_id);
|
||||
~CompileLog();
|
||||
|
||||
intx thread_id() { return _thread_id; }
|
||||
|
@ -468,7 +468,25 @@ BytecodeInterpreter::run(interpreterState istate) {
|
||||
|
||||
#ifdef ASSERT
|
||||
if (istate->_msg != initialize) {
|
||||
assert(abs(istate->_stack_base - istate->_stack_limit) == (istate->_method->max_stack() + 1), "bad stack limit");
|
||||
// We have a problem here if we are running with a pre-hsx24 JDK (for example during bootstrap)
|
||||
// because in that case, EnableInvokeDynamic is true by default but will be later switched off
|
||||
// if java_lang_invoke_MethodHandle::compute_offsets() detects that the JDK only has the classes
|
||||
// for the old JSR292 implementation.
|
||||
// This leads to a situation where 'istate->_stack_limit' always accounts for
|
||||
// methodOopDesc::extra_stack_entries() because it is computed in
|
||||
// CppInterpreterGenerator::generate_compute_interpreter_state() which was generated while
|
||||
// EnableInvokeDynamic was still true. On the other hand, istate->_method->max_stack() doesn't
|
||||
// account for extra_stack_entries() anymore because at the time when it is called
|
||||
// EnableInvokeDynamic was already set to false.
|
||||
// So we have a second version of the assertion which handles the case where EnableInvokeDynamic was
|
||||
// switched off because of the wrong classes.
|
||||
if (EnableInvokeDynamic || FLAG_IS_CMDLINE(EnableInvokeDynamic)) {
|
||||
assert(abs(istate->_stack_base - istate->_stack_limit) == (istate->_method->max_stack() + 1), "bad stack limit");
|
||||
} else {
|
||||
const int extra_stack_entries = Method::extra_stack_entries_for_indy;
|
||||
assert(labs(istate->_stack_base - istate->_stack_limit) == (istate->_method->max_stack() + extra_stack_entries
|
||||
+ 1), "bad stack limit");
|
||||
}
|
||||
#ifndef SHARK
|
||||
IA32_ONLY(assert(istate->_stack_limit == istate->_thread->last_Java_sp() + 1, "wrong"));
|
||||
#endif // !SHARK
|
||||
|
@ -671,13 +671,15 @@ class Method : public Metadata {
|
||||
Symbol* signature, //anything at all
|
||||
TRAPS);
|
||||
static Klass* check_non_bcp_klass(Klass* klass);
|
||||
// these operate only on invoke methods:
|
||||
|
||||
// How many extra stack entries for invokedynamic when it's enabled
|
||||
static const int extra_stack_entries_for_jsr292 = 1;
|
||||
|
||||
// this operates only on invoke methods:
|
||||
// presize interpreter frames for extra interpreter stack entries, if needed
|
||||
// method handles want to be able to push a few extra values (e.g., a bound receiver), and
|
||||
// invokedynamic sometimes needs to push a bootstrap method, call site, and arglist,
|
||||
// all without checking for a stack overflow
|
||||
static int extra_stack_entries() { return EnableInvokeDynamic ? 2 : 0; }
|
||||
static int extra_stack_words(); // = extra_stack_entries() * Interpreter::stackElementSize()
|
||||
// Account for the extra appendix argument for invokehandle/invokedynamic
|
||||
static int extra_stack_entries() { return EnableInvokeDynamic ? extra_stack_entries_for_jsr292 : 0; }
|
||||
static int extra_stack_words(); // = extra_stack_entries() * Interpreter::stackElementSize
|
||||
|
||||
// RedefineClasses() support:
|
||||
bool is_old() const { return access_flags().is_old(); }
|
||||
|
@ -2202,7 +2202,7 @@ Node* ConnectionGraph::get_addp_base(Node *addp) {
|
||||
int opcode = uncast_base->Opcode();
|
||||
assert(opcode == Op_ConP || opcode == Op_ThreadLocal ||
|
||||
opcode == Op_CastX2P || uncast_base->is_DecodeNarrowPtr() ||
|
||||
(uncast_base->is_Mem() && uncast_base->bottom_type() == TypeRawPtr::NOTNULL) ||
|
||||
(uncast_base->is_Mem() && (uncast_base->bottom_type()->isa_rawptr() != NULL)) ||
|
||||
(uncast_base->is_Proj() && uncast_base->in(0)->is_Allocate()), "sanity");
|
||||
}
|
||||
return base;
|
||||
|
@ -1282,16 +1282,6 @@ MachNode *Matcher::match_sfpt( SafePointNode *sfpt ) {
|
||||
mcall->_argsize = out_arg_limit_per_call - begin_out_arg_area;
|
||||
}
|
||||
|
||||
if (is_method_handle_invoke) {
|
||||
// Kill some extra stack space in case method handles want to do
|
||||
// a little in-place argument insertion.
|
||||
// FIXME: Is this still necessary?
|
||||
int regs_per_word = NOT_LP64(1) LP64_ONLY(2); // %%% make a global const!
|
||||
out_arg_limit_per_call += Method::extra_stack_entries() * regs_per_word;
|
||||
// Do not update mcall->_argsize because (a) the extra space is not
|
||||
// pushed as arguments and (b) _argsize is dead (not used anywhere).
|
||||
}
|
||||
|
||||
// Compute the max stack slot killed by any call. These will not be
|
||||
// available for debug info, and will be used to adjust FIRST_STACK_mask
|
||||
// after all call sites have been visited.
|
||||
|
@ -51,6 +51,15 @@
|
||||
|
||||
static const char out_of_nodes[] = "out of nodes during split";
|
||||
|
||||
static bool contains_no_live_range_input(const Node* def) {
|
||||
for (uint i = 1; i < def->req(); ++i) {
|
||||
if (def->in(i) != NULL && def->in_RegMask(i).is_NotEmpty()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------get_spillcopy_wide-----------------------------
|
||||
// Get a SpillCopy node with wide-enough masks. Use the 'wide-mask', the
|
||||
// wide ideal-register spill-mask if possible. If the 'wide-mask' does
|
||||
@ -1312,7 +1321,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
|
||||
Node *def = Reaches[pidx][slidx];
|
||||
assert( def, "must have reaching def" );
|
||||
// If input up/down sense and reg-pressure DISagree
|
||||
if( def->rematerialize() ) {
|
||||
if (def->rematerialize() && contains_no_live_range_input(def)) {
|
||||
// Place the rematerialized node above any MSCs created during
|
||||
// phi node splitting. end_idx points at the insertion point
|
||||
// so look at the node before it.
|
||||
|
@ -2217,6 +2217,13 @@ bool Arguments::check_vm_args_consistency() {
|
||||
status = false;
|
||||
}
|
||||
|
||||
if (ReservedCodeCacheSize < InitialCodeCacheSize) {
|
||||
jio_fprintf(defaultStream::error_stream(),
|
||||
"Invalid ReservedCodeCacheSize: %dK. Should be greater than InitialCodeCacheSize=%dK\n",
|
||||
ReservedCodeCacheSize/K, InitialCodeCacheSize/K);
|
||||
status = false;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -2619,13 +2626,10 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
|
||||
} else if (match_option(option, "-Xmaxjitcodesize", &tail) ||
|
||||
match_option(option, "-XX:ReservedCodeCacheSize=", &tail)) {
|
||||
julong long_ReservedCodeCacheSize = 0;
|
||||
ArgsRange errcode = parse_memory_size(tail, &long_ReservedCodeCacheSize,
|
||||
(size_t)InitialCodeCacheSize);
|
||||
ArgsRange errcode = parse_memory_size(tail, &long_ReservedCodeCacheSize, 1);
|
||||
if (errcode != arg_in_range) {
|
||||
jio_fprintf(defaultStream::error_stream(),
|
||||
"Invalid maximum code cache size: %s. Should be greater than InitialCodeCacheSize=%dK\n",
|
||||
option->optionString, InitialCodeCacheSize/K);
|
||||
describe_range_error(errcode);
|
||||
"Invalid maximum code cache size: %s.\n", option->optionString);
|
||||
return JNI_EINVAL;
|
||||
}
|
||||
FLAG_SET_CMDLINE(uintx, ReservedCodeCacheSize, (uintx)long_ReservedCodeCacheSize);
|
||||
|
@ -635,18 +635,22 @@ JRT_LEAF(BasicType, Deoptimization::unpack_frames(JavaThread* thread, int exec_m
|
||||
// at an uncommon trap for an invoke (where the compiler
|
||||
// generates debug info before the invoke has executed)
|
||||
Bytecodes::Code cur_code = str.next();
|
||||
if (cur_code == Bytecodes::_invokevirtual ||
|
||||
cur_code == Bytecodes::_invokespecial ||
|
||||
cur_code == Bytecodes::_invokestatic ||
|
||||
cur_code == Bytecodes::_invokeinterface) {
|
||||
if (cur_code == Bytecodes::_invokevirtual ||
|
||||
cur_code == Bytecodes::_invokespecial ||
|
||||
cur_code == Bytecodes::_invokestatic ||
|
||||
cur_code == Bytecodes::_invokeinterface ||
|
||||
cur_code == Bytecodes::_invokedynamic) {
|
||||
Bytecode_invoke invoke(mh, iframe->interpreter_frame_bci());
|
||||
Symbol* signature = invoke.signature();
|
||||
ArgumentSizeComputer asc(signature);
|
||||
cur_invoke_parameter_size = asc.size();
|
||||
if (cur_code != Bytecodes::_invokestatic) {
|
||||
if (invoke.has_receiver()) {
|
||||
// Add in receiver
|
||||
++cur_invoke_parameter_size;
|
||||
}
|
||||
if (i != 0 && !invoke.is_invokedynamic() && MethodHandles::has_member_arg(invoke.klass(), invoke.name())) {
|
||||
callee_size_of_parameters++;
|
||||
}
|
||||
}
|
||||
if (str.bci() < max_bci) {
|
||||
Bytecodes::Code bc = str.next();
|
||||
@ -661,6 +665,7 @@ JRT_LEAF(BasicType, Deoptimization::unpack_frames(JavaThread* thread, int exec_m
|
||||
case Bytecodes::_invokespecial:
|
||||
case Bytecodes::_invokestatic:
|
||||
case Bytecodes::_invokeinterface:
|
||||
case Bytecodes::_invokedynamic:
|
||||
case Bytecodes::_athrow:
|
||||
break;
|
||||
default: {
|
||||
|
@ -1008,6 +1008,7 @@ class CompiledArgumentOopFinder: public SignatureInfo {
|
||||
OopClosure* _f;
|
||||
int _offset; // the current offset, incremented with each argument
|
||||
bool _has_receiver; // true if the callee has a receiver
|
||||
bool _has_appendix; // true if the call has an appendix
|
||||
frame _fr;
|
||||
RegisterMap* _reg_map;
|
||||
int _arg_size;
|
||||
@ -1027,19 +1028,20 @@ class CompiledArgumentOopFinder: public SignatureInfo {
|
||||
}
|
||||
|
||||
public:
|
||||
CompiledArgumentOopFinder(Symbol* signature, bool has_receiver, OopClosure* f, frame fr, const RegisterMap* reg_map)
|
||||
CompiledArgumentOopFinder(Symbol* signature, bool has_receiver, bool has_appendix, OopClosure* f, frame fr, const RegisterMap* reg_map)
|
||||
: SignatureInfo(signature) {
|
||||
|
||||
// initialize CompiledArgumentOopFinder
|
||||
_f = f;
|
||||
_offset = 0;
|
||||
_has_receiver = has_receiver;
|
||||
_has_appendix = has_appendix;
|
||||
_fr = fr;
|
||||
_reg_map = (RegisterMap*)reg_map;
|
||||
_arg_size = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0);
|
||||
_arg_size = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0) + (has_appendix ? 1 : 0);
|
||||
|
||||
int arg_size;
|
||||
_regs = SharedRuntime::find_callee_arguments(signature, has_receiver, &arg_size);
|
||||
_regs = SharedRuntime::find_callee_arguments(signature, has_receiver, has_appendix, &arg_size);
|
||||
assert(arg_size == _arg_size, "wrong arg size");
|
||||
}
|
||||
|
||||
@ -1049,12 +1051,16 @@ class CompiledArgumentOopFinder: public SignatureInfo {
|
||||
_offset++;
|
||||
}
|
||||
iterate_parameters();
|
||||
if (_has_appendix) {
|
||||
handle_oop_offset();
|
||||
_offset++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void frame::oops_compiled_arguments_do(Symbol* signature, bool has_receiver, const RegisterMap* reg_map, OopClosure* f) {
|
||||
void frame::oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix, const RegisterMap* reg_map, OopClosure* f) {
|
||||
ResourceMark rm;
|
||||
CompiledArgumentOopFinder finder(signature, has_receiver, f, *this, reg_map);
|
||||
CompiledArgumentOopFinder finder(signature, has_receiver, has_appendix, f, *this, reg_map);
|
||||
finder.oops_do();
|
||||
}
|
||||
|
||||
|
@ -411,7 +411,7 @@ class frame VALUE_OBJ_CLASS_SPEC {
|
||||
oop* oopmapreg_to_location(VMReg reg, const RegisterMap* regmap) const;
|
||||
|
||||
// Oops-do's
|
||||
void oops_compiled_arguments_do(Symbol* signature, bool has_receiver, const RegisterMap* reg_map, OopClosure* f);
|
||||
void oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix, const RegisterMap* reg_map, OopClosure* f);
|
||||
void oops_interpreted_do(OopClosure* f, CLDToOopClosure* cld_f, const RegisterMap* map, bool query_oop_map_cache = true);
|
||||
|
||||
private:
|
||||
|
@ -2726,7 +2726,7 @@ VMReg SharedRuntime::name_for_receiver() {
|
||||
return regs.first();
|
||||
}
|
||||
|
||||
VMRegPair *SharedRuntime::find_callee_arguments(Symbol* sig, bool has_receiver, int* arg_size) {
|
||||
VMRegPair *SharedRuntime::find_callee_arguments(Symbol* sig, bool has_receiver, bool has_appendix, int* arg_size) {
|
||||
// This method is returning a data structure allocating as a
|
||||
// ResourceObject, so do not put any ResourceMarks in here.
|
||||
char *s = sig->as_C_string();
|
||||
@ -2770,6 +2770,11 @@ VMRegPair *SharedRuntime::find_callee_arguments(Symbol* sig, bool has_receiver,
|
||||
default : ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
|
||||
if (has_appendix) {
|
||||
sig_bt[cnt++] = T_OBJECT;
|
||||
}
|
||||
|
||||
assert( cnt < 256, "grow table size" );
|
||||
|
||||
int comp_args_on_stack;
|
||||
|
@ -410,7 +410,7 @@ class SharedRuntime: AllStatic {
|
||||
|
||||
// Convert a sig into a calling convention register layout
|
||||
// and find interesting things about it.
|
||||
static VMRegPair* find_callee_arguments(Symbol* sig, bool has_receiver, int *arg_size);
|
||||
static VMRegPair* find_callee_arguments(Symbol* sig, bool has_receiver, bool has_appendix, int *arg_size);
|
||||
static VMReg name_for_receiver();
|
||||
|
||||
// "Top of Stack" slots that may be unused by the calling convention but must
|
||||
|
77
hotspot/test/compiler/8011771/Test8011771.java
Normal file
77
hotspot/test/compiler/8011771/Test8011771.java
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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 8011771
|
||||
* @summary Array bound check elimination's in block motion doesn't always reset its data structures from one step to the other.
|
||||
* @run main/othervm -XX:-BackgroundCompilation Test8011771
|
||||
*
|
||||
*/
|
||||
|
||||
public class Test8011771 {
|
||||
|
||||
static void m(int[] a, int[] b, int j) {
|
||||
// Array bound check elimination inserts a predicate before
|
||||
// the loop. We'll have the predicate fail, so the method is
|
||||
// recompiled without optimistic optimizations
|
||||
for (int i = 0; i < 10; i++) {
|
||||
a[i] = i;
|
||||
}
|
||||
|
||||
// The test itself
|
||||
a[j] = 0;
|
||||
a[j+5] = 0;
|
||||
b[j+4] = 0; // this range check shouldn't be eliminated
|
||||
}
|
||||
|
||||
static public void main(String[] args) {
|
||||
int[] arr1 = new int[10], arr2 = new int[10];
|
||||
// force compilation:
|
||||
for (int i = 0; i < 5000; i++) {
|
||||
m(arr1, arr2, 0);
|
||||
}
|
||||
|
||||
try {
|
||||
m(new int[1], null, 0); // force predicate failure
|
||||
} catch(ArrayIndexOutOfBoundsException e) {}
|
||||
|
||||
// force compilation again (no optimistic opts):
|
||||
for (int i = 0; i < 5000; i++) {
|
||||
m(arr1, arr2, 0);
|
||||
}
|
||||
|
||||
// Check that the range check on the second array wasn't optimized out
|
||||
boolean success = false;
|
||||
try {
|
||||
m(arr1, new int[1], 0);
|
||||
} catch(ArrayIndexOutOfBoundsException e) {
|
||||
success = true;
|
||||
}
|
||||
if (success) {
|
||||
System.out.println("TEST PASSED");
|
||||
} else {
|
||||
throw new RuntimeException("TEST FAILED: erroneous bound check elimination");
|
||||
}
|
||||
}
|
||||
}
|
55
hotspot/test/compiler/8013496/Test8013496.sh
Normal file
55
hotspot/test/compiler/8013496/Test8013496.sh
Normal file
@ -0,0 +1,55 @@
|
||||
#!/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
|
Loading…
x
Reference in New Issue
Block a user