提交 b6ac67b7 编写于 作者: Z zgu

Merge

......@@ -258,3 +258,6 @@ e77b8e0ed1f84e3e268239e276c7ab64fa573baa jdk8-b43
831e5c76a20af18f3c08c5a95ed31be0e128a010 jdk8-b44
9d5f20961bc5846fa8d098d534effafbbdae0a58 jdk8-b45
40e5a3f2907ed02b335c7caa8ecf068cc801380d hs24-b15
cf37a594c38db2ea926954154636f9f81da2e032 jdk8-b46
0c7bb1f4f9c8062b5c5bfa56b3bdca44839b4109 jdk8-b47
66b0450071c1534e014b131892cc86b63f1d009c hs24-b16
/*
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2012, 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
......@@ -688,8 +688,7 @@ implements ReferenceType {
if (sde == null) {
String extension = null;
if (saKlass instanceof InstanceKlass) {
Symbol sdeSym = ((InstanceKlass)saKlass).getSourceDebugExtension();
extension = (sdeSym != null)? sdeSym.asString() : null;
extension = ((InstanceKlass)saKlass).getSourceDebugExtension();
}
if (extension == null) {
sde = NO_SDE_INFO_MARK;
......
......@@ -342,7 +342,7 @@ public class InstanceKlass extends Klass {
public Oop getProtectionDomain() { return protectionDomain.getValue(this); }
public ObjArray getSigners() { return (ObjArray) signers.getValue(this); }
public Symbol getSourceFileName() { return getSymbol(sourceFileName); }
public Symbol getSourceDebugExtension(){ return getSymbol(sourceDebugExtension); }
public String getSourceDebugExtension(){ return CStringUtilities.getString(sourceDebugExtension.getValue(getHandle())); }
public TypeArray getInnerClasses() { return (TypeArray) innerClasses.getValue(this); }
public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); }
public long getStaticOopFieldCount() { return staticOopFieldCount.getValue(this); }
......
......@@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2012
HS_MAJOR_VER=24
HS_MINOR_VER=0
HS_BUILD_NUMBER=16
HS_BUILD_NUMBER=17
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
......
......@@ -2337,12 +2337,7 @@ void ClassFileParser::parse_classfile_source_debug_extension_attribute(constantP
// Don't bother storing it if there is no way to retrieve it
if (JvmtiExport::can_get_source_debug_extension()) {
// Optimistically assume that only 1 byte UTF format is used
// (common case)
TempNewSymbol sde_symbol = SymbolTable::new_symbol((const char*)sde_buffer, length, CHECK);
k->set_source_debug_extension(sde_symbol);
// Note that set_source_debug_extension() increments the reference count
// for its copy of the Symbol*, so use a TempNewSymbol here.
k->set_source_debug_extension((char*)sde_buffer, length);
}
// Got utf8 string, set stream position forward
cfs->skip_u1(length, CHECK);
......
......@@ -550,10 +550,12 @@ void CompilerOracle::parse_from_line(char* line) {
}
}
static const char* default_cc_file = ".hotspot_compiler";
static const char* cc_file() {
#ifdef ASSERT
if (CompileCommandFile == NULL)
return ".hotspot_compiler";
return default_cc_file;
#endif
return CompileCommandFile;
}
......@@ -636,10 +638,17 @@ void compilerOracle_init() {
CompilerOracle::parse_from_string(CompileOnly, CompilerOracle::parse_compile_only);
if (CompilerOracle::has_command_file()) {
CompilerOracle::parse_from_file();
} else {
struct stat buf;
if (os::stat(default_cc_file, &buf) == 0) {
warning("%s file is present but has been ignored. "
"Run with -XX:CompileCommandFile=%s to load the file.",
default_cc_file, default_cc_file);
}
}
if (lists[PrintCommand] != NULL) {
if (PrintAssembly) {
warning("CompileCommand and/or .hotspot_compiler file contains 'print' commands, but PrintAssembly is also enabled");
warning("CompileCommand and/or %s file contains 'print' commands, but PrintAssembly is also enabled", default_cc_file);
} else if (FLAG_IS_DEFAULT(DebugNonSafepoints)) {
warning("printing of assembly code is enabled; turning on DebugNonSafepoints to gain additional output");
DebugNonSafepoints = true;
......
......@@ -847,7 +847,6 @@ void instanceKlass::shared_symbols_iterate(SymbolClosure* closure) {
Klass::shared_symbols_iterate(closure);
closure->do_symbol(&_generic_signature);
closure->do_symbol(&_source_file_name);
closure->do_symbol(&_source_debug_extension);
for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
int name_index = fs.name_index();
......@@ -1944,9 +1943,10 @@ void instanceKlass::release_C_heap_structures() {
// class can't be referenced anymore).
if (_array_name != NULL) _array_name->decrement_refcount();
if (_source_file_name != NULL) _source_file_name->decrement_refcount();
if (_source_debug_extension != NULL) _source_debug_extension->decrement_refcount();
// walk constant pool and decrement symbol reference counts
_constants->unreference_symbols();
if (_source_debug_extension != NULL) FREE_C_HEAP_ARRAY(char, _source_debug_extension, mtClass);
}
void instanceKlass::set_source_file_name(Symbol* n) {
......@@ -1954,9 +1954,22 @@ void instanceKlass::set_source_file_name(Symbol* n) {
if (_source_file_name != NULL) _source_file_name->increment_refcount();
}
void instanceKlass::set_source_debug_extension(Symbol* n) {
_source_debug_extension = n;
if (_source_debug_extension != NULL) _source_debug_extension->increment_refcount();
void instanceKlass::set_source_debug_extension(char* array, int length) {
if (array == NULL) {
_source_debug_extension = NULL;
} else {
// Adding one to the attribute length in order to store a null terminator
// character could cause an overflow because the attribute length is
// already coded with an u4 in the classfile, but in practice, it's
// unlikely to happen.
assert((length+1) > length, "Overflow checking");
char* sde = NEW_C_HEAP_ARRAY(char, (length + 1), mtClass);
for (int i = 0; i < length; i++) {
sde[i] = array[i];
}
sde[length] = '\0';
_source_debug_extension = sde;
}
}
address instanceKlass::static_field_addr(int offset) {
......
......@@ -226,7 +226,9 @@ class instanceKlass: public Klass {
// Name of source file containing this klass, NULL if not specified.
Symbol* _source_file_name;
// the source debug extension for this klass, NULL if not specified.
Symbol* _source_debug_extension;
// Specified as UTF-8 string without terminating zero byte in the classfile,
// it is stored in the instanceklass as a NULL-terminated UTF-8 string
char* _source_debug_extension;
// Generic signature, or null if none.
Symbol* _generic_signature;
// Array name derived from this class which needs unreferencing
......@@ -542,8 +544,8 @@ class instanceKlass: public Klass {
void set_major_version(u2 major_version) { _major_version = major_version; }
// source debug extension
Symbol* source_debug_extension() const { return _source_debug_extension; }
void set_source_debug_extension(Symbol* n);
char* source_debug_extension() const { return _source_debug_extension; }
void set_source_debug_extension(char* array, int length);
// symbol unloading support (refcount already added)
Symbol* array_name() { return _array_name; }
......
......@@ -421,8 +421,7 @@ instanceKlassKlass::allocate_instance_klass(Symbol* name, int vtable_len, int it
ik->set_protection_domain(NULL);
ik->set_signers(NULL);
ik->set_source_file_name(NULL);
ik->set_source_debug_extension(NULL);
ik->set_source_debug_extension(NULL);
ik->set_source_debug_extension(NULL, 0);
ik->set_array_name(NULL);
ik->set_inner_classes(NULL);
ik->set_static_oop_field_count(0);
......@@ -531,7 +530,7 @@ void instanceKlassKlass::oop_print_on(oop obj, outputStream* st) {
}
if (ik->source_debug_extension() != NULL) {
st->print(BULLET"source debug extension: ");
ik->source_debug_extension()->print_value_on(st);
st->print_cr("%s", ik->source_debug_extension());
st->cr();
}
......
......@@ -160,6 +160,7 @@ class LibraryCallKit : public GraphKit {
bool inline_trans(vmIntrinsics::ID id);
bool inline_abs(vmIntrinsics::ID id);
bool inline_sqrt(vmIntrinsics::ID id);
void finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName);
bool inline_pow(vmIntrinsics::ID id);
bool inline_exp(vmIntrinsics::ID id);
bool inline_min_max(vmIntrinsics::ID id);
......@@ -1535,40 +1536,79 @@ bool LibraryCallKit::inline_abs(vmIntrinsics::ID id) {
return true;
}
void LibraryCallKit::finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName) {
//-------------------
//result=(result.isNaN())? funcAddr():result;
// Check: If isNaN() by checking result!=result? then either trap
// or go to runtime
Node* cmpisnan = _gvn.transform(new (C, 3) CmpDNode(result,result));
// Build the boolean node
Node* bolisnum = _gvn.transform( new (C, 2) BoolNode(cmpisnan, BoolTest::eq) );
if (!too_many_traps(Deoptimization::Reason_intrinsic)) {
{
BuildCutout unless(this, bolisnum, PROB_STATIC_FREQUENT);
// End the current control-flow path
push_pair(x);
if (y != NULL) {
push_pair(y);
}
// The pow or exp intrinsic returned a NaN, which requires a call
// to the runtime. Recompile with the runtime call.
uncommon_trap(Deoptimization::Reason_intrinsic,
Deoptimization::Action_make_not_entrant);
}
push_pair(result);
} else {
// If this inlining ever returned NaN in the past, we compile a call
// to the runtime to properly handle corner cases
IfNode* iff = create_and_xform_if(control(), bolisnum, PROB_STATIC_FREQUENT, COUNT_UNKNOWN);
Node* if_slow = _gvn.transform( new (C, 1) IfFalseNode(iff) );
Node* if_fast = _gvn.transform( new (C, 1) IfTrueNode(iff) );
if (!if_slow->is_top()) {
RegionNode* result_region = new(C, 3) RegionNode(3);
PhiNode* result_val = new (C, 3) PhiNode(result_region, Type::DOUBLE);
result_region->init_req(1, if_fast);
result_val->init_req(1, result);
set_control(if_slow);
const TypePtr* no_memory_effects = NULL;
Node* rt = make_runtime_call(RC_LEAF, call_type, funcAddr, funcName,
no_memory_effects,
x, top(), y, y ? top() : NULL);
Node* value = _gvn.transform(new (C, 1) ProjNode(rt, TypeFunc::Parms+0));
#ifdef ASSERT
Node* value_top = _gvn.transform(new (C, 1) ProjNode(rt, TypeFunc::Parms+1));
assert(value_top == top(), "second value must be top");
#endif
result_region->init_req(2, control());
result_val->init_req(2, value);
push_result(result_region, result_val);
} else {
push_pair(result);
}
}
}
//------------------------------inline_exp-------------------------------------
// Inline exp instructions, if possible. The Intel hardware only misses
// really odd corner cases (+/- Infinity). Just uncommon-trap them.
bool LibraryCallKit::inline_exp(vmIntrinsics::ID id) {
assert(id == vmIntrinsics::_dexp, "Not exp");
// If this inlining ever returned NaN in the past, we do not intrinsify it
// every again. NaN results requires StrictMath.exp handling.
if (too_many_traps(Deoptimization::Reason_intrinsic)) return false;
_sp += arg_size(); // restore stack pointer
Node *x = pop_math_arg();
Node *result = _gvn.transform(new (C, 2) ExpDNode(0,x));
//-------------------
//result=(result.isNaN())? StrictMath::exp():result;
// Check: If isNaN() by checking result!=result? then go to Strict Math
Node* cmpisnan = _gvn.transform(new (C, 3) CmpDNode(result,result));
// Build the boolean node
Node* bolisnum = _gvn.transform( new (C, 2) BoolNode(cmpisnan, BoolTest::eq) );
{ BuildCutout unless(this, bolisnum, PROB_STATIC_FREQUENT);
// End the current control-flow path
push_pair(x);
// Math.exp intrinsic returned a NaN, which requires StrictMath.exp
// to handle. Recompile without intrinsifying Math.exp
uncommon_trap(Deoptimization::Reason_intrinsic,
Deoptimization::Action_make_not_entrant);
}
finish_pow_exp(result, x, NULL, OptoRuntime::Math_D_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dexp), "EXP");
C->set_has_split_ifs(true); // Has chance for split-if optimization
push_pair(result);
return true;
}
......@@ -1577,17 +1617,12 @@ bool LibraryCallKit::inline_exp(vmIntrinsics::ID id) {
bool LibraryCallKit::inline_pow(vmIntrinsics::ID id) {
assert(id == vmIntrinsics::_dpow, "Not pow");
// If this inlining ever returned NaN in the past, we do not intrinsify it
// every again. NaN results requires StrictMath.pow handling.
if (too_many_traps(Deoptimization::Reason_intrinsic)) return false;
// Do not intrinsify on older platforms which lack cmove.
if (ConditionalMoveLimit == 0) return false;
// Pseudocode for pow
// if (x <= 0.0) {
// if ((double)((int)y)==y) { // if y is int
// result = ((1&(int)y)==0)?-DPow(abs(x), y):DPow(abs(x), y)
// long longy = (long)y;
// if ((double)longy == y) { // if y is long
// if (y + 1 == y) longy = 0; // huge number: even
// result = ((1&longy) == 0)?-DPow(abs(x), y):DPow(abs(x), y);
// } else {
// result = NaN;
// }
......@@ -1595,7 +1630,7 @@ bool LibraryCallKit::inline_pow(vmIntrinsics::ID id) {
// result = DPow(x,y);
// }
// if (result != result)? {
// uncommon_trap();
// result = uncommon_trap() or runtime_call();
// }
// return result;
......@@ -1603,15 +1638,14 @@ bool LibraryCallKit::inline_pow(vmIntrinsics::ID id) {
Node* y = pop_math_arg();
Node* x = pop_math_arg();
Node *fast_result = _gvn.transform( new (C, 3) PowDNode(0, x, y) );
Node* result = NULL;
// Short form: if not top-level (i.e., Math.pow but inlining Math.pow
// inside of something) then skip the fancy tests and just check for
// NaN result.
Node *result = NULL;
if( jvms()->depth() >= 1 ) {
result = fast_result;
if (!too_many_traps(Deoptimization::Reason_intrinsic)) {
// Short form: skip the fancy tests and just check for NaN result.
result = _gvn.transform( new (C, 3) PowDNode(0, x, y) );
} else {
// If this inlining ever returned NaN in the past, include all
// checks + call to the runtime.
// Set the merge point for If node with condition of (x <= 0.0)
// There are four possible paths to region node and phi node
......@@ -1627,55 +1661,95 @@ bool LibraryCallKit::inline_pow(vmIntrinsics::ID id) {
Node *bol1 = _gvn.transform( new (C, 2) BoolNode( cmp, BoolTest::le ) );
// Branch either way
IfNode *if1 = create_and_xform_if(control(),bol1, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN);
Node *opt_test = _gvn.transform(if1);
//assert( opt_test->is_If(), "Expect an IfNode");
IfNode *opt_if1 = (IfNode*)opt_test;
// Fast path taken; set region slot 3
Node *fast_taken = _gvn.transform( new (C, 1) IfFalseNode(opt_if1) );
Node *fast_taken = _gvn.transform( new (C, 1) IfFalseNode(if1) );
r->init_req(3,fast_taken); // Capture fast-control
// Fast path not-taken, i.e. slow path
Node *complex_path = _gvn.transform( new (C, 1) IfTrueNode(opt_if1) );
Node *complex_path = _gvn.transform( new (C, 1) IfTrueNode(if1) );
// Set fast path result
Node *fast_result = _gvn.transform( new (C, 3) PowDNode(0, y, x) );
Node *fast_result = _gvn.transform( new (C, 3) PowDNode(0, x, y) );
phi->init_req(3, fast_result);
// Complex path
// Build the second if node (if y is int)
// Node for (int)y
Node *inty = _gvn.transform( new (C, 2) ConvD2INode(y));
// Node for (double)((int) y)
Node *doubleinty= _gvn.transform( new (C, 2) ConvI2DNode(inty));
// Check (double)((int) y) : y
Node *cmpinty= _gvn.transform(new (C, 3) CmpDNode(doubleinty, y));
// Check if (y isn't int) then go to slow path
Node *bol2 = _gvn.transform( new (C, 2) BoolNode( cmpinty, BoolTest::ne ) );
// Build the second if node (if y is long)
// Node for (long)y
Node *longy = _gvn.transform( new (C, 2) ConvD2LNode(y));
// Node for (double)((long) y)
Node *doublelongy= _gvn.transform( new (C, 2) ConvL2DNode(longy));
// Check (double)((long) y) : y
Node *cmplongy= _gvn.transform(new (C, 3) CmpDNode(doublelongy, y));
// Check if (y isn't long) then go to slow path
Node *bol2 = _gvn.transform( new (C, 2) BoolNode( cmplongy, BoolTest::ne ) );
// Branch either way
IfNode *if2 = create_and_xform_if(complex_path,bol2, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN);
Node *slow_path = opt_iff(r,if2); // Set region path 2
Node* ylong_path = _gvn.transform( new (C, 1) IfFalseNode(if2));
Node *slow_path = _gvn.transform( new (C, 1) IfTrueNode(if2) );
// Calculate DPow(abs(x), y)*(1 & (int)y)
// Calculate DPow(abs(x), y)*(1 & (long)y)
// Node for constant 1
Node *conone = intcon(1);
// 1& (int)y
Node *signnode= _gvn.transform( new (C, 3) AndINode(conone, inty) );
Node *conone = longcon(1);
// 1& (long)y
Node *signnode= _gvn.transform( new (C, 3) AndLNode(conone, longy) );
// A huge number is always even. Detect a huge number by checking
// if y + 1 == y and set integer to be tested for parity to 0.
// Required for corner case:
// (long)9.223372036854776E18 = max_jlong
// (double)(long)9.223372036854776E18 = 9.223372036854776E18
// max_jlong is odd but 9.223372036854776E18 is even
Node* yplus1 = _gvn.transform( new (C, 3) AddDNode(y, makecon(TypeD::make(1))));
Node *cmpyplus1= _gvn.transform(new (C, 3) CmpDNode(yplus1, y));
Node *bolyplus1 = _gvn.transform( new (C, 2) BoolNode( cmpyplus1, BoolTest::eq ) );
Node* correctedsign = NULL;
if (ConditionalMoveLimit != 0) {
correctedsign = _gvn.transform( CMoveNode::make(C, NULL, bolyplus1, signnode, longcon(0), TypeLong::LONG));
} else {
IfNode *ifyplus1 = create_and_xform_if(ylong_path,bolyplus1, PROB_FAIR, COUNT_UNKNOWN);
RegionNode *r = new (C, 3) RegionNode(3);
Node *phi = new (C, 3) PhiNode(r, TypeLong::LONG);
r->init_req(1, _gvn.transform( new (C, 1) IfFalseNode(ifyplus1)));
r->init_req(2, _gvn.transform( new (C, 1) IfTrueNode(ifyplus1)));
phi->init_req(1, signnode);
phi->init_req(2, longcon(0));
correctedsign = _gvn.transform(phi);
ylong_path = _gvn.transform(r);
record_for_igvn(r);
}
// zero node
Node *conzero = intcon(0);
// Check (1&(int)y)==0?
Node *cmpeq1 = _gvn.transform(new (C, 3) CmpINode(signnode, conzero));
// Check if (1&(int)y)!=0?, if so the result is negative
Node *conzero = longcon(0);
// Check (1&(long)y)==0?
Node *cmpeq1 = _gvn.transform(new (C, 3) CmpLNode(correctedsign, conzero));
// Check if (1&(long)y)!=0?, if so the result is negative
Node *bol3 = _gvn.transform( new (C, 2) BoolNode( cmpeq1, BoolTest::ne ) );
// abs(x)
Node *absx=_gvn.transform( new (C, 2) AbsDNode(x));
// abs(x)^y
Node *absxpowy = _gvn.transform( new (C, 3) PowDNode(0, y, absx) );
Node *absxpowy = _gvn.transform( new (C, 3) PowDNode(0, absx, y) );
// -abs(x)^y
Node *negabsxpowy = _gvn.transform(new (C, 2) NegDNode (absxpowy));
// (1&(int)y)==1?-DPow(abs(x), y):DPow(abs(x), y)
Node *signresult = _gvn.transform( CMoveNode::make(C, NULL, bol3, absxpowy, negabsxpowy, Type::DOUBLE));
// (1&(long)y)==1?-DPow(abs(x), y):DPow(abs(x), y)
Node *signresult = NULL;
if (ConditionalMoveLimit != 0) {
signresult = _gvn.transform( CMoveNode::make(C, NULL, bol3, absxpowy, negabsxpowy, Type::DOUBLE));
} else {
IfNode *ifyeven = create_and_xform_if(ylong_path,bol3, PROB_FAIR, COUNT_UNKNOWN);
RegionNode *r = new (C, 3) RegionNode(3);
Node *phi = new (C, 3) PhiNode(r, Type::DOUBLE);
r->init_req(1, _gvn.transform( new (C, 1) IfFalseNode(ifyeven)));
r->init_req(2, _gvn.transform( new (C, 1) IfTrueNode(ifyeven)));
phi->init_req(1, absxpowy);
phi->init_req(2, negabsxpowy);
signresult = _gvn.transform(phi);
ylong_path = _gvn.transform(r);
record_for_igvn(r);
}
// Set complex path fast result
r->init_req(2, ylong_path);
phi->init_req(2, signresult);
static const jlong nan_bits = CONST64(0x7ff8000000000000);
......@@ -1689,27 +1763,10 @@ bool LibraryCallKit::inline_pow(vmIntrinsics::ID id) {
result=_gvn.transform(phi);
}
//-------------------
//result=(result.isNaN())? uncommon_trap():result;
// Check: If isNaN() by checking result!=result? then go to Strict Math
Node* cmpisnan = _gvn.transform(new (C, 3) CmpDNode(result,result));
// Build the boolean node
Node* bolisnum = _gvn.transform( new (C, 2) BoolNode(cmpisnan, BoolTest::eq) );
{ BuildCutout unless(this, bolisnum, PROB_STATIC_FREQUENT);
// End the current control-flow path
push_pair(x);
push_pair(y);
// Math.pow intrinsic returned a NaN, which requires StrictMath.pow
// to handle. Recompile without intrinsifying Math.pow.
uncommon_trap(Deoptimization::Reason_intrinsic,
Deoptimization::Action_make_not_entrant);
}
finish_pow_exp(result, x, y, OptoRuntime::Math_DD_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dpow), "POW");
C->set_has_split_ifs(true); // Has chance for split-if optimization
push_pair(result);
return true;
}
......
......@@ -1278,9 +1278,9 @@ void Parse::sharpen_type_after_if(BoolTest::mask btest,
// or the narrowOop equivalent.
const Type* obj_type = _gvn.type(obj);
const TypeOopPtr* tboth = obj_type->join(con_type)->isa_oopptr();
if (tboth != NULL && tboth != obj_type && tboth->higher_equal(obj_type)) {
if (tboth != NULL && tboth->klass_is_exact() && tboth != obj_type &&
tboth->higher_equal(obj_type)) {
// obj has to be of the exact type Foo if the CmpP succeeds.
assert(tboth->klass_is_exact(), "klass should be exact");
int obj_in_map = map()->find_edge(obj);
JVMState* jvms = this->jvms();
if (obj_in_map >= 0 &&
......
......@@ -554,9 +554,7 @@ const Type *CmpUNode::sub( const Type *t1, const Type *t2 ) const {
return TypeInt::CC_GE;
} else if (hi0 <= lo1) {
// Check for special case in Hashtable::get. (See below.)
if ((jint)lo0 >= 0 && (jint)lo1 >= 0 &&
in(1)->Opcode() == Op_ModI &&
in(1)->in(2) == in(2) )
if ((jint)lo0 >= 0 && (jint)lo1 >= 0 && is_index_range_check())
return TypeInt::CC_LT;
return TypeInt::CC_LE;
}
......@@ -567,13 +565,17 @@ const Type *CmpUNode::sub( const Type *t1, const Type *t2 ) const {
// to be positive.
// (This is a gross hack, since the sub method never
// looks at the structure of the node in any other case.)
if ((jint)lo0 >= 0 && (jint)lo1 >= 0 &&
in(1)->Opcode() == Op_ModI &&
in(1)->in(2)->uncast() == in(2)->uncast())
if ((jint)lo0 >= 0 && (jint)lo1 >= 0 && is_index_range_check())
return TypeInt::CC_LT;
return TypeInt::CC; // else use worst case results
}
bool CmpUNode::is_index_range_check() const {
// Check for the "(X ModI Y) CmpU Y" shape
return (in(1)->Opcode() == Op_ModI &&
in(1)->in(2)->eqv_uncast(in(2)));
}
//------------------------------Idealize---------------------------------------
Node *CmpINode::Ideal( PhaseGVN *phase, bool can_reshape ) {
if (phase->type(in(2))->higher_equal(TypeInt::ZERO)) {
......
......@@ -158,6 +158,7 @@ public:
CmpUNode( Node *in1, Node *in2 ) : CmpNode(in1,in2) {}
virtual int Opcode() const;
virtual const Type *sub( const Type *, const Type * ) const;
bool is_index_range_check() const;
};
//------------------------------CmpPNode---------------------------------------
......
......@@ -268,14 +268,18 @@ void JvmtiClassFileReconstituter::write_source_file_attribute() {
// JSR45| SourceDebugExtension_attribute {
// JSR45| u2 attribute_name_index;
// JSR45| u4 attribute_length;
// JSR45| u2 sourcefile_index;
// JSR45| u1 debug_extension[attribute_length];
// JSR45| }
void JvmtiClassFileReconstituter::write_source_debug_extension_attribute() {
assert(ikh()->source_debug_extension() != NULL, "caller must check");
write_attribute_name_index("SourceDebugExtension");
write_u4(2); // always length 2
write_u2(symbol_to_cpool_index(ikh()->source_debug_extension()));
int len = (int)strlen(ikh()->source_debug_extension());
write_u4(len);
u1* ext = (u1*)ikh()->source_debug_extension();
for (int i=0; i<len; i++) {
write_u1(ext[i]);
}
}
// Write (generic) Signature attribute
......
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2012, 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
......@@ -2541,15 +2541,12 @@ JvmtiEnv::GetSourceDebugExtension(oop k_mirror, char** source_debug_extension_pt
if (!Klass::cast(k)->oop_is_instance()) {
return JVMTI_ERROR_ABSENT_INFORMATION;
}
Symbol* sdeOop = instanceKlass::cast(k)->source_debug_extension();
NULL_CHECK(sdeOop, JVMTI_ERROR_ABSENT_INFORMATION);
char* sde = instanceKlass::cast(k)->source_debug_extension();
NULL_CHECK(sde, JVMTI_ERROR_ABSENT_INFORMATION);
{
JavaThread* current_thread = JavaThread::current();
ResourceMark rm(current_thread);
const char* sdecp = (const char*) sdeOop->as_C_string();
*source_debug_extension_ptr = (char *) jvmtiMalloc(strlen(sdecp)+1);
strcpy(*source_debug_extension_ptr, sdecp);
*source_debug_extension_ptr = (char *) jvmtiMalloc(strlen(sde)+1);
strcpy(*source_debug_extension_ptr, sde);
}
}
......
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2012, 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
......@@ -3236,7 +3236,9 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass,
// Copy the "source debug extension" attribute from new class version
the_class->set_source_debug_extension(
scratch_class->source_debug_extension());
scratch_class->source_debug_extension(),
scratch_class->source_debug_extension() == NULL ? 0 :
(int)strlen(scratch_class->source_debug_extension()));
// Use of javac -g could be different in the old and the new
if (scratch_class->access_flags().has_localvariable_table() !=
......
......@@ -113,6 +113,9 @@ const char* WhiteBox::lookup_jstring(const char* field_name, oop object) {
int offset = offset_for_field(field_name, object,
vmSymbols::string_signature());
oop string = object->obj_field(offset);
if (string == NULL) {
return NULL;
}
const char* ret = java_lang_String::as_utf8_string(string);
return ret;
}
......
......@@ -2983,7 +2983,10 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
const char* tail;
// If flag "-XX:Flags=flags-file" is used it will be the first option to be processed.
const char* hotspotrc = ".hotspotrc";
bool settings_file_specified = false;
bool needs_hotspotrc_warning = false;
const char* flags_file;
int index;
for (index = 0; index < args->nOptions; index++) {
......@@ -3031,16 +3034,19 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
if (!process_settings_file(flags_file, true, args->ignoreUnrecognized)) {
return JNI_EINVAL;
}
}
} else {
#ifdef ASSERT
// Parse default .hotspotrc settings file
if (!settings_file_specified) {
// Parse default .hotspotrc settings file
if (!process_settings_file(".hotspotrc", false, args->ignoreUnrecognized)) {
return JNI_EINVAL;
}
}
#else
struct stat buf;
if (os::stat(hotspotrc, &buf) == 0) {
needs_hotspotrc_warning = true;
}
#endif
}
if (PrintVMOptions) {
for (index = 0; index < args->nOptions; index++) {
......@@ -3057,6 +3063,14 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
return result;
}
// Delay warning until here so that we've had a chance to process
// the -XX:-PrintWarnings flag
if (needs_hotspotrc_warning) {
warning("%s file is present but has been ignored. "
"Run with -XX:Flags=%s to load the file.",
hotspotrc, hotspotrc);
}
#if (defined JAVASE_EMBEDDED || defined ARM)
UNSUPPORTED_OPTION(UseG1GC, "G1 GC");
#endif
......
......@@ -308,7 +308,7 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
nonstatic_field(instanceKlass, _protection_domain, oop) \
nonstatic_field(instanceKlass, _signers, objArrayOop) \
nonstatic_field(instanceKlass, _source_file_name, Symbol*) \
nonstatic_field(instanceKlass, _source_debug_extension, Symbol*) \
nonstatic_field(instanceKlass, _source_debug_extension, char*) \
nonstatic_field(instanceKlass, _inner_classes, typeArrayOop) \
nonstatic_field(instanceKlass, _nonstatic_field_size, int) \
nonstatic_field(instanceKlass, _static_field_size, int) \
......
......@@ -48,7 +48,7 @@ public:
"With no argument this will show a list of available commands. "
"'help all' will show help for all commands.";
}
static const char* impact() { return "Low: "; }
static const char* impact() { return "Low"; }
static int num_arguments();
virtual void execute(TRAPS);
};
......@@ -60,7 +60,7 @@ public:
static const char* description() {
return "Print JVM version information.";
}
static const char* impact() { return "Low: "; }
static const char* impact() { return "Low"; }
static int num_arguments() { return 0; }
virtual void execute(TRAPS);
};
......@@ -72,7 +72,7 @@ public:
static const char* description() {
return "Print the command line used to start this VM instance.";
}
static const char* impact() { return "Low: "; }
static const char* impact() { return "Low"; }
static int num_arguments() { return 0; }
virtual void execute(TRAPS) {
Arguments::print_on(_output);
......@@ -88,7 +88,7 @@ public:
return "Print system properties.";
}
static const char* impact() {
return "Low: ";
return "Low";
}
static int num_arguments() { return 0; }
virtual void execute(TRAPS);
......@@ -105,7 +105,7 @@ public:
return "Print VM flag options and their current values.";
}
static const char* impact() {
return "Low: ";
return "Low";
}
static int num_arguments();
virtual void execute(TRAPS);
......@@ -121,7 +121,7 @@ public:
return "Print VM uptime.";
}
static const char* impact() {
return "Low: ";
return "Low";
}
static int num_arguments();
virtual void execute(TRAPS);
......
......@@ -75,11 +75,13 @@ bool DCmdArgIter::next(TRAPS) {
}
// extracting first item, argument or option name
_key_addr = &_buffer[_cursor];
bool arg_had_quotes = false;
while (_cursor <= _len - 1 && _buffer[_cursor] != '=' && _buffer[_cursor] != _delim) {
// argument can be surrounded by single or double quotes
if (_buffer[_cursor] == '\"' || _buffer[_cursor] == '\'') {
_key_addr++;
char quote = _buffer[_cursor];
arg_had_quotes = true;
while (_cursor < _len - 1) {
_cursor++;
if (_buffer[_cursor] == quote && _buffer[_cursor - 1] != '\\') {
......@@ -95,16 +97,22 @@ bool DCmdArgIter::next(TRAPS) {
_cursor++;
}
_key_len = &_buffer[_cursor] - _key_addr;
if (arg_had_quotes) {
// if the argument was quoted, we need to step past the last quote here
_cursor++;
}
// check if the argument has the <key>=<value> format
if (_cursor <= _len -1 && _buffer[_cursor] == '=') {
_cursor++;
_value_addr = &_buffer[_cursor];
bool value_had_quotes = false;
// extract the value
while (_cursor <= _len - 1 && _buffer[_cursor] != _delim) {
// value can be surrounded by simple or double quotes
if (_buffer[_cursor] == '\"' || _buffer[_cursor] == '\'') {
_value_addr++;
char quote = _buffer[_cursor];
value_had_quotes = true;
while (_cursor < _len - 1) {
_cursor++;
if (_buffer[_cursor] == quote && _buffer[_cursor - 1] != '\\') {
......@@ -120,6 +128,10 @@ bool DCmdArgIter::next(TRAPS) {
_cursor++;
}
_value_len = &_buffer[_cursor] - _value_addr;
if (value_had_quotes) {
// if the value was quoted, we need to step past the last quote here
_cursor++;
}
} else {
_value_addr = NULL;
_value_len = 0;
......@@ -185,8 +197,17 @@ void DCmdParser::parse(CmdLine* line, char delim, TRAPS) {
arg->read_value(iter.key_addr(), iter.key_length(), CHECK);
next_argument = next_argument->next();
} else {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"Unknown argument in diagnostic command");
const size_t buflen = 120;
const size_t argbuflen = 30;
char buf[buflen];
char argbuf[argbuflen];
size_t len = MIN2<size_t>(iter.key_length(), argbuflen - 1);
strncpy(argbuf, iter.key_addr(), len);
argbuf[len] = '\0';
jio_snprintf(buf, buflen - 1, "Unknown argument '%s' in diagnostic command.", argbuf);
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), buf);
}
}
cont = iter.next(CHECK);
......@@ -207,19 +228,21 @@ GenDCmdArgument* DCmdParser::lookup_dcmd_option(const char* name, size_t len) {
}
void DCmdParser::check(TRAPS) {
const size_t buflen = 256;
char buf[buflen];
GenDCmdArgument* arg = _arguments_list;
while (arg != NULL) {
if (arg->is_mandatory() && !arg->has_value()) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"Missing argument for diagnostic command");
jio_snprintf(buf, buflen - 1, "The argument '%s' is mandatory.", arg->name());
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), buf);
}
arg = arg->next();
}
arg = _options;
while (arg != NULL) {
if (arg->is_mandatory() && !arg->has_value()) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"Missing option for diagnostic command");
jio_snprintf(buf, buflen - 1, "The option '%s' is mandatory.", arg->name());
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), buf);
}
arg = arg->next();
}
......
......@@ -238,6 +238,16 @@ public:
static const char* name() { return "No Name";}
static const char* description() { return "No Help";}
static const char* disabled_message() { return "Diagnostic command currently disabled"; }
// The impact() method returns a description of the intrusiveness of the diagnostic
// command on the Java Virtual Machine behavior. The rational for this method is that some
// diagnostic commands can seriously disrupt the behavior of the Java Virtual Machine
// (for instance a Thread Dump for an application with several tens of thousands of threads,
// or a Head Dump with a 40GB+ heap size) and other diagnostic commands have no serious
// impact on the JVM (for instance, getting the command line arguments or the JVM version).
// The recommended format for the description is <impact level>: [longer description],
// where the impact level is selected among this list: {Low, Medium, High}. The optional
// longer description can provide more specific details like the fact that Thread Dump
// impact depends on the heap size.
static const char* impact() { return "Low: No impact"; }
static int num_arguments() { return 0; }
outputStream* output() { return _output; }
......@@ -250,7 +260,7 @@ public:
bool has_arg = iter.next(CHECK);
if (has_arg) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"Unknown argument in diagnostic command");
"The argument list of this diagnostic command should be empty.");
}
}
virtual void execute(TRAPS) { }
......
/*
* Copyright (c) 2012, 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.
*
*/
/*
* Micro-benchmark for Math.pow() and Math.exp()
*/
import java.util.*;
public class Test7177917 {
static double d;
static Random r = new Random(0);
static long m_pow(double[][] values) {
double res = 0;
long start = System.nanoTime();
for (int i = 0; i < values.length; i++) {
res += Math.pow(values[i][0], values[i][1]);
}
long stop = System.nanoTime();
d = res;
return (stop - start) / 1000;
}
static long m_exp(double[] values) {
double res = 0;
long start = System.nanoTime();
for (int i = 0; i < values.length; i++) {
res += Math.exp(values[i]);
}
long stop = System.nanoTime();
d = res;
return (stop - start) / 1000;
}
static double[][] pow_values(int nb) {
double[][] res = new double[nb][2];
for (int i = 0; i < nb; i++) {
double ylogx = (1 + (r.nextDouble() * 2045)) - 1023; // 2045 rather than 2046 as a safety margin
double x = Math.abs(Double.longBitsToDouble(r.nextLong()));
while (x != x) {
x = Math.abs(Double.longBitsToDouble(r.nextLong()));
}
double logx = Math.log(x) / Math.log(2);
double y = ylogx / logx;
res[i][0] = x;
res[i][1] = y;
}
return res;
}
static double[] exp_values(int nb) {
double[] res = new double[nb];
for (int i = 0; i < nb; i++) {
double ylogx = (1 + (r.nextDouble() * 2045)) - 1023; // 2045 rather than 2046 as a safety margin
double x = Math.E;
double logx = Math.log(x) / Math.log(2);
double y = ylogx / logx;
res[i] = y;
}
return res;
}
static public void main(String[] args) {
{
// warmup
double[][] warmup_values = pow_values(10);
m_pow(warmup_values);
for (int i = 0; i < 20000; i++) {
m_pow(warmup_values);
}
// test pow perf
double[][] values = pow_values(1000000);
System.out.println("==> POW " + m_pow(values));
// force uncommon trap
double[][] nan_values = new double[1][2];
nan_values[0][0] = Double.NaN;
nan_values[0][1] = Double.NaN;
m_pow(nan_values);
// force recompilation
for (int i = 0; i < 20000; i++) {
m_pow(warmup_values);
}
// test pow perf again
System.out.println("==> POW " + m_pow(values));
}
{
// warmup
double[] warmup_values = exp_values(10);
m_exp(warmup_values);
for (int i = 0; i < 20000; i++) {
m_exp(warmup_values);
}
// test pow perf
double[] values = exp_values(1000000);
System.out.println("==> EXP " + m_exp(values));
// force uncommon trap
double[] nan_values = new double[1];
nan_values[0] = Double.NaN;
m_exp(nan_values);
// force recompilation
for (int i = 0; i < 20000; i++) {
m_exp(warmup_values);
}
// test pow perf again
System.out.println("==> EXP " + m_exp(values));
}
}
}
/*
* Copyright (c) 2012, 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 6294277
* @summary java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
* @run main/othervm -Xdebug -Xrunjdwp:transport=dt_socket,address=8888,server=y,suspend=n SourceDebugExtension
*/
import java.io.*;
public class SourceDebugExtension extends ClassLoader
{
static final int attrSize = 68000;
static byte[] header = {
(byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x32, (byte)0x00, (byte)0x1e, (byte)0x0a, (byte)0x00, (byte)0x06, (byte)0x00,
(byte)0x0f, (byte)0x09, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x11, (byte)0x08,
(byte)0x00, (byte)0x12, (byte)0x0a, (byte)0x00, (byte)0x13, (byte)0x00, (byte)0x14,
(byte)0x07, (byte)0x00, (byte)0x15, (byte)0x07, (byte)0x00, (byte)0x16, (byte)0x01,
(byte)0x00, (byte)0x06, (byte)0x3c, (byte)0x69, (byte)0x6e, (byte)0x69, (byte)0x74,
(byte)0x3e, (byte)0x01, (byte)0x00, (byte)0x03, (byte)0x28, (byte)0x29, (byte)0x56,
(byte)0x01, (byte)0x00, (byte)0x04, (byte)0x43, (byte)0x6f, (byte)0x64, (byte)0x65,
(byte)0x01, (byte)0x00, (byte)0x0f, (byte)0x4c, (byte)0x69, (byte)0x6e, (byte)0x65,
(byte)0x4e, (byte)0x75, (byte)0x6d, (byte)0x62, (byte)0x65, (byte)0x72, (byte)0x54,
(byte)0x61, (byte)0x62, (byte)0x6c, (byte)0x65, (byte)0x01, (byte)0x00, (byte)0x04,
(byte)0x6d, (byte)0x61, (byte)0x69, (byte)0x6e, (byte)0x01, (byte)0x00, (byte)0x16,
(byte)0x28, (byte)0x5b, (byte)0x4c, (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61,
(byte)0x2f, (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2f, (byte)0x53,
(byte)0x74, (byte)0x72, (byte)0x69, (byte)0x6e, (byte)0x67, (byte)0x3b, (byte)0x29,
(byte)0x56, (byte)0x01, (byte)0x00, (byte)0x0a, (byte)0x53, (byte)0x6f, (byte)0x75,
(byte)0x72, (byte)0x63, (byte)0x65, (byte)0x46, (byte)0x69, (byte)0x6c, (byte)0x65,
(byte)0x01, (byte)0x00, (byte)0x0d, (byte)0x54, (byte)0x65, (byte)0x73, (byte)0x74,
(byte)0x50, (byte)0x72, (byte)0x6f, (byte)0x67, (byte)0x2e, (byte)0x6a, (byte)0x61,
(byte)0x76, (byte)0x61, (byte)0x0c, (byte)0x00, (byte)0x07, (byte)0x00, (byte)0x08,
(byte)0x07, (byte)0x00, (byte)0x17, (byte)0x0c, (byte)0x00, (byte)0x18, (byte)0x00,
(byte)0x19, (byte)0x01, (byte)0x00, (byte)0x34, (byte)0x54, (byte)0x65, (byte)0x73,
(byte)0x74, (byte)0x20, (byte)0x70, (byte)0x72, (byte)0x6f, (byte)0x67, (byte)0x72,
(byte)0x61, (byte)0x6d, (byte)0x20, (byte)0x66, (byte)0x6f, (byte)0x72, (byte)0x20,
(byte)0x62, (byte)0x69, (byte)0x67, (byte)0x20, (byte)0x53, (byte)0x6f, (byte)0x75,
(byte)0x72, (byte)0x63, (byte)0x65, (byte)0x44, (byte)0x65, (byte)0x62, (byte)0x75,
(byte)0x67, (byte)0x45, (byte)0x78, (byte)0x74, (byte)0x65, (byte)0x6e, (byte)0x73,
(byte)0x69, (byte)0x6f, (byte)0x6e, (byte)0x20, (byte)0x61, (byte)0x74, (byte)0x74,
(byte)0x72, (byte)0x69, (byte)0x62, (byte)0x75, (byte)0x74, (byte)0x65, (byte)0x73,
(byte)0x07, (byte)0x00, (byte)0x1a, (byte)0x0c, (byte)0x00, (byte)0x1b, (byte)0x00,
(byte)0x1c, (byte)0x01, (byte)0x00, (byte)0x08, (byte)0x54, (byte)0x65, (byte)0x73,
(byte)0x74, (byte)0x50, (byte)0x72, (byte)0x6f, (byte)0x67, (byte)0x01, (byte)0x00,
(byte)0x10, (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x6c,
(byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2f, (byte)0x4f, (byte)0x62, (byte)0x6a,
(byte)0x65, (byte)0x63, (byte)0x74, (byte)0x01, (byte)0x00, (byte)0x10, (byte)0x6a,
(byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x6c, (byte)0x61, (byte)0x6e,
(byte)0x67, (byte)0x2f, (byte)0x53, (byte)0x79, (byte)0x73, (byte)0x74, (byte)0x65,
(byte)0x6d, (byte)0x01, (byte)0x00, (byte)0x03, (byte)0x6f, (byte)0x75, (byte)0x74,
(byte)0x01, (byte)0x00, (byte)0x15, (byte)0x4c, (byte)0x6a, (byte)0x61, (byte)0x76,
(byte)0x61, (byte)0x2f, (byte)0x69, (byte)0x6f, (byte)0x2f, (byte)0x50, (byte)0x72,
(byte)0x69, (byte)0x6e, (byte)0x74, (byte)0x53, (byte)0x74, (byte)0x72, (byte)0x65,
(byte)0x61, (byte)0x6d, (byte)0x3b, (byte)0x01, (byte)0x00, (byte)0x13, (byte)0x6a,
(byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x69, (byte)0x6f, (byte)0x2f,
(byte)0x50, (byte)0x72, (byte)0x69, (byte)0x6e, (byte)0x74, (byte)0x53, (byte)0x74,
(byte)0x72, (byte)0x65, (byte)0x61, (byte)0x6d, (byte)0x01, (byte)0x00, (byte)0x07,
(byte)0x70, (byte)0x72, (byte)0x69, (byte)0x6e, (byte)0x74, (byte)0x6c, (byte)0x6e,
(byte)0x01, (byte)0x00, (byte)0x15, (byte)0x28, (byte)0x4c, (byte)0x6a, (byte)0x61,
(byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67,
(byte)0x2f, (byte)0x53, (byte)0x74, (byte)0x72, (byte)0x69, (byte)0x6e, (byte)0x67,
(byte)0x3b, (byte)0x29, (byte)0x56, (byte)0x01, (byte)0x00, (byte)0x14, (byte)0x53,
(byte)0x6f, (byte)0x75, (byte)0x72, (byte)0x63, (byte)0x65, (byte)0x44, (byte)0x65,
(byte)0x62, (byte)0x75, (byte)0x67, (byte)0x45, (byte)0x78, (byte)0x74, (byte)0x65,
(byte)0x6e, (byte)0x73, (byte)0x69, (byte)0x6f, (byte)0x6e, (byte)0x00, (byte)0x21,
(byte)0x00, (byte)0x05, (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x07,
(byte)0x00, (byte)0x08, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x09, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x1d, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x01,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x05, (byte)0x2a, (byte)0xb7, (byte)0x00,
(byte)0x01, (byte)0xb1, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00,
(byte)0x0a, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x01,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x09, (byte)0x00,
(byte)0x0b, (byte)0x00, (byte)0x0c, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x09,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x25, (byte)0x00, (byte)0x02, (byte)0x00,
(byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x09, (byte)0xb2, (byte)0x00,
(byte)0x02, (byte)0x12, (byte)0x03, (byte)0xb6, (byte)0x00, (byte)0x04, (byte)0xb1,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x0a, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x03, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x04, (byte)0x00,
(byte)0x02, (byte)0x00, (byte)0x0d, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02,
(byte)0x00, (byte)0x0e, (byte)0x00, (byte)0x1d, (byte)0x00, (byte)0x01, (byte)0x09,
(byte)0xa0
};
public static void main(String[] args) throws Exception
{
try {
SourceDebugExtension loader = new SourceDebugExtension();
/* The test program creates a class file from the header
* stored above and adding the content of a SourceDebugExtension
* attribute made of the character 0x02 repeated 68000 times.
* This attribute doesn't follow the syntax specified in JSR 45
* but it's fine because this test just checks that the JVM is
* able to load a class file with a SourceDebugExtension
* attribute bigger than 64KB. The JVM doesn't try to
* parse the content of the attribute, this work is performed
* by the SA or external tools.
*/
byte[] buf = new byte[header.length + attrSize];
for(int i=0; i<header.length; i++) {
buf[i] = header[i];
}
for(int i=0; i<attrSize; i++) {
buf[header.length+i] = (byte)0x02;
}
Class c = loader.defineClass("TestProg", buf, 0, buf.length);
System.out.println("Test PASSES");
} catch(Exception e) {
System.out.println("Test FAILS");
}
}
}
......@@ -2,10 +2,9 @@
##
## @test
## @bug 7020373 7055247
## @bug 7020373 7055247 7053586
## @key cte_test
## @summary JSR rewriting can overflow memory address size variables
## @ignore Ignore it until 7053586 fixed
## @run shell Test7020373.sh
##
......@@ -30,7 +29,7 @@ fi
# set platform-dependent variables
OS=`uname -s`
case "$OS" in
SunOS | Linux )
SunOS | Linux | Darwin )
NULL=/dev/null
PS=":"
FS="/"
......@@ -66,7 +65,7 @@ then
echo "Test Failed"
exit 1
else
grep "java.lang.LinkageError" test.out
egrep "java.lang.LinkageError|java.lang.NoSuchMethodError|Main method not found in class OOMCrashClass4000_1|insufficient memory" test.out
if [ $? = 0 ]
then
echo "Test Passed"
......
......@@ -20,6 +20,7 @@ public class ParserTest {
testNanoTime();
testJLong();
testBool();
testQuotes();
testMemorySize();
}
......@@ -95,6 +96,33 @@ public class ParserTest {
parse(name, "false", "", args);
}
public void testQuotes() throws Exception {
String name = "name";
DiagnosticCommand arg1 = new DiagnosticCommand(name,
"desc", DiagnosticArgumentType.STRING,
false, null);
DiagnosticCommand arg2 = new DiagnosticCommand("arg",
"desc", DiagnosticArgumentType.STRING,
false, null);
DiagnosticCommand[] args = {arg1, arg2};
// try with a quoted value
parse(name, "Recording 1", name + "=\"Recording 1\"", args);
// try with a quoted argument
parse(name, "myrec", "\"" + name + "\"" + "=myrec", args);
// try with both a quoted value and a quoted argument
parse(name, "Recording 1", "\"" + name + "\"" + "=\"Recording 1\"", args);
// now the same thing but with other arguments after
// try with a quoted value
parse(name, "Recording 1", name + "=\"Recording 1\",arg=value", args);
// try with a quoted argument
parse(name, "myrec", "\"" + name + "\"" + "=myrec,arg=value", args);
// try with both a quoted value and a quoted argument
parse(name, "Recording 1", "\"" + name + "\"" + "=\"Recording 1\",arg=value", args);
}
public void testMemorySize() throws Exception {
String name = "name";
String defaultValue = "1024";
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册