From 696e17c0ba6b44d02c806a89ff537f09f4b7f925 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Thu, 3 Jul 2008 18:02:47 -0700 Subject: [PATCH 01/52] 6684714: Optimize EA Connection Graph build performance Switch on EA by default, optimize Connection Graph construction Reviewed-by: rasbold, never --- hotspot/src/share/vm/compiler/oopMap.cpp | 21 +- hotspot/src/share/vm/compiler/oopMap.hpp | 8 +- hotspot/src/share/vm/opto/bytecodeInfo.cpp | 2 +- hotspot/src/share/vm/opto/c2_globals.hpp | 2 +- hotspot/src/share/vm/opto/compile.cpp | 16 +- hotspot/src/share/vm/opto/escape.cpp | 474 +++++++++++---------- hotspot/src/share/vm/opto/escape.hpp | 52 ++- 7 files changed, 290 insertions(+), 285 deletions(-) diff --git a/hotspot/src/share/vm/compiler/oopMap.cpp b/hotspot/src/share/vm/compiler/oopMap.cpp index 2984d647ea8..78bef1836c8 100644 --- a/hotspot/src/share/vm/compiler/oopMap.cpp +++ b/hotspot/src/share/vm/compiler/oopMap.cpp @@ -188,10 +188,6 @@ void OopMap::set_derived_oop(VMReg reg, VMReg derived_from_local_register ) { } } -void OopMap::set_stack_obj(VMReg reg) { - set_xxx(reg, OopMapValue::stack_obj, VMRegImpl::Bad()); -} - // OopMapSet OopMapSet::OopMapSet() { @@ -399,8 +395,7 @@ void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map, if ( loc != NULL ) { if ( omv.type() == OopMapValue::oop_value ) { #ifdef ASSERT - if (COMPILER2_PRESENT(!DoEscapeAnalysis &&) - (((uintptr_t)loc & (sizeof(*loc)-1)) != 0) || + if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) || !Universe::heap()->is_in_or_null(*loc)) { tty->print_cr("# Found non oop pointer. Dumping state at failure"); // try to dump out some helpful debugging information @@ -431,17 +426,6 @@ void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map, } } } - -#ifdef COMPILER2 - if (DoEscapeAnalysis) { - for (OopMapStream oms(map, OopMapValue::stack_obj); !oms.is_done(); oms.next()) { - omv = oms.current(); - assert(omv.is_stack_loc(), "should refer to stack location"); - oop loc = (oop) fr->oopmapreg_to_location(omv.reg(),reg_map); - oop_fn->do_oop(&loc); - } - } -#endif // COMPILER2 } @@ -540,9 +524,6 @@ void print_register_type(OopMapValue::oop_types x, VMReg optional, st->print("Derived_oop_" ); optional->print_on(st); break; - case OopMapValue::stack_obj: - st->print("Stack"); - break; default: ShouldNotReachHere(); } diff --git a/hotspot/src/share/vm/compiler/oopMap.hpp b/hotspot/src/share/vm/compiler/oopMap.hpp index ac05d570c04..bce97de176c 100644 --- a/hotspot/src/share/vm/compiler/oopMap.hpp +++ b/hotspot/src/share/vm/compiler/oopMap.hpp @@ -46,7 +46,7 @@ private: public: // Constants - enum { type_bits = 6, + enum { type_bits = 5, register_bits = BitsPerShort - type_bits }; enum { type_shift = 0, @@ -63,8 +63,7 @@ public: value_value = 2, narrowoop_value = 4, callee_saved_value = 8, - derived_oop_value= 16, - stack_obj = 32 }; + derived_oop_value= 16 }; // Constructors OopMapValue () { set_value(0); set_content_reg(VMRegImpl::Bad()); } @@ -93,14 +92,12 @@ public: bool is_narrowoop() { return mask_bits(value(), type_mask_in_place) == narrowoop_value; } bool is_callee_saved() { return mask_bits(value(), type_mask_in_place) == callee_saved_value; } bool is_derived_oop() { return mask_bits(value(), type_mask_in_place) == derived_oop_value; } - bool is_stack_obj() { return mask_bits(value(), type_mask_in_place) == stack_obj; } void set_oop() { set_value((value() & register_mask_in_place) | oop_value); } void set_value() { set_value((value() & register_mask_in_place) | value_value); } void set_narrowoop() { set_value((value() & register_mask_in_place) | narrowoop_value); } void set_callee_saved() { set_value((value() & register_mask_in_place) | callee_saved_value); } void set_derived_oop() { set_value((value() & register_mask_in_place) | derived_oop_value); } - void set_stack_obj() { set_value((value() & register_mask_in_place) | stack_obj); } VMReg reg() const { return VMRegImpl::as_VMReg(mask_bits(value(), register_mask_in_place) >> register_shift); } oop_types type() const { return (oop_types)mask_bits(value(), type_mask_in_place); } @@ -180,7 +177,6 @@ class OopMap: public ResourceObj { void set_dead ( VMReg local); void set_callee_saved( VMReg local, VMReg caller_machine_register ); void set_derived_oop ( VMReg local, VMReg derived_from_local_register ); - void set_stack_obj( VMReg local); void set_xxx(VMReg reg, OopMapValue::oop_types x, VMReg optional); int heap_size() const; diff --git a/hotspot/src/share/vm/opto/bytecodeInfo.cpp b/hotspot/src/share/vm/opto/bytecodeInfo.cpp index 1b12ee877ad..b1fe31aed2e 100644 --- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp +++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp @@ -83,7 +83,7 @@ static bool is_init_with_ea(ciMethod* callee_method, ciMethod* caller_method, Compile* C) { // True when EA is ON and a java constructor is called or // a super constructor is called from an inlined java constructor. - return DoEscapeAnalysis && EliminateAllocations && + return C->do_escape_analysis() && EliminateAllocations && ( callee_method->is_initializer() || (caller_method->is_initializer() && caller_method != C->method() && diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp index 691914e2b0a..7cdf24bdc23 100644 --- a/hotspot/src/share/vm/opto/c2_globals.hpp +++ b/hotspot/src/share/vm/opto/c2_globals.hpp @@ -373,7 +373,7 @@ product(intx, AutoBoxCacheMax, 128, \ "Sets max value cached by the java.lang.Integer autobox cache") \ \ - product(bool, DoEscapeAnalysis, false, \ + product(bool, DoEscapeAnalysis, true, \ "Perform escape analysis") \ \ notproduct(bool, PrintEscapeAnalysis, false, \ diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp index 019ca50ae59..f193d5d2d11 100644 --- a/hotspot/src/share/vm/opto/compile.cpp +++ b/hotspot/src/share/vm/opto/compile.cpp @@ -583,18 +583,22 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr NOT_PRODUCT( verify_graph_edges(); ) // Perform escape analysis - if (_do_escape_analysis) - _congraph = new ConnectionGraph(this); - if (_congraph != NULL) { - NOT_PRODUCT( TracePhase t2("escapeAnalysis", &_t_escapeAnalysis, TimeCompiler); ) - _congraph->compute_escape(); - if (failing()) return; + if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) { + TracePhase t2("escapeAnalysis", &_t_escapeAnalysis, true); + + _congraph = new(comp_arena()) ConnectionGraph(this); + bool has_non_escaping_obj = _congraph->compute_escape(); #ifndef PRODUCT if (PrintEscapeAnalysis) { _congraph->dump(); } #endif + if (!has_non_escaping_obj) { + _congraph = NULL; + } + + if (failing()) return; } // Now optimize Optimize(); diff --git a/hotspot/src/share/vm/opto/escape.cpp b/hotspot/src/share/vm/opto/escape.cpp index ad6c8826270..7fee3d3d44f 100644 --- a/hotspot/src/share/vm/opto/escape.cpp +++ b/hotspot/src/share/vm/opto/escape.cpp @@ -25,16 +25,6 @@ #include "incls/_precompiled.incl" #include "incls/_escape.cpp.incl" -uint PointsToNode::edge_target(uint e) const { - assert(_edges != NULL && e < (uint)_edges->length(), "valid edge index"); - return (_edges->at(e) >> EdgeShift); -} - -PointsToNode::EdgeType PointsToNode::edge_type(uint e) const { - assert(_edges != NULL && e < (uint)_edges->length(), "valid edge index"); - return (EdgeType) (_edges->at(e) & EdgeMask); -} - void PointsToNode::add_edge(uint targIdx, PointsToNode::EdgeType et) { uint v = (targIdx << EdgeShift) + ((uint) et); if (_edges == NULL) { @@ -87,12 +77,13 @@ void PointsToNode::dump() const { } #endif -ConnectionGraph::ConnectionGraph(Compile * C) : _processed(C->comp_arena()), _node_map(C->comp_arena()) { - _collecting = true; - this->_compile = C; - const PointsToNode &dummy = PointsToNode(); - int sz = C->unique(); - _nodes = new(C->comp_arena()) GrowableArray(C->comp_arena(), sz, sz, dummy); +ConnectionGraph::ConnectionGraph(Compile * C) : + _nodes(C->comp_arena(), C->unique(), C->unique(), PointsToNode()), + _processed(C->comp_arena()), + _collecting(true), + _compile(C), + _node_map(C->comp_arena()) { + _phantom_object = C->top()->_idx; PointsToNode *phn = ptnode_adr(_phantom_object); phn->_node = C->top(); @@ -182,32 +173,36 @@ PointsToNode::EscapeState ConnectionGraph::escape_state(Node *n, PhaseTransform // If we are still collecting or there were no non-escaping allocations // we don't know the answer yet - if (_collecting || !_has_allocations) + if (_collecting) return PointsToNode::UnknownEscape; // if the node was created after the escape computation, return // UnknownEscape - if (idx >= (uint)_nodes->length()) + if (idx >= nodes_size()) return PointsToNode::UnknownEscape; - es = _nodes->at_grow(idx).escape_state(); + es = ptnode_adr(idx)->escape_state(); // if we have already computed a value, return it if (es != PointsToNode::UnknownEscape) return es; + // PointsTo() calls n->uncast() which can return a new ideal node. + if (n->uncast()->_idx >= nodes_size()) + return PointsToNode::UnknownEscape; + // compute max escape state of anything this node could point to VectorSet ptset(Thread::current()->resource_area()); PointsTo(ptset, n, phase); for(VectorSetI i(&ptset); i.test() && es != PointsToNode::GlobalEscape; ++i) { uint pt = i.elem; - PointsToNode::EscapeState pes = _nodes->adr_at(pt)->escape_state(); + PointsToNode::EscapeState pes = ptnode_adr(pt)->escape_state(); if (pes > es) es = pes; } // cache the computed escape state assert(es != PointsToNode::UnknownEscape, "should have computed an escape state"); - _nodes->adr_at(idx)->set_escape_state(es); + ptnode_adr(idx)->set_escape_state(es); return es; } @@ -220,49 +215,51 @@ void ConnectionGraph::PointsTo(VectorSet &ptset, Node * n, PhaseTransform *phase #endif n = n->uncast(); - PointsToNode npt = _nodes->at_grow(n->_idx); + PointsToNode* npt = ptnode_adr(n->_idx); // If we have a JavaObject, return just that object - if (npt.node_type() == PointsToNode::JavaObject) { + if (npt->node_type() == PointsToNode::JavaObject) { ptset.set(n->_idx); return; } #ifdef ASSERT - if (npt._node == NULL) { + if (npt->_node == NULL) { if (orig_n != n) orig_n->dump(); n->dump(); - assert(npt._node != NULL, "unregistered node"); + assert(npt->_node != NULL, "unregistered node"); } #endif worklist.push(n->_idx); while(worklist.length() > 0) { int ni = worklist.pop(); - PointsToNode pn = _nodes->at_grow(ni); - if (!visited.test_set(ni)) { - // ensure that all inputs of a Phi have been processed - assert(!_collecting || !pn._node->is_Phi() || _processed.test(ni),""); + if (visited.test_set(ni)) + continue; - int edges_processed = 0; - for (uint e = 0; e < pn.edge_count(); e++) { - uint etgt = pn.edge_target(e); - PointsToNode::EdgeType et = pn.edge_type(e); - if (et == PointsToNode::PointsToEdge) { - ptset.set(etgt); - edges_processed++; - } else if (et == PointsToNode::DeferredEdge) { - worklist.push(etgt); - edges_processed++; - } else { - assert(false,"neither PointsToEdge or DeferredEdge"); - } - } - if (edges_processed == 0) { - // no deferred or pointsto edges found. Assume the value was set - // outside this method. Add the phantom object to the pointsto set. - ptset.set(_phantom_object); + PointsToNode* pn = ptnode_adr(ni); + // ensure that all inputs of a Phi have been processed + assert(!_collecting || !pn->_node->is_Phi() || _processed.test(ni),""); + + int edges_processed = 0; + uint e_cnt = pn->edge_count(); + for (uint e = 0; e < e_cnt; e++) { + uint etgt = pn->edge_target(e); + PointsToNode::EdgeType et = pn->edge_type(e); + if (et == PointsToNode::PointsToEdge) { + ptset.set(etgt); + edges_processed++; + } else if (et == PointsToNode::DeferredEdge) { + worklist.push(etgt); + edges_processed++; + } else { + assert(false,"neither PointsToEdge or DeferredEdge"); } } + if (edges_processed == 0) { + // no deferred or pointsto edges found. Assume the value was set + // outside this method. Add the phantom object to the pointsto set. + ptset.set(_phantom_object); + } } } @@ -272,11 +269,11 @@ void ConnectionGraph::remove_deferred(uint ni, GrowableArray* deferred_edg deferred_edges->clear(); visited->Clear(); - uint i = 0; + visited->set(ni); PointsToNode *ptn = ptnode_adr(ni); // Mark current edges as visited and move deferred edges to separate array. - while (i < ptn->edge_count()) { + for (uint i = 0; i < ptn->edge_count(); ) { uint t = ptn->edge_target(i); #ifdef ASSERT assert(!visited->test_set(t), "expecting no duplications"); @@ -293,24 +290,23 @@ void ConnectionGraph::remove_deferred(uint ni, GrowableArray* deferred_edg for (int next = 0; next < deferred_edges->length(); ++next) { uint t = deferred_edges->at(next); PointsToNode *ptt = ptnode_adr(t); - for (uint j = 0; j < ptt->edge_count(); j++) { - uint n1 = ptt->edge_target(j); - if (visited->test_set(n1)) + uint e_cnt = ptt->edge_count(); + for (uint e = 0; e < e_cnt; e++) { + uint etgt = ptt->edge_target(e); + if (visited->test_set(etgt)) continue; - switch(ptt->edge_type(j)) { - case PointsToNode::PointsToEdge: - add_pointsto_edge(ni, n1); - if(n1 == _phantom_object) { - // Special case - field set outside (globally escaping). - ptn->set_escape_state(PointsToNode::GlobalEscape); - } - break; - case PointsToNode::DeferredEdge: - deferred_edges->append(n1); - break; - case PointsToNode::FieldEdge: - assert(false, "invalid connection graph"); - break; + + PointsToNode::EdgeType et = ptt->edge_type(e); + if (et == PointsToNode::PointsToEdge) { + add_pointsto_edge(ni, etgt); + if(etgt == _phantom_object) { + // Special case - field set outside (globally escaping). + ptn->set_escape_state(PointsToNode::GlobalEscape); + } + } else if (et == PointsToNode::DeferredEdge) { + deferred_edges->append(etgt); + } else { + assert(false,"invalid connection graph"); } } } @@ -322,15 +318,15 @@ void ConnectionGraph::remove_deferred(uint ni, GrowableArray* deferred_edg // a pointsto edge is added if it is a JavaObject void ConnectionGraph::add_edge_from_fields(uint adr_i, uint to_i, int offs) { - PointsToNode an = _nodes->at_grow(adr_i); - PointsToNode to = _nodes->at_grow(to_i); - bool deferred = (to.node_type() == PointsToNode::LocalVar); + PointsToNode* an = ptnode_adr(adr_i); + PointsToNode* to = ptnode_adr(to_i); + bool deferred = (to->node_type() == PointsToNode::LocalVar); - for (uint fe = 0; fe < an.edge_count(); fe++) { - assert(an.edge_type(fe) == PointsToNode::FieldEdge, "expecting a field edge"); - int fi = an.edge_target(fe); - PointsToNode pf = _nodes->at_grow(fi); - int po = pf.offset(); + for (uint fe = 0; fe < an->edge_count(); fe++) { + assert(an->edge_type(fe) == PointsToNode::FieldEdge, "expecting a field edge"); + int fi = an->edge_target(fe); + PointsToNode* pf = ptnode_adr(fi); + int po = pf->offset(); if (po == offs || po == Type::OffsetBot || offs == Type::OffsetBot) { if (deferred) add_deferred_edge(fi, to_i); @@ -343,13 +339,13 @@ void ConnectionGraph::add_edge_from_fields(uint adr_i, uint to_i, int offs) { // Add a deferred edge from node given by "from_i" to any field of adr_i // whose offset matches "offset". void ConnectionGraph::add_deferred_edge_to_fields(uint from_i, uint adr_i, int offs) { - PointsToNode an = _nodes->at_grow(adr_i); - for (uint fe = 0; fe < an.edge_count(); fe++) { - assert(an.edge_type(fe) == PointsToNode::FieldEdge, "expecting a field edge"); - int fi = an.edge_target(fe); - PointsToNode pf = _nodes->at_grow(fi); - int po = pf.offset(); - if (pf.edge_count() == 0) { + PointsToNode* an = ptnode_adr(adr_i); + for (uint fe = 0; fe < an->edge_count(); fe++) { + assert(an->edge_type(fe) == PointsToNode::FieldEdge, "expecting a field edge"); + int fi = an->edge_target(fe); + PointsToNode* pf = ptnode_adr(fi); + int po = pf->offset(); + if (pf->edge_count() == 0) { // we have not seen any stores to this field, assume it was set outside this method add_pointsto_edge(fi, _phantom_object); } @@ -835,6 +831,11 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) // Phase 1: Process possible allocations from alloc_worklist. // Create instance types for the CheckCastPP for allocations where possible. + // + // (Note: don't forget to change the order of the second AddP node on + // the alloc_worklist if the order of the worklist processing is changed, + // see the comment in find_second_addp().) + // while (alloc_worklist.length() != 0) { Node *n = alloc_worklist.pop(); uint ni = n->_idx; @@ -842,7 +843,7 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) if (n->is_Call()) { CallNode *alloc = n->as_Call(); // copy escape information to call node - PointsToNode* ptn = _nodes->adr_at(alloc->_idx); + PointsToNode* ptn = ptnode_adr(alloc->_idx); PointsToNode::EscapeState es = escape_state(alloc, igvn); // We have an allocation or call which returns a Java object, // see if it is unescaped. @@ -899,7 +900,7 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) // First, put on the worklist all Field edges from Connection Graph // which is more accurate then putting immediate users from Ideal Graph. for (uint e = 0; e < ptn->edge_count(); e++) { - Node *use = _nodes->adr_at(ptn->edge_target(e))->_node; + Node *use = ptnode_adr(ptn->edge_target(e))->_node; assert(ptn->edge_type(e) == PointsToNode::FieldEdge && use->is_AddP(), "only AddP nodes are Field edges in CG"); if (use->outcnt() > 0) { // Don't process dead nodes @@ -1062,7 +1063,7 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) } if (mem != n->in(MemNode::Memory)) { set_map(n->_idx, mem); - _nodes->adr_at(n->_idx)->_node = n; + ptnode_adr(n->_idx)->_node = n; } if (n->is_Load()) { continue; // don't push users @@ -1223,10 +1224,10 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) // Update the memory inputs of MemNodes with the value we computed // in Phase 2. - for (int i = 0; i < _nodes->length(); i++) { + for (uint i = 0; i < nodes_size(); i++) { Node *nmem = get_map(i); if (nmem != NULL) { - Node *n = _nodes->adr_at(i)->_node; + Node *n = ptnode_adr(i)->_node; if (n != NULL && n->is_Mem()) { igvn->hash_delete(n); n->set_req(MemNode::Memory, nmem); @@ -1237,28 +1238,48 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) } } -void ConnectionGraph::compute_escape() { +bool ConnectionGraph::has_candidates(Compile *C) { + // EA brings benefits only when the code has allocations and/or locks which + // are represented by ideal Macro nodes. + int cnt = C->macro_count(); + for( int i=0; i < cnt; i++ ) { + Node *n = C->macro_node(i); + if ( n->is_Allocate() ) + return true; + if( n->is_Lock() ) { + Node* obj = n->as_Lock()->obj_node()->uncast(); + if( !(obj->is_Parm() || obj->is_Con()) ) + return true; + } + } + return false; +} + +bool ConnectionGraph::compute_escape() { + Compile* C = _compile; // 1. Populate Connection Graph (CG) with Ideal nodes. Unique_Node_List worklist_init; - worklist_init.map(_compile->unique(), NULL); // preallocate space + worklist_init.map(C->unique(), NULL); // preallocate space // Initialize worklist - if (_compile->root() != NULL) { - worklist_init.push(_compile->root()); + if (C->root() != NULL) { + worklist_init.push(C->root()); } GrowableArray cg_worklist; - PhaseGVN* igvn = _compile->initial_gvn(); + PhaseGVN* igvn = C->initial_gvn(); bool has_allocations = false; // Push all useful nodes onto CG list and set their type. for( uint next = 0; next < worklist_init.size(); ++next ) { Node* n = worklist_init.at(next); record_for_escape_analysis(n, igvn); - if (n->is_Call() && - _nodes->adr_at(n->_idx)->node_type() == PointsToNode::JavaObject) { + // Only allocations and java static calls results are checked + // for an escape status. See process_call_result() below. + if (n->is_Allocate() || n->is_CallStaticJava() && + ptnode_adr(n->_idx)->node_type() == PointsToNode::JavaObject) { has_allocations = true; } if(n->is_AddP()) @@ -1269,24 +1290,23 @@ void ConnectionGraph::compute_escape() { } } - if (has_allocations) { - _has_allocations = true; - } else { - _has_allocations = false; + if (!has_allocations) { _collecting = false; - return; // Nothing to do. + return false; // Nothing to do. } // 2. First pass to create simple CG edges (doesn't require to walk CG). - for( uint next = 0; next < _delayed_worklist.size(); ++next ) { + uint delayed_size = _delayed_worklist.size(); + for( uint next = 0; next < delayed_size; ++next ) { Node* n = _delayed_worklist.at(next); build_connection_graph(n, igvn); } // 3. Pass to create fields edges (Allocate -F-> AddP). - for( int next = 0; next < cg_worklist.length(); ++next ) { + uint cg_length = cg_worklist.length(); + for( uint next = 0; next < cg_length; ++next ) { int ni = cg_worklist.at(next); - build_connection_graph(_nodes->adr_at(ni)->_node, igvn); + build_connection_graph(ptnode_adr(ni)->_node, igvn); } cg_worklist.clear(); @@ -1294,8 +1314,8 @@ void ConnectionGraph::compute_escape() { // 4. Build Connection Graph which need // to walk the connection graph. - for (uint ni = 0; ni < (uint)_nodes->length(); ni++) { - PointsToNode* ptn = _nodes->adr_at(ni); + for (uint ni = 0; ni < nodes_size(); ni++) { + PointsToNode* ptn = ptnode_adr(ni); Node *n = ptn->_node; if (n != NULL) { // Call, AddP, LoadP, StoreP build_connection_graph(n, igvn); @@ -1305,20 +1325,19 @@ void ConnectionGraph::compute_escape() { } VectorSet ptset(Thread::current()->resource_area()); - GrowableArray alloc_worklist; - GrowableArray worklist; GrowableArray deferred_edges; VectorSet visited(Thread::current()->resource_area()); - // remove deferred edges from the graph and collect - // information we will need for type splitting - for( int next = 0; next < cg_worklist.length(); ++next ) { + // 5. Remove deferred edges from the graph and collect + // information needed for type splitting. + cg_length = cg_worklist.length(); + for( uint next = 0; next < cg_length; ++next ) { int ni = cg_worklist.at(next); - PointsToNode* ptn = _nodes->adr_at(ni); + PointsToNode* ptn = ptnode_adr(ni); PointsToNode::NodeType nt = ptn->node_type(); - Node *n = ptn->_node; if (nt == PointsToNode::LocalVar || nt == PointsToNode::Field) { remove_deferred(ni, &deferred_edges, &visited); + Node *n = ptn->_node; if (n->is_AddP()) { // If this AddP computes an address which may point to more that one // object or more then one field (array's element), nothing the address @@ -1329,116 +1348,123 @@ void ConnectionGraph::compute_escape() { if (ptset.Size() > 1 || (ptset.Size() != 0 && ptn->offset() == Type::OffsetBot)) { for( VectorSetI j(&ptset); j.test(); ++j ) { - uint pt = j.elem; - ptnode_adr(pt)->_scalar_replaceable = false; + ptnode_adr(j.elem)->_scalar_replaceable = false; } } } - } else if (nt == PointsToNode::JavaObject && n->is_Call()) { - // Push call on alloc_worlist (alocations are calls) - // for processing by split_unique_types(). - alloc_worklist.append(n); } } + // 6. Propagate escape states. + GrowableArray worklist; + bool has_non_escaping_obj = false; + // push all GlobalEscape nodes on the worklist - for( int next = 0; next < cg_worklist.length(); ++next ) { + for( uint next = 0; next < cg_length; ++next ) { int nk = cg_worklist.at(next); - if (_nodes->adr_at(nk)->escape_state() == PointsToNode::GlobalEscape) - worklist.append(nk); + if (ptnode_adr(nk)->escape_state() == PointsToNode::GlobalEscape) + worklist.push(nk); } - // mark all node reachable from GlobalEscape nodes + // mark all nodes reachable from GlobalEscape nodes while(worklist.length() > 0) { - PointsToNode n = _nodes->at(worklist.pop()); - for (uint ei = 0; ei < n.edge_count(); ei++) { - uint npi = n.edge_target(ei); + PointsToNode* ptn = ptnode_adr(worklist.pop()); + uint e_cnt = ptn->edge_count(); + for (uint ei = 0; ei < e_cnt; ei++) { + uint npi = ptn->edge_target(ei); PointsToNode *np = ptnode_adr(npi); if (np->escape_state() < PointsToNode::GlobalEscape) { np->set_escape_state(PointsToNode::GlobalEscape); - worklist.append_if_missing(npi); + worklist.push(npi); } } } // push all ArgEscape nodes on the worklist - for( int next = 0; next < cg_worklist.length(); ++next ) { + for( uint next = 0; next < cg_length; ++next ) { int nk = cg_worklist.at(next); - if (_nodes->adr_at(nk)->escape_state() == PointsToNode::ArgEscape) + if (ptnode_adr(nk)->escape_state() == PointsToNode::ArgEscape) worklist.push(nk); } - // mark all node reachable from ArgEscape nodes + // mark all nodes reachable from ArgEscape nodes while(worklist.length() > 0) { - PointsToNode n = _nodes->at(worklist.pop()); - for (uint ei = 0; ei < n.edge_count(); ei++) { - uint npi = n.edge_target(ei); + PointsToNode* ptn = ptnode_adr(worklist.pop()); + if (ptn->node_type() == PointsToNode::JavaObject) + has_non_escaping_obj = true; // Non GlobalEscape + uint e_cnt = ptn->edge_count(); + for (uint ei = 0; ei < e_cnt; ei++) { + uint npi = ptn->edge_target(ei); PointsToNode *np = ptnode_adr(npi); if (np->escape_state() < PointsToNode::ArgEscape) { np->set_escape_state(PointsToNode::ArgEscape); - worklist.append_if_missing(npi); + worklist.push(npi); } } } + GrowableArray alloc_worklist; + // push all NoEscape nodes on the worklist - for( int next = 0; next < cg_worklist.length(); ++next ) { + for( uint next = 0; next < cg_length; ++next ) { int nk = cg_worklist.at(next); - if (_nodes->adr_at(nk)->escape_state() == PointsToNode::NoEscape) + if (ptnode_adr(nk)->escape_state() == PointsToNode::NoEscape) worklist.push(nk); } - // mark all node reachable from NoEscape nodes + // mark all nodes reachable from NoEscape nodes while(worklist.length() > 0) { - PointsToNode n = _nodes->at(worklist.pop()); - for (uint ei = 0; ei < n.edge_count(); ei++) { - uint npi = n.edge_target(ei); + PointsToNode* ptn = ptnode_adr(worklist.pop()); + if (ptn->node_type() == PointsToNode::JavaObject) + has_non_escaping_obj = true; // Non GlobalEscape + Node* n = ptn->_node; + if (n->is_Allocate() && ptn->_scalar_replaceable ) { + // Push scalar replaceable alocations on alloc_worklist + // for processing in split_unique_types(). + alloc_worklist.append(n); + } + uint e_cnt = ptn->edge_count(); + for (uint ei = 0; ei < e_cnt; ei++) { + uint npi = ptn->edge_target(ei); PointsToNode *np = ptnode_adr(npi); if (np->escape_state() < PointsToNode::NoEscape) { np->set_escape_state(PointsToNode::NoEscape); - worklist.append_if_missing(npi); + worklist.push(npi); } } } _collecting = false; + assert(C->unique() == nodes_size(), "there should be no new ideal nodes during ConnectionGraph build"); - has_allocations = false; // Are there scalar replaceable allocations? + bool has_scalar_replaceable_candidates = alloc_worklist.length() > 0; + if ( has_scalar_replaceable_candidates && + C->AliasLevel() >= 3 && EliminateAllocations ) { - for( int next = 0; next < alloc_worklist.length(); ++next ) { - Node* n = alloc_worklist.at(next); - uint ni = n->_idx; - PointsToNode* ptn = _nodes->adr_at(ni); - PointsToNode::EscapeState es = ptn->escape_state(); - if (ptn->escape_state() == PointsToNode::NoEscape && - ptn->_scalar_replaceable) { - has_allocations = true; - break; - } - } - if (!has_allocations) { - return; // Nothing to do. - } - - if(_compile->AliasLevel() >= 3 && EliminateAllocations) { // Now use the escape information to create unique types for - // unescaped objects + // scalar replaceable objects. split_unique_types(alloc_worklist); - if (_compile->failing()) return; + + if (C->failing()) return false; // Clean up after split unique types. ResourceMark rm; - PhaseRemoveUseless pru(_compile->initial_gvn(), _compile->for_igvn()); + PhaseRemoveUseless pru(C->initial_gvn(), C->for_igvn()); + + C->print_method("After Escape Analysis", 2); #ifdef ASSERT - } else if (PrintEscapeAnalysis || PrintEliminateAllocations) { + } else if (Verbose && (PrintEscapeAnalysis || PrintEliminateAllocations)) { tty->print("=== No allocations eliminated for "); - C()->method()->print_short_name(); + C->method()->print_short_name(); if(!EliminateAllocations) { tty->print(" since EliminateAllocations is off ==="); - } else if(_compile->AliasLevel() < 3) { + } else if(!has_scalar_replaceable_candidates) { + tty->print(" since there are no scalar replaceable candidates ==="); + } else if(C->AliasLevel() < 3) { tty->print(" since AliasLevel < 3 ==="); } tty->cr(); #endif } + return has_non_escaping_obj; } void ConnectionGraph::process_call_arguments(CallNode *call, PhaseTransform *phase) { @@ -1538,7 +1564,7 @@ void ConnectionGraph::process_call_arguments(CallNode *call, PhaseTransform *pha } } if (copy_dependencies) - call_analyzer->copy_dependencies(C()->dependencies()); + call_analyzer->copy_dependencies(_compile->dependencies()); break; } } @@ -1561,7 +1587,6 @@ void ConnectionGraph::process_call_arguments(CallNode *call, PhaseTransform *pha for( VectorSetI j(&ptset); j.test(); ++j ) { uint pt = j.elem; set_escape_state(pt, PointsToNode::GlobalEscape); - PointsToNode *ptadr = ptnode_adr(pt); } } } @@ -1569,9 +1594,10 @@ void ConnectionGraph::process_call_arguments(CallNode *call, PhaseTransform *pha } } void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *phase) { - PointsToNode *ptadr = ptnode_adr(resproj->_idx); + CallNode *call = resproj->in(0)->as_Call(); + uint call_idx = call->_idx; + uint resproj_idx = resproj->_idx; - CallNode *call = resproj->in(0)->as_Call(); switch (call->Opcode()) { case Op_Allocate: { @@ -1587,7 +1613,6 @@ void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *pha ciKlass* cik = kt->klass(); ciInstanceKlass* ciik = cik->as_instance_klass(); - PointsToNode *ptadr = ptnode_adr(call->_idx); PointsToNode::EscapeState es; uint edge_to; if (cik->is_subclass_of(_compile->env()->Thread_klass()) || ciik->has_finalizer()) { @@ -1595,25 +1620,24 @@ void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *pha edge_to = _phantom_object; // Could not be worse } else { es = PointsToNode::NoEscape; - edge_to = call->_idx; + edge_to = call_idx; } - set_escape_state(call->_idx, es); - add_pointsto_edge(resproj->_idx, edge_to); - _processed.set(resproj->_idx); + set_escape_state(call_idx, es); + add_pointsto_edge(resproj_idx, edge_to); + _processed.set(resproj_idx); break; } case Op_AllocateArray: { - PointsToNode *ptadr = ptnode_adr(call->_idx); int length = call->in(AllocateNode::ALength)->find_int_con(-1); if (length < 0 || length > EliminateAllocationArraySizeLimit) { // Not scalar replaceable if the length is not constant or too big. - ptadr->_scalar_replaceable = false; + ptnode_adr(call_idx)->_scalar_replaceable = false; } - set_escape_state(call->_idx, PointsToNode::NoEscape); - add_pointsto_edge(resproj->_idx, call->_idx); - _processed.set(resproj->_idx); + set_escape_state(call_idx, PointsToNode::NoEscape); + add_pointsto_edge(resproj_idx, call_idx); + _processed.set(resproj_idx); break; } @@ -1631,19 +1655,17 @@ void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *pha // Note: we use isa_ptr() instead of isa_oopptr() here because the // _multianewarray functions return a TypeRawPtr. if (ret_type == NULL || ret_type->isa_ptr() == NULL) { - _processed.set(resproj->_idx); + _processed.set(resproj_idx); break; // doesn't return a pointer type } ciMethod *meth = call->as_CallJava()->method(); const TypeTuple * d = call->tf()->domain(); if (meth == NULL) { // not a Java method, assume global escape - set_escape_state(call->_idx, PointsToNode::GlobalEscape); - if (resproj != NULL) - add_pointsto_edge(resproj->_idx, _phantom_object); + set_escape_state(call_idx, PointsToNode::GlobalEscape); + add_pointsto_edge(resproj_idx, _phantom_object); } else { BCEscapeAnalyzer *call_analyzer = meth->get_bcea(); - VectorSet ptset(Thread::current()->resource_area()); bool copy_dependencies = false; if (call_analyzer->is_return_allocated()) { @@ -1651,13 +1673,12 @@ void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *pha // update dependency information. // Mark it as NoEscape so that objects referenced by // it's fields will be marked as NoEscape at least. - set_escape_state(call->_idx, PointsToNode::NoEscape); - if (resproj != NULL) - add_pointsto_edge(resproj->_idx, call->_idx); + set_escape_state(call_idx, PointsToNode::NoEscape); + add_pointsto_edge(resproj_idx, call_idx); copy_dependencies = true; - } else if (call_analyzer->is_return_local() && resproj != NULL) { + } else if (call_analyzer->is_return_local()) { // determine whether any arguments are returned - set_escape_state(call->_idx, PointsToNode::NoEscape); + set_escape_state(call_idx, PointsToNode::NoEscape); for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { const Type* at = d->field_at(i); @@ -1665,36 +1686,35 @@ void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *pha Node *arg = call->in(i)->uncast(); if (call_analyzer->is_arg_returned(i - TypeFunc::Parms)) { - PointsToNode *arg_esp = _nodes->adr_at(arg->_idx); + PointsToNode *arg_esp = ptnode_adr(arg->_idx); if (arg_esp->node_type() == PointsToNode::UnknownType) done = false; else if (arg_esp->node_type() == PointsToNode::JavaObject) - add_pointsto_edge(resproj->_idx, arg->_idx); + add_pointsto_edge(resproj_idx, arg->_idx); else - add_deferred_edge(resproj->_idx, arg->_idx); + add_deferred_edge(resproj_idx, arg->_idx); arg_esp->_hidden_alias = true; } } } copy_dependencies = true; } else { - set_escape_state(call->_idx, PointsToNode::GlobalEscape); - if (resproj != NULL) - add_pointsto_edge(resproj->_idx, _phantom_object); + set_escape_state(call_idx, PointsToNode::GlobalEscape); + add_pointsto_edge(resproj_idx, _phantom_object); for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { const Type* at = d->field_at(i); if (at->isa_oopptr() != NULL) { Node *arg = call->in(i)->uncast(); - PointsToNode *arg_esp = _nodes->adr_at(arg->_idx); + PointsToNode *arg_esp = ptnode_adr(arg->_idx); arg_esp->_hidden_alias = true; } } } if (copy_dependencies) - call_analyzer->copy_dependencies(C()->dependencies()); + call_analyzer->copy_dependencies(_compile->dependencies()); } if (done) - _processed.set(resproj->_idx); + _processed.set(resproj_idx); break; } @@ -1709,13 +1729,11 @@ void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *pha // Note: we use isa_ptr() instead of isa_oopptr() here because the // _multianewarray functions return a TypeRawPtr. if (ret_type->isa_ptr() != NULL) { - PointsToNode *ptadr = ptnode_adr(call->_idx); - set_escape_state(call->_idx, PointsToNode::GlobalEscape); - if (resproj != NULL) - add_pointsto_edge(resproj->_idx, _phantom_object); + set_escape_state(call_idx, PointsToNode::GlobalEscape); + add_pointsto_edge(resproj_idx, _phantom_object); } } - _processed.set(resproj->_idx); + _processed.set(resproj_idx); } } } @@ -1743,7 +1761,7 @@ void ConnectionGraph::record_for_escape_analysis(Node *n, PhaseTransform *phase) // Check if a call returns an object. const TypeTuple *r = n->as_Call()->tf()->range(); - if (r->cnt() > TypeFunc::Parms && + if (n->is_CallStaticJava() && r->cnt() > TypeFunc::Parms && n->as_Call()->proj_out(TypeFunc::Parms) != NULL) { // Note: use isa_ptr() instead of isa_oopptr() here because // the _multianewarray functions return a TypeRawPtr. @@ -1776,7 +1794,7 @@ void ConnectionGraph::record_for_escape_analysis(Node *n, PhaseTransform *phase) { add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false); int ti = n->in(1)->_idx; - PointsToNode::NodeType nt = _nodes->adr_at(ti)->node_type(); + PointsToNode::NodeType nt = ptnode_adr(ti)->node_type(); if (nt == PointsToNode::UnknownType) { _delayed_worklist.push(n); // Process it later. break; @@ -1866,7 +1884,7 @@ void ConnectionGraph::record_for_escape_analysis(Node *n, PhaseTransform *phase) if (in->is_top() || in == n) continue; // ignore top or inputs which go back this node int ti = in->_idx; - PointsToNode::NodeType nt = _nodes->adr_at(ti)->node_type(); + PointsToNode::NodeType nt = ptnode_adr(ti)->node_type(); if (nt == PointsToNode::UnknownType) { break; } else if (nt == PointsToNode::JavaObject) { @@ -1904,7 +1922,7 @@ void ConnectionGraph::record_for_escape_analysis(Node *n, PhaseTransform *phase) // Treat Return value as LocalVar with GlobalEscape escape state. add_node(n, PointsToNode::LocalVar, PointsToNode::GlobalEscape, false); int ti = n->in(TypeFunc::Parms)->_idx; - PointsToNode::NodeType nt = _nodes->adr_at(ti)->node_type(); + PointsToNode::NodeType nt = ptnode_adr(ti)->node_type(); if (nt == PointsToNode::UnknownType) { _delayed_worklist.push(n); // Process it later. break; @@ -1968,17 +1986,17 @@ void ConnectionGraph::record_for_escape_analysis(Node *n, PhaseTransform *phase) } void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) { + uint n_idx = n->_idx; + // Don't set processed bit for AddP, LoadP, StoreP since // they may need more then one pass to process. - if (_processed.test(n->_idx)) + if (_processed.test(n_idx)) return; // No need to redefine node's state. - PointsToNode *ptadr = ptnode_adr(n->_idx); - if (n->is_Call()) { CallNode *call = n->as_Call(); process_call_arguments(call, phase); - _processed.set(n->_idx); + _processed.set(n_idx); return; } @@ -1991,7 +2009,7 @@ void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) { PointsTo(ptset, base, phase); for( VectorSetI i(&ptset); i.test(); ++i ) { uint pt = i.elem; - add_field_edge(pt, n->_idx, address_offset(n, phase)); + add_field_edge(pt, n_idx, address_offset(n, phase)); } break; } @@ -2006,12 +2024,12 @@ void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) { case Op_DecodeN: { int ti = n->in(1)->_idx; - if (_nodes->adr_at(ti)->node_type() == PointsToNode::JavaObject) { - add_pointsto_edge(n->_idx, ti); + if (ptnode_adr(ti)->node_type() == PointsToNode::JavaObject) { + add_pointsto_edge(n_idx, ti); } else { - add_deferred_edge(n->_idx, ti); + add_deferred_edge(n_idx, ti); } - _processed.set(n->_idx); + _processed.set(n_idx); break; } case Op_ConP: @@ -2060,7 +2078,7 @@ void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) { int offset = address_offset(adr, phase); for( VectorSetI i(&ptset); i.test(); ++i ) { uint pt = i.elem; - add_deferred_edge_to_fields(n->_idx, pt, offset); + add_deferred_edge_to_fields(n_idx, pt, offset); } break; } @@ -2083,13 +2101,13 @@ void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) { if (in->is_top() || in == n) continue; // ignore top or inputs which go back this node int ti = in->_idx; - if (_nodes->adr_at(in->_idx)->node_type() == PointsToNode::JavaObject) { - add_pointsto_edge(n->_idx, ti); + if (ptnode_adr(in->_idx)->node_type() == PointsToNode::JavaObject) { + add_pointsto_edge(n_idx, ti); } else { - add_deferred_edge(n->_idx, ti); + add_deferred_edge(n_idx, ti); } } - _processed.set(n->_idx); + _processed.set(n_idx); break; } case Op_Proj: @@ -2097,7 +2115,7 @@ void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) { // we are only interested in the result projection from a call if (n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->is_Call() ) { process_call_result(n->as_Proj(), phase); - assert(_processed.test(n->_idx), "all call results should be processed"); + assert(_processed.test(n_idx), "all call results should be processed"); } else { assert(false, "Op_Proj"); } @@ -2112,12 +2130,12 @@ void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) { } #endif int ti = n->in(TypeFunc::Parms)->_idx; - if (_nodes->adr_at(ti)->node_type() == PointsToNode::JavaObject) { - add_pointsto_edge(n->_idx, ti); + if (ptnode_adr(ti)->node_type() == PointsToNode::JavaObject) { + add_pointsto_edge(n_idx, ti); } else { - add_deferred_edge(n->_idx, ti); + add_deferred_edge(n_idx, ti); } - _processed.set(n->_idx); + _processed.set(n_idx); break; } case Op_StoreP: @@ -2162,9 +2180,9 @@ void ConnectionGraph::dump() { PhaseGVN *igvn = _compile->initial_gvn(); bool first = true; - uint size = (uint)_nodes->length(); + uint size = nodes_size(); for (uint ni = 0; ni < size; ni++) { - PointsToNode *ptn = _nodes->adr_at(ni); + PointsToNode *ptn = ptnode_adr(ni); PointsToNode::NodeType ptn_type = ptn->node_type(); if (ptn_type != PointsToNode::JavaObject || ptn->_node == NULL) @@ -2174,7 +2192,7 @@ void ConnectionGraph::dump() { if (first) { tty->cr(); tty->print("======== Connection graph for "); - C()->method()->print_short_name(); + _compile->method()->print_short_name(); tty->cr(); first = false; } @@ -2182,12 +2200,12 @@ void ConnectionGraph::dump() { ptn->dump(); // Print all locals which reference this allocation for (uint li = ni; li < size; li++) { - PointsToNode *ptn_loc = _nodes->adr_at(li); + PointsToNode *ptn_loc = ptnode_adr(li); PointsToNode::NodeType ptn_loc_type = ptn_loc->node_type(); if ( ptn_loc_type == PointsToNode::LocalVar && ptn_loc->_node != NULL && ptn_loc->edge_count() == 1 && ptn_loc->edge_target(0) == ni ) { tty->print("%6d LocalVar [[%d]]", li, ni); - _nodes->adr_at(li)->_node->dump(); + ptnode_adr(li)->_node->dump(); } } if (Verbose) { @@ -2195,7 +2213,7 @@ void ConnectionGraph::dump() { for (uint i = 0; i < ptn->edge_count(); i++) { uint ei = ptn->edge_target(i); tty->print("%6d Field [[%d]]", ei, ni); - _nodes->adr_at(ei)->_node->dump(); + ptnode_adr(ei)->_node->dump(); } } tty->cr(); diff --git a/hotspot/src/share/vm/opto/escape.hpp b/hotspot/src/share/vm/opto/escape.hpp index 1d2c83511e7..5d9259569ef 100644 --- a/hotspot/src/share/vm/opto/escape.hpp +++ b/hotspot/src/share/vm/opto/escape.hpp @@ -178,14 +178,24 @@ public: // count of outgoing edges uint edge_count() const { return (_edges == NULL) ? 0 : _edges->length(); } + // node index of target of outgoing edge "e" - uint edge_target(uint e) const; + uint edge_target(uint e) const { + assert(_edges != NULL, "valid edge index"); + return (_edges->at(e) >> EdgeShift); + } // type of outgoing edge "e" - EdgeType edge_type(uint e) const; + EdgeType edge_type(uint e) const { + assert(_edges != NULL, "valid edge index"); + return (EdgeType) (_edges->at(e) & EdgeMask); + } + // add a edge of the specified type pointing to the specified target void add_edge(uint targIdx, EdgeType et); + // remove an edge of the specified type pointing to the specified target void remove_edge(uint targIdx, EdgeType et); + #ifndef PRODUCT void dump() const; #endif @@ -194,7 +204,7 @@ public: class ConnectionGraph: public ResourceObj { private: - GrowableArray* _nodes; // Connection graph nodes indexed + GrowableArray _nodes; // Connection graph nodes indexed // by ideal node index. Unique_Node_List _delayed_worklist; // Nodes to be processed before @@ -207,9 +217,6 @@ private: // is still being collected. If false, // no new nodes will be processed. - bool _has_allocations; // Indicates whether method has any - // non-escaping allocations. - uint _phantom_object; // Index of globally escaping object // that pointer values loaded from // a field which has not been set @@ -217,14 +224,13 @@ private: Compile * _compile; // Compile object for current compilation - // address of an element in _nodes. Used when the element is to be modified - PointsToNode *ptnode_adr(uint idx) { - if ((uint)_nodes->length() <= idx) { - // expand _nodes array - PointsToNode dummy = _nodes->at_grow(idx); - } - return _nodes->adr_at(idx); + // Address of an element in _nodes. Used when the element is to be modified + PointsToNode *ptnode_adr(uint idx) const { + // There should be no new ideal nodes during ConnectionGraph build, + // growableArray::adr_at() will throw assert otherwise. + return _nodes.adr_at(idx); } + uint nodes_size() const { return _nodes.length(); } // Add node to ConnectionGraph. void add_node(Node *n, PointsToNode::NodeType nt, PointsToNode::EscapeState es, bool done); @@ -307,30 +313,30 @@ private: // Set the escape state of a node void set_escape_state(uint ni, PointsToNode::EscapeState es); - // Get Compile object for current compilation. - Compile *C() const { return _compile; } - public: ConnectionGraph(Compile *C); + // Check for non-escaping candidates + static bool has_candidates(Compile *C); + // Compute the escape information - void compute_escape(); + bool compute_escape(); // escape state of a node PointsToNode::EscapeState escape_state(Node *n, PhaseTransform *phase); // other information we have collected bool is_scalar_replaceable(Node *n) { - if (_collecting) + if (_collecting || (n->_idx >= nodes_size())) return false; - PointsToNode ptn = _nodes->at_grow(n->_idx); - return ptn.escape_state() == PointsToNode::NoEscape && ptn._scalar_replaceable; + PointsToNode* ptn = ptnode_adr(n->_idx); + return ptn->escape_state() == PointsToNode::NoEscape && ptn->_scalar_replaceable; } bool hidden_alias(Node *n) { - if (_collecting) + if (_collecting || (n->_idx >= nodes_size())) return true; - PointsToNode ptn = _nodes->at_grow(n->_idx); - return (ptn.escape_state() != PointsToNode::NoEscape) || ptn._hidden_alias; + PointsToNode* ptn = ptnode_adr(n->_idx); + return (ptn->escape_state() != PointsToNode::NoEscape) || ptn->_hidden_alias; } #ifndef PRODUCT From 18dbebd14308d8aa9a2c30ffe2f790f7cff46bd7 Mon Sep 17 00:00:00 2001 From: Jon Masamitsu Date: Wed, 9 Jul 2008 15:08:55 -0700 Subject: [PATCH 02/52] 6672698: mangle_unused_area() should not remangle the entire heap at each collection Maintain a high water mark for the allocations in a space and mangle only up to that high water mark. Reviewed-by: ysr, apetrusenko --- .../binaryTreeDictionary.cpp | 11 +- .../compactibleFreeListSpace.cpp | 2 +- .../freeBlockDictionary.hpp | 1 - .../concurrentMarkSweep/freeChunk.hpp | 2 + .../includeDB_gc_concurrentMarkSweep | 2 + .../vm/gc_implementation/includeDB_gc_parNew | 16 +- .../includeDB_gc_parallelScavenge | 21 +- .../vm/gc_implementation/includeDB_gc_shared | 2 + .../parNew/asParNewGeneration.cpp | 35 ++- .../parNew/parNewGeneration.cpp | 16 +- .../parallelScavenge/asPSYoungGen.cpp | 112 +++++++-- .../parallelScavenge/cardTableExtension.cpp | 6 +- .../parallelScavenge/parallelScavengeHeap.cpp | 20 ++ .../parallelScavenge/parallelScavengeHeap.hpp | 6 + .../parallelScavenge/psMarkSweep.cpp | 16 +- .../parallelScavenge/psMarkSweepDecorator.cpp | 4 +- .../parallelScavenge/psOldGen.cpp | 42 +++- .../parallelScavenge/psOldGen.hpp | 4 + .../parallelScavenge/psParallelCompact.cpp | 36 ++- .../parallelScavenge/psParallelCompact.hpp | 93 ++++++++ .../parallelScavenge/psScavenge.cpp | 19 +- .../parallelScavenge/psYoungGen.cpp | 214 +++++++++++++++--- .../parallelScavenge/psYoungGen.hpp | 8 + .../shared/mutableNUMASpace.cpp | 63 ++++-- .../shared/mutableNUMASpace.hpp | 13 +- .../gc_implementation/shared/mutableSpace.cpp | 55 ++++- .../gc_implementation/shared/mutableSpace.hpp | 42 +++- .../shared/spaceDecorator.cpp | 140 ++++++++++++ .../shared/spaceDecorator.hpp | 141 ++++++++++++ hotspot/src/share/vm/includeDB_core | 10 + hotspot/src/share/vm/includeDB_features | 1 + .../src/share/vm/memory/defNewGeneration.cpp | 118 ++++++++-- .../src/share/vm/memory/defNewGeneration.hpp | 15 +- hotspot/src/share/vm/memory/dump.cpp | 2 +- .../src/share/vm/memory/genCollectedHeap.cpp | 29 +++ .../src/share/vm/memory/genCollectedHeap.hpp | 6 + hotspot/src/share/vm/memory/genMarkSweep.cpp | 4 + hotspot/src/share/vm/memory/generation.cpp | 21 +- hotspot/src/share/vm/memory/generation.hpp | 9 + hotspot/src/share/vm/memory/space.cpp | 81 +++++-- hotspot/src/share/vm/memory/space.hpp | 53 ++++- hotspot/src/share/vm/runtime/globals.hpp | 8 +- .../share/vm/utilities/globalDefinitions.hpp | 6 +- 43 files changed, 1299 insertions(+), 206 deletions(-) create mode 100644 hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.cpp create mode 100644 hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.hpp diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp index 91d381d5501..5064f1104b3 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp @@ -71,8 +71,15 @@ TreeList* TreeList::as_TreeList(TreeChunk* tc) { TreeList* TreeList::as_TreeList(HeapWord* addr, size_t size) { TreeChunk* tc = (TreeChunk*) addr; assert(size >= sizeof(TreeChunk), "Chunk is too small for a TreeChunk"); - assert(tc->size() == 0 && tc->prev() == NULL && tc->next() == NULL, - "Space should be clear"); + // The space in the heap will have been mangled initially but + // is not remangled when a free chunk is returned to the free list + // (since it is used to maintain the chunk on the free list). + assert((ZapUnusedHeapArea && + SpaceMangler::is_mangled((HeapWord*) tc->size_addr()) && + SpaceMangler::is_mangled((HeapWord*) tc->prev_addr()) && + SpaceMangler::is_mangled((HeapWord*) tc->next_addr())) || + (tc->size() == 0 && tc->prev() == NULL && tc->next() == NULL), + "Space should be clear or mangled"); tc->setSize(size); tc->linkPrev(NULL); tc->linkNext(NULL); diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp index 245807e7319..a0c86f686f0 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp @@ -54,7 +54,7 @@ CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs, _collector(NULL) { _bt.set_space(this); - initialize(mr, true); + initialize(mr, SpaceDecorator::Clear, SpaceDecorator::Mangle); // We have all of "mr", all of which we place in the dictionary // as one big chunk. We'll need to decide here which of several // possible alternative dictionary implementations to use. For diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp index b238c023674..fd0448c1a15 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp @@ -22,7 +22,6 @@ * */ - // A FreeBlockDictionary is an abstract superclass that will allow // a number of alternative implementations in the future. class FreeBlockDictionary: public CHeapObj { diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp index be2479475a8..e356dc05092 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp @@ -85,6 +85,8 @@ class FreeChunk VALUE_OBJ_CLASS_SPEC { } debug_only(void* prev_addr() const { return (void*)&_prev; }) + debug_only(void* next_addr() const { return (void*)&_next; }) + debug_only(void* size_addr() const { return (void*)&_size; }) size_t size() const volatile { LP64_ONLY(if (UseCompressedOops) return mark()->get_size(); else ) diff --git a/hotspot/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep b/hotspot/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep index d3e253edc7b..621c3f9b94e 100644 --- a/hotspot/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep +++ b/hotspot/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep @@ -28,6 +28,7 @@ binaryTreeDictionary.cpp allocationStats.hpp binaryTreeDictionary.cpp binaryTreeDictionary.hpp binaryTreeDictionary.cpp globals.hpp binaryTreeDictionary.cpp ostream.hpp +binaryTreeDictionary.cpp spaceDecorator.hpp binaryTreeDictionary.hpp freeBlockDictionary.hpp binaryTreeDictionary.hpp freeList.hpp @@ -114,6 +115,7 @@ compactibleFreeListSpace.cpp java.hpp compactibleFreeListSpace.cpp liveRange.hpp compactibleFreeListSpace.cpp oop.inline.hpp compactibleFreeListSpace.cpp resourceArea.hpp +compactibleFreeListSpace.cpp spaceDecorator.hpp compactibleFreeListSpace.cpp universe.inline.hpp compactibleFreeListSpace.cpp vmThread.hpp diff --git a/hotspot/src/share/vm/gc_implementation/includeDB_gc_parNew b/hotspot/src/share/vm/gc_implementation/includeDB_gc_parNew index 7c926792262..e5e5bc17b7c 100644 --- a/hotspot/src/share/vm/gc_implementation/includeDB_gc_parNew +++ b/hotspot/src/share/vm/gc_implementation/includeDB_gc_parNew @@ -22,16 +22,17 @@ // // -asParNewGeneration.hpp adaptiveSizePolicy.hpp -asParNewGeneration.hpp parNewGeneration.hpp +asParNewGeneration.hpp adaptiveSizePolicy.hpp +asParNewGeneration.hpp parNewGeneration.hpp -asParNewGeneration.cpp asParNewGeneration.hpp -asParNewGeneration.cpp cmsAdaptiveSizePolicy.hpp +asParNewGeneration.cpp asParNewGeneration.hpp +asParNewGeneration.cpp cmsAdaptiveSizePolicy.hpp asParNewGeneration.cpp cmsGCAdaptivePolicyCounters.hpp -asParNewGeneration.cpp defNewGeneration.inline.hpp -asParNewGeneration.cpp oop.pcgc.inline.hpp -asParNewGeneration.cpp parNewGeneration.hpp +asParNewGeneration.cpp defNewGeneration.inline.hpp +asParNewGeneration.cpp oop.pcgc.inline.hpp +asParNewGeneration.cpp parNewGeneration.hpp asParNewGeneration.cpp referencePolicy.hpp +asParNewGeneration.cpp spaceDecorator.hpp parCardTableModRefBS.cpp allocation.inline.hpp parCardTableModRefBS.cpp cardTableModRefBS.hpp @@ -75,6 +76,7 @@ parNewGeneration.cpp referencePolicy.hpp parNewGeneration.cpp resourceArea.hpp parNewGeneration.cpp sharedHeap.hpp parNewGeneration.cpp space.hpp +parNewGeneration.cpp spaceDecorator.hpp parNewGeneration.cpp workgroup.hpp parNewGeneration.hpp defNewGeneration.hpp diff --git a/hotspot/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge b/hotspot/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge index 8a2a7a6127b..3406c59d91f 100644 --- a/hotspot/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge +++ b/hotspot/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge @@ -53,14 +53,15 @@ asPSOldGen.cpp java.hpp asPSOldGen.cpp oop.inline.hpp asPSOldGen.cpp parallelScavengeHeap.hpp asPSOldGen.cpp psMarkSweepDecorator.hpp -asPSOldGen.cpp asPSOldGen.hpp +asPSOldGen.cpp asPSOldGen.hpp asPSYoungGen.hpp generationCounters.hpp asPSYoungGen.hpp mutableSpace.hpp asPSYoungGen.hpp objectStartArray.hpp asPSYoungGen.hpp spaceCounters.hpp asPSYoungGen.hpp psVirtualspace.hpp -asPSYoungGen.hpp psYoungGen.hpp +asPSYoungGen.hpp psYoungGen.hpp +asPSYoungGen.hpp spaceDecorator.hpp asPSYoungGen.cpp gcUtil.hpp asPSYoungGen.cpp java.hpp @@ -68,8 +69,9 @@ asPSYoungGen.cpp oop.inline.hpp asPSYoungGen.cpp parallelScavengeHeap.hpp asPSYoungGen.cpp psMarkSweepDecorator.hpp asPSYoungGen.cpp psScavenge.hpp -asPSYoungGen.cpp asPSYoungGen.hpp -asPSYoungGen.cpp psYoungGen.hpp +asPSYoungGen.cpp asPSYoungGen.hpp +asPSYoungGen.cpp psYoungGen.hpp +asPSYoungGen.cpp spaceDecorator.hpp cardTableExtension.cpp cardTableExtension.hpp cardTableExtension.cpp gcTaskManager.hpp @@ -225,6 +227,7 @@ psMarkSweep.cpp psYoungGen.hpp psMarkSweep.cpp referencePolicy.hpp psMarkSweep.cpp referenceProcessor.hpp psMarkSweep.cpp safepoint.hpp +psMarkSweep.cpp spaceDecorator.hpp psMarkSweep.cpp symbolTable.hpp psMarkSweep.cpp systemDictionary.hpp psMarkSweep.cpp vmThread.hpp @@ -239,6 +242,7 @@ psMarkSweepDecorator.cpp oop.inline.hpp psMarkSweepDecorator.cpp parallelScavengeHeap.hpp psMarkSweepDecorator.cpp psMarkSweep.hpp psMarkSweepDecorator.cpp psMarkSweepDecorator.hpp +psMarkSweepDecorator.cpp spaceDecorator.hpp psMarkSweepDecorator.cpp systemDictionary.hpp psMarkSweepDecorator.hpp mutableSpace.hpp @@ -290,6 +294,7 @@ psOldGen.cpp oop.inline.hpp psOldGen.cpp parallelScavengeHeap.hpp psOldGen.cpp psMarkSweepDecorator.hpp psOldGen.cpp psOldGen.hpp +psOldGen.cpp spaceDecorator.hpp psOldGen.hpp psGenerationCounters.hpp psOldGen.hpp mutableSpace.hpp @@ -351,6 +356,7 @@ psScavenge.cpp psTasks.hpp psScavenge.cpp referencePolicy.hpp psScavenge.cpp referenceProcessor.hpp psScavenge.cpp resourceArea.hpp +psScavenge.cpp spaceDecorator.hpp psScavenge.cpp threadCritical.hpp psScavenge.cpp vmThread.hpp psScavenge.cpp vm_operations.hpp @@ -409,8 +415,8 @@ psVirtualspace.hpp virtualspace.hpp psVirtualspace.cpp os.hpp psVirtualspace.cpp os_.inline.hpp -psVirtualspace.cpp psVirtualspace.hpp -psVirtualspace.cpp virtualspace.hpp +psVirtualspace.cpp psVirtualspace.hpp +psVirtualspace.cpp virtualspace.hpp psYoungGen.cpp gcUtil.hpp psYoungGen.cpp java.hpp @@ -419,7 +425,8 @@ psYoungGen.cpp parallelScavengeHeap.hpp psYoungGen.cpp psMarkSweepDecorator.hpp psYoungGen.cpp psScavenge.hpp psYoungGen.cpp psYoungGen.hpp -psYoungGen.cpp mutableNUMASpace.hpp +psYoungGen.cpp mutableNUMASpace.hpp +psYoungGen.cpp spaceDecorator.hpp psYoungGen.hpp psGenerationCounters.hpp psYoungGen.hpp mutableSpace.hpp diff --git a/hotspot/src/share/vm/gc_implementation/includeDB_gc_shared b/hotspot/src/share/vm/gc_implementation/includeDB_gc_shared index 367fccf4807..7729f5eb830 100644 --- a/hotspot/src/share/vm/gc_implementation/includeDB_gc_shared +++ b/hotspot/src/share/vm/gc_implementation/includeDB_gc_shared @@ -56,6 +56,7 @@ markSweep.inline.hpp psParallelCompact.hpp mutableNUMASpace.cpp mutableNUMASpace.hpp mutableNUMASpace.cpp oop.inline.hpp mutableNUMASpace.cpp sharedHeap.hpp +mutableNUMASpace.cpp spaceDecorator.hpp mutableNUMASpace.cpp thread_.inline.hpp mutableNUMASpace.hpp mutableSpace.hpp @@ -64,6 +65,7 @@ mutableNUMASpace.hpp gcUtil.hpp mutableSpace.cpp mutableSpace.hpp mutableSpace.cpp oop.inline.hpp mutableSpace.cpp safepoint.hpp +mutableSpace.cpp spaceDecorator.hpp mutableSpace.cpp thread.hpp spaceCounters.cpp resourceArea.hpp diff --git a/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp b/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp index fa4a554b976..abdeb185a93 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp @@ -162,10 +162,9 @@ bool ASParNewGeneration::resize_generation(size_t eden_size, // Grow the generation size_t change = desired_size - orig_size; assert(change % alignment == 0, "just checking"); - if (!virtual_space()->expand_by(change)) { + if (expand(change)) { return false; // Error if we fail to resize! } - size_changed = true; } else if (desired_size < orig_size) { size_t desired_change = orig_size - desired_size; @@ -222,7 +221,9 @@ void ASParNewGeneration::reset_survivors_after_shrink() { // Was there a shrink of the survivor space? if (new_end < to()->end()) { MemRegion mr(to()->bottom(), new_end); - to()->initialize(mr, false /* clear */); + to()->initialize(mr, + SpaceDecorator::DontClear, + SpaceDecorator::DontMangle); } } } @@ -322,9 +323,7 @@ void ASParNewGeneration::resize_spaces(size_t requested_eden_size, pointer_delta(from_start, eden_start, sizeof(char))); } -// tty->print_cr("eden_size before: " SIZE_FORMAT, eden_size); eden_size = align_size_down(eden_size, alignment); -// tty->print_cr("eden_size after: " SIZE_FORMAT, eden_size); eden_end = eden_start + eden_size; assert(eden_end >= eden_start, "addition overflowed") @@ -501,11 +500,31 @@ void ASParNewGeneration::resize_spaces(size_t requested_eden_size, size_t old_from = from()->capacity(); size_t old_to = to()->capacity(); + // If not clearing the spaces, do some checking to verify that + // the spaces are already mangled. + + // Must check mangling before the spaces are reshaped. Otherwise, + // the bottom or end of one space may have moved into another + // a failure of the check may not correctly indicate which space + // is not properly mangled. + if (ZapUnusedHeapArea) { + HeapWord* limit = (HeapWord*) virtual_space()->high(); + eden()->check_mangled_unused_area(limit); + from()->check_mangled_unused_area(limit); + to()->check_mangled_unused_area(limit); + } + // The call to initialize NULL's the next compaction space - eden()->initialize(edenMR, true); + eden()->initialize(edenMR, + SpaceDecorator::Clear, + SpaceDecorator::DontMangle); eden()->set_next_compaction_space(from()); - to()->initialize(toMR , true); - from()->initialize(fromMR, false); // Note, not cleared! + to()->initialize(toMR , + SpaceDecorator::Clear, + SpaceDecorator::DontMangle); + from()->initialize(fromMR, + SpaceDecorator::DontClear, + SpaceDecorator::DontMangle); assert(from()->top() == old_from_top, "from top changed!"); diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp index 8beea55ee97..e2f7ef1541c 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp @@ -727,7 +727,7 @@ void ParNewGeneration::collect(bool full, SpecializationStats::clear(); age_table()->clear(); - to()->clear(); + to()->clear(SpaceDecorator::Mangle); gch->save_marks(); assert(workers != NULL, "Need parallel worker threads."); @@ -793,8 +793,18 @@ void ParNewGeneration::collect(bool full, } if (!promotion_failed()) { // Swap the survivor spaces. - eden()->clear(); - from()->clear(); + eden()->clear(SpaceDecorator::Mangle); + from()->clear(SpaceDecorator::Mangle); + if (ZapUnusedHeapArea) { + // This is now done here because of the piece-meal mangling which + // can check for valid mangling at intermediate points in the + // collection(s). When a minor collection fails to collect + // sufficient space resizing of the young generation can occur + // an redistribute the spaces in the young generation. Mangle + // here so that unzapped regions don't get distributed to + // other spaces. + to()->mangle_unused_area(); + } swap_spaces(); assert(to()->is_empty(), "to space should be empty now"); diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp index 7ef34bb89bd..d1efec8ff71 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp @@ -170,9 +170,20 @@ bool ASPSYoungGen::resize_generation(size_t eden_size, size_t survivor_size) { if (desired_size > orig_size) { // Grow the generation size_t change = desired_size - orig_size; + HeapWord* prev_low = (HeapWord*) virtual_space()->low(); if (!virtual_space()->expand_by(change)) { return false; } + if (ZapUnusedHeapArea) { + // Mangle newly committed space immediately because it + // can be done here more simply that after the new + // spaces have been computed. + HeapWord* new_low = (HeapWord*) virtual_space()->low(); + assert(new_low < prev_low, "Did not grow"); + + MemRegion mangle_region(new_low, prev_low); + SpaceMangler::mangle_region(mangle_region); + } size_changed = true; } else if (desired_size < orig_size) { size_t desired_change = orig_size - desired_size; @@ -215,8 +226,10 @@ bool ASPSYoungGen::resize_generation(size_t eden_size, size_t survivor_size) { // current implementation does not allow holes between the spaces // _young_generation_boundary has to be reset because it changes. // so additional verification + void ASPSYoungGen::resize_spaces(size_t requested_eden_size, size_t requested_survivor_size) { + assert(UseAdaptiveSizePolicy, "sanity check"); assert(requested_eden_size > 0 && requested_survivor_size > 0, "just checking"); @@ -276,22 +289,42 @@ void ASPSYoungGen::resize_spaces(size_t requested_eden_size, ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); const size_t alignment = heap->intra_heap_alignment(); + const bool maintain_minimum = + (requested_eden_size + 2 * requested_survivor_size) <= min_gen_size(); + bool eden_from_to_order = from_start < to_start; // Check whether from space is below to space - if (from_start < to_start) { + if (eden_from_to_order) { // Eden, from, to + if (PrintAdaptiveSizePolicy && Verbose) { gclog_or_tty->print_cr(" Eden, from, to:"); } // Set eden - // Compute how big eden can be, then adjust end. - // See comment in PSYoungGen::resize_spaces() on - // calculating eden_end. - const size_t eden_size = MIN2(requested_eden_size, - pointer_delta(from_start, - eden_start, - sizeof(char))); + // "requested_eden_size" is a goal for the size of eden + // and may not be attainable. "eden_size" below is + // calculated based on the location of from-space and + // the goal for the size of eden. from-space is + // fixed in place because it contains live data. + // The calculation is done this way to avoid 32bit + // overflow (i.e., eden_start + requested_eden_size + // may too large for representation in 32bits). + size_t eden_size; + if (maintain_minimum) { + // Only make eden larger than the requested size if + // the minimum size of the generation has to be maintained. + // This could be done in general but policy at a higher + // level is determining a requested size for eden and that + // should be honored unless there is a fundamental reason. + eden_size = pointer_delta(from_start, + eden_start, + sizeof(char)); + } else { + eden_size = MIN2(requested_eden_size, + pointer_delta(from_start, eden_start, sizeof(char))); + } + eden_end = eden_start + eden_size; assert(eden_end >= eden_start, "addition overflowed") @@ -371,12 +404,14 @@ void ASPSYoungGen::resize_spaces(size_t requested_eden_size, to_start = MAX2(to_start, eden_start + alignment); // Compute how big eden can be, then adjust end. - // See comment in PSYoungGen::resize_spaces() on - // calculating eden_end. - const size_t eden_size = MIN2(requested_eden_size, - pointer_delta(to_start, - eden_start, - sizeof(char))); + // See comments above on calculating eden_end. + size_t eden_size; + if (maintain_minimum) { + eden_size = pointer_delta(to_start, eden_start, sizeof(char)); + } else { + eden_size = MIN2(requested_eden_size, + pointer_delta(to_start, eden_start, sizeof(char))); + } eden_end = eden_start + eden_size; assert(eden_end >= eden_start, "addition overflowed") @@ -423,9 +458,47 @@ void ASPSYoungGen::resize_spaces(size_t requested_eden_size, size_t old_from = from_space()->capacity_in_bytes(); size_t old_to = to_space()->capacity_in_bytes(); - eden_space()->initialize(edenMR, true); - to_space()->initialize(toMR , true); - from_space()->initialize(fromMR, false); // Note, not cleared! + if (ZapUnusedHeapArea) { + // NUMA is a special case because a numa space is not mangled + // in order to not prematurely bind its address to memory to + // the wrong memory (i.e., don't want the GC thread to first + // touch the memory). The survivor spaces are not numa + // spaces and are mangled. + if (UseNUMA) { + if (eden_from_to_order) { + mangle_survivors(from_space(), fromMR, to_space(), toMR); + } else { + mangle_survivors(to_space(), toMR, from_space(), fromMR); + } + } + + // If not mangling the spaces, do some checking to verify that + // the spaces are already mangled. + // The spaces should be correctly mangled at this point so + // do some checking here. Note that they are not being mangled + // in the calls to initialize(). + // Must check mangling before the spaces are reshaped. Otherwise, + // the bottom or end of one space may have moved into an area + // covered by another space and a failure of the check may + // not correctly indicate which space is not properly mangled. + + HeapWord* limit = (HeapWord*) virtual_space()->high(); + eden_space()->check_mangled_unused_area(limit); + from_space()->check_mangled_unused_area(limit); + to_space()->check_mangled_unused_area(limit); + } + // When an existing space is being initialized, it is not + // mangled because the space has been previously mangled. + eden_space()->initialize(edenMR, + SpaceDecorator::Clear, + SpaceDecorator::DontMangle); + to_space()->initialize(toMR, + SpaceDecorator::Clear, + SpaceDecorator::DontMangle); + from_space()->initialize(fromMR, + SpaceDecorator::DontClear, + SpaceDecorator::DontMangle); + PSScavenge::set_young_generation_boundary(eden_space()->bottom()); assert(from_space()->top() == old_from_top, "from top changed!"); @@ -446,7 +519,6 @@ void ASPSYoungGen::resize_spaces(size_t requested_eden_size, } space_invariants(); } - void ASPSYoungGen::reset_after_change() { assert_locked_or_safepoint(Heap_lock); @@ -458,7 +530,9 @@ void ASPSYoungGen::reset_after_change() { HeapWord* eden_bottom = eden_space()->bottom(); if (new_eden_bottom != eden_bottom) { MemRegion eden_mr(new_eden_bottom, eden_space()->end()); - eden_space()->initialize(eden_mr, true); + eden_space()->initialize(eden_mr, + SpaceDecorator::Clear, + SpaceDecorator::Mangle); PSScavenge::set_young_generation_boundary(eden_space()->bottom()); } MemRegion cmr((HeapWord*)virtual_space()->low(), diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp index 2b2c6f87c51..affd72fc2b1 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp @@ -666,9 +666,9 @@ void CardTableExtension::resize_commit_uncommit(int changed_region, HeapWord* new_end_for_commit = MIN2(cur_committed.end(), _guard_region.start()); - MemRegion new_committed = - MemRegion(new_start_aligned, new_end_for_commit); - if(!new_committed.is_empty()) { + if(new_start_aligned < new_end_for_commit) { + MemRegion new_committed = + MemRegion(new_start_aligned, new_end_for_commit); if (!os::commit_memory((char*)new_committed.start(), new_committed.byte_size())) { vm_exit_out_of_memory(new_committed.byte_size(), diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp index 6fd50b39fc5..85ffd751270 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp @@ -938,3 +938,23 @@ void ParallelScavengeHeap::resize_old_gen(size_t desired_free_space) { // Delegate the resize to the generation. _old_gen->resize(desired_free_space); } + +#ifndef PRODUCT +void ParallelScavengeHeap::record_gen_tops_before_GC() { + if (ZapUnusedHeapArea) { + young_gen()->record_spaces_top(); + old_gen()->record_spaces_top(); + perm_gen()->record_spaces_top(); + } +} + +void ParallelScavengeHeap::gen_mangle_unused_area() { + if (ZapUnusedHeapArea) { + young_gen()->eden_space()->mangle_unused_area(); + young_gen()->to_space()->mangle_unused_area(); + young_gen()->from_space()->mangle_unused_area(); + old_gen()->object_space()->mangle_unused_area(); + perm_gen()->object_space()->mangle_unused_area(); + } +} +#endif diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp index d26eec48882..a4c141840b7 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp @@ -213,6 +213,12 @@ class ParallelScavengeHeap : public CollectedHeap { // Resize the old generation. The reserved space for the // generation may be expanded in preparation for the resize. void resize_old_gen(size_t desired_free_space); + + // Save the tops of the spaces in all generations + void record_gen_tops_before_GC() PRODUCT_RETURN; + + // Mangle the unused parts of all spaces in the heap + void gen_mangle_unused_area() PRODUCT_RETURN; }; inline size_t ParallelScavengeHeap::set_alignment(size_t& var, size_t val) diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp index 3a817a2049e..d42d4fc26df 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp @@ -98,6 +98,9 @@ void PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) { // Increment the invocation count heap->increment_total_collections(true /* full */); + // Save information needed to minimize mangling + heap->record_gen_tops_before_GC(); + // We need to track unique mark sweep invocations as well. _total_invocations++; @@ -188,6 +191,12 @@ void PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) { deallocate_stacks(); + if (ZapUnusedHeapArea) { + // Do a complete mangle (top to end) because the usage for + // scratch does not maintain a top pointer. + young_gen->to_space()->mangle_unused_area_complete(); + } + eden_empty = young_gen->eden_space()->is_empty(); if (!eden_empty) { eden_empty = absorb_live_data_from_eden(size_policy, young_gen, old_gen); @@ -198,7 +207,7 @@ void PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) { Universe::update_heap_info_at_gc(); survivors_empty = young_gen->from_space()->is_empty() && - young_gen->to_space()->is_empty(); + young_gen->to_space()->is_empty(); young_gen_empty = eden_empty && survivors_empty; BarrierSet* bs = heap->barrier_set(); @@ -344,6 +353,11 @@ void PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) { perm_gen->verify_object_start_array(); } + if (ZapUnusedHeapArea) { + old_gen->object_space()->check_mangled_unused_area_complete(); + perm_gen->object_space()->check_mangled_unused_area_complete(); + } + NOT_PRODUCT(ref_processor()->verify_no_references_recorded()); if (PrintHeapAtGC) { diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp index cec3a48db1a..c0fa75a8c98 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp @@ -438,5 +438,7 @@ void PSMarkSweepDecorator::compact(bool mangle_free_space ) { "should point inside space"); space()->set_top(compaction_top()); - if (mangle_free_space) space()->mangle_unused_area(); + if (mangle_free_space) { + space()->mangle_unused_area(); + } } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp index f92d291cc4e..89515f945c6 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp @@ -87,6 +87,15 @@ void PSOldGen::initialize_work(const char* perf_data_name, int level) { MemRegion cmr((HeapWord*)virtual_space()->low(), (HeapWord*)virtual_space()->high()); + if (ZapUnusedHeapArea) { + // Mangle newly committed space immediately rather than + // waiting for the initialization of the space even though + // mangling is related to spaces. Doing it here eliminates + // the need to carry along information that a complete mangling + // (bottom to end) needs to be done. + SpaceMangler::mangle_region(cmr); + } + Universe::heap()->barrier_set()->resize_covered_region(cmr); CardTableModRefBS* _ct = (CardTableModRefBS*)Universe::heap()->barrier_set(); @@ -112,7 +121,9 @@ void PSOldGen::initialize_work(const char* perf_data_name, int level) { if (_object_space == NULL) vm_exit_during_initialization("Could not allocate an old gen space"); - object_space()->initialize(cmr, true); + object_space()->initialize(cmr, + SpaceDecorator::Clear, + SpaceDecorator::Mangle); _object_mark_sweep = new PSMarkSweepDecorator(_object_space, start_array(), MarkSweepDeadRatio); @@ -232,6 +243,19 @@ bool PSOldGen::expand_by(size_t bytes) { assert_locked_or_safepoint(Heap_lock); bool result = virtual_space()->expand_by(bytes); if (result) { + if (ZapUnusedHeapArea) { + // We need to mangle the newly expanded area. The memregion spans + // end -> new_end, we assume that top -> end is already mangled. + // Do the mangling before post_resize() is called because + // the space is available for allocation after post_resize(); + HeapWord* const virtual_space_high = (HeapWord*) virtual_space()->high(); + assert(object_space()->end() < virtual_space_high, + "Should be true before post_resize()"); + MemRegion mangle_region(object_space()->end(), virtual_space_high); + // Note that the object space has not yet been updated to + // coincede with the new underlying virtual space. + SpaceMangler::mangle_region(mangle_region); + } post_resize(); if (UsePerfData) { _space_counters->update_capacity(); @@ -348,16 +372,7 @@ void PSOldGen::post_resize() { start_array()->set_covered_region(new_memregion); Universe::heap()->barrier_set()->resize_covered_region(new_memregion); - // Did we expand? HeapWord* const virtual_space_high = (HeapWord*) virtual_space()->high(); - if (object_space()->end() < virtual_space_high) { - // We need to mangle the newly expanded area. The memregion spans - // end -> new_end, we assume that top -> end is already mangled. - // This cannot be safely tested for, as allocation may be taking - // place. - MemRegion mangle_region(object_space()->end(), virtual_space_high); - object_space()->mangle_region(mangle_region); - } // ALWAYS do this last!! object_space()->set_end(virtual_space_high); @@ -462,3 +477,10 @@ void PSOldGen::verify_object_start_array() { VerifyObjectStartArrayClosure check( this, &_start_array ); object_iterate(&check); } + +#ifndef PRODUCT +void PSOldGen::record_spaces_top() { + assert(ZapUnusedHeapArea, "Not mangling unused space"); + object_space()->set_top_for_allocations(); +} +#endif diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp index a7a68bdf68e..7e1d30811e6 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp @@ -185,4 +185,8 @@ class PSOldGen : public CHeapObj { // Printing support virtual const char* name() const { return _name; } + + // Debugging support + // Save the tops of all spaces for later use during mangling. + void record_spaces_top() PRODUCT_RETURN; }; diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp index 8f9ec0e59c3..2b25332ab96 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp @@ -1058,6 +1058,10 @@ void PSParallelCompact::post_compact() ref_processor()->enqueue_discovered_references(NULL); + if (ZapUnusedHeapArea) { + heap->gen_mangle_unused_area(); + } + // Update time of last GC reset_millis_since_last_gc(); } @@ -1959,6 +1963,11 @@ void PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { PSPermGen* perm_gen = heap->perm_gen(); PSAdaptiveSizePolicy* size_policy = heap->size_policy(); + if (ZapUnusedHeapArea) { + // Save information needed to minimize mangling + heap->record_gen_tops_before_GC(); + } + _print_phases = PrintGCDetails && PrintParallelOldGCPhaseTimes; // Make sure data structures are sane, make the heap parsable, and do other @@ -2127,17 +2136,19 @@ void PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { size_t max_eden_size = young_gen->max_size() - young_gen->from_space()->capacity_in_bytes() - young_gen->to_space()->capacity_in_bytes(); - size_policy->compute_generation_free_space(young_gen->used_in_bytes(), - young_gen->eden_space()->used_in_bytes(), - old_gen->used_in_bytes(), - perm_gen->used_in_bytes(), - young_gen->eden_space()->capacity_in_bytes(), - old_gen->max_gen_size(), - max_eden_size, - true /* full gc*/, - gc_cause); + size_policy->compute_generation_free_space( + young_gen->used_in_bytes(), + young_gen->eden_space()->used_in_bytes(), + old_gen->used_in_bytes(), + perm_gen->used_in_bytes(), + young_gen->eden_space()->capacity_in_bytes(), + old_gen->max_gen_size(), + max_eden_size, + true /* full gc*/, + gc_cause); - heap->resize_old_gen(size_policy->calculated_old_free_size_in_bytes()); + heap->resize_old_gen( + size_policy->calculated_old_free_size_in_bytes()); // Don't resize the young generation at an major collection. A // desired young generation size may have been calculated but @@ -2210,6 +2221,11 @@ void PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { perm_gen->verify_object_start_array(); } + if (ZapUnusedHeapArea) { + old_gen->object_space()->check_mangled_unused_area_complete(); + perm_gen->object_space()->check_mangled_unused_area_complete(); + } + NOT_PRODUCT(ref_processor()->verify_no_references_recorded()); collection_exit.update(); diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp index 9566821169b..4b1f8572fa5 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp @@ -716,6 +716,99 @@ class BitBlockUpdateClosure: public ParMarkBitMapClosure { virtual IterationStatus do_addr(HeapWord* addr, size_t words); }; +// The UseParallelOldGC collector is a stop-the-world garbage +// collector that does parts of the collection using parallel threads. +// The collection includes the tenured generation and the young +// generation. The permanent generation is collected at the same +// time as the other two generations but the permanent generation +// is collect by a single GC thread. The permanent generation is +// collected serially because of the requirement that during the +// processing of a klass AAA, any objects reference by AAA must +// already have been processed. This requirement is enforced by +// a left (lower address) to right (higher address) sliding compaction. +// +// There are four phases of the collection. +// +// - marking phase +// - summary phase +// - compacting phase +// - clean up phase +// +// Roughly speaking these phases correspond, respectively, to +// - mark all the live objects +// - calculate the destination of each object at the end of the collection +// - move the objects to their destination +// - update some references and reinitialize some variables +// +// These three phases are invoked in PSParallelCompact::invoke_no_policy(). +// The marking phase is implemented in PSParallelCompact::marking_phase() +// and does a complete marking of the heap. +// The summary phase is implemented in PSParallelCompact::summary_phase(). +// The move and update phase is implemented in PSParallelCompact::compact(). +// +// A space that is being collected is divided into chunks and with +// each chunk is associated an object of type ParallelCompactData. +// Each chunk is of a fixed size and typically will contain more than +// 1 object and may have parts of objects at the front and back of the +// chunk. +// +// chunk -----+---------------------+---------- +// objects covered [ AAA )[ BBB )[ CCC )[ DDD ) +// +// The marking phase does a complete marking of all live objects in the +// heap. The marking also compiles the size of the data for +// all live objects covered by the chunk. This size includes the +// part of any live object spanning onto the chunk (part of AAA +// if it is live) from the front, all live objects contained in the chunk +// (BBB and/or CCC if they are live), and the part of any live objects +// covered by the chunk that extends off the chunk (part of DDD if it is +// live). The marking phase uses multiple GC threads and marking is +// done in a bit array of type ParMarkBitMap. The marking of the +// bit map is done atomically as is the accumulation of the size of the +// live objects covered by a chunk. +// +// The summary phase calculates the total live data to the left of +// each chunk XXX. Based on that total and the bottom of the space, +// it can calculate the starting location of the live data in XXX. +// The summary phase calculates for each chunk XXX quantites such as +// +// - the amount of live data at the beginning of a chunk from an object +// entering the chunk. +// - the location of the first live data on the chunk +// - a count of the number of chunks receiving live data from XXX. +// +// See ParallelCompactData for precise details. The summary phase also +// calculates the dense prefix for the compaction. The dense prefix +// is a portion at the beginning of the space that is not moved. The +// objects in the dense prefix do need to have their object references +// updated. See method summarize_dense_prefix(). +// +// The summary phase is done using 1 GC thread. +// +// The compaction phase moves objects to their new location and updates +// all references in the object. +// +// A current exception is that objects that cross a chunk boundary +// are moved but do not have their references updated. References are +// not updated because it cannot easily be determined if the klass +// pointer KKK for the object AAA has been updated. KKK likely resides +// in a chunk to the left of the chunk containing AAA. These AAA's +// have there references updated at the end in a clean up phase. +// See the method PSParallelCompact::update_deferred_objects(). An +// alternate strategy is being investigated for this deferral of updating. +// +// Compaction is done on a chunk basis. A chunk that is ready to be +// filled is put on a ready list and GC threads take chunk off the list +// and fill them. A chunk is ready to be filled if it +// empty of live objects. Such a chunk may have been initially +// empty (only contained +// dead objects) or may have had all its live objects copied out already. +// A chunk that compacts into itself is also ready for filling. The +// ready list is initially filled with empty chunks and chunks compacting +// into themselves. There is always at least 1 chunk that can be put on +// the ready list. The chunks are atomically added and removed from +// the ready list. +// class PSParallelCompact : AllStatic { public: // Convenient access to type names. diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp index 5f960dc9ece..7d655878206 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp @@ -265,6 +265,11 @@ bool PSScavenge::invoke_no_policy() { young_gen->eden_space()->accumulate_statistics(); } + if (ZapUnusedHeapArea) { + // Save information needed to minimize mangling + heap->record_gen_tops_before_GC(); + } + if (PrintHeapAtGC) { Universe::print_heap_before_gc(); } @@ -315,7 +320,7 @@ bool PSScavenge::invoke_no_policy() { if (!ScavengeWithObjectsInToSpace) { assert(young_gen->to_space()->is_empty(), "Attempt to scavenge with live objects in to_space"); - young_gen->to_space()->clear(); + young_gen->to_space()->clear(SpaceDecorator::Mangle); } else if (ZapUnusedHeapArea) { young_gen->to_space()->mangle_unused_area(); } @@ -437,8 +442,10 @@ bool PSScavenge::invoke_no_policy() { if (!promotion_failure_occurred) { // Swap the survivor spaces. - young_gen->eden_space()->clear(); - young_gen->from_space()->clear(); + + + young_gen->eden_space()->clear(SpaceDecorator::Mangle); + young_gen->from_space()->clear(SpaceDecorator::Mangle); young_gen->swap_spaces(); size_t survived = young_gen->from_space()->used_in_bytes(); @@ -600,6 +607,12 @@ bool PSScavenge::invoke_no_policy() { Universe::print_heap_after_gc(); } + if (ZapUnusedHeapArea) { + young_gen->eden_space()->check_mangled_unused_area_complete(); + young_gen->from_space()->check_mangled_unused_area_complete(); + young_gen->to_space()->check_mangled_unused_area_complete(); + } + scavenge_exit.update(); if (PrintGCTaskTimeStamps) { diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp index b7088556bdc..56a8491f6b0 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp @@ -36,7 +36,7 @@ PSYoungGen::PSYoungGen(size_t initial_size, void PSYoungGen::initialize_virtual_space(ReservedSpace rs, size_t alignment) { assert(_init_gen_size != 0, "Should have a finite size"); _virtual_space = new PSVirtualSpace(rs, alignment); - if (!_virtual_space->expand_by(_init_gen_size)) { + if (!virtual_space()->expand_by(_init_gen_size)) { vm_exit_during_initialization("Could not reserve enough space for " "object heap"); } @@ -49,13 +49,20 @@ void PSYoungGen::initialize(ReservedSpace rs, size_t alignment) { void PSYoungGen::initialize_work() { - _reserved = MemRegion((HeapWord*)_virtual_space->low_boundary(), - (HeapWord*)_virtual_space->high_boundary()); + _reserved = MemRegion((HeapWord*)virtual_space()->low_boundary(), + (HeapWord*)virtual_space()->high_boundary()); - MemRegion cmr((HeapWord*)_virtual_space->low(), - (HeapWord*)_virtual_space->high()); + MemRegion cmr((HeapWord*)virtual_space()->low(), + (HeapWord*)virtual_space()->high()); Universe::heap()->barrier_set()->resize_covered_region(cmr); + if (ZapUnusedHeapArea) { + // Mangle newly committed space immediately because it + // can be done here more simply that after the new + // spaces have been computed. + SpaceMangler::mangle_region(cmr); + } + if (UseNUMA) { _eden_space = new MutableNUMASpace(); } else { @@ -89,7 +96,7 @@ void PSYoungGen::initialize_work() { // Compute maximum space sizes for performance counters ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); size_t alignment = heap->intra_heap_alignment(); - size_t size = _virtual_space->reserved_size(); + size_t size = virtual_space()->reserved_size(); size_t max_survivor_size; size_t max_eden_size; @@ -142,7 +149,7 @@ void PSYoungGen::compute_initial_space_boundaries() { // Compute sizes size_t alignment = heap->intra_heap_alignment(); - size_t size = _virtual_space->committed_size(); + size_t size = virtual_space()->committed_size(); size_t survivor_size = size / InitialSurvivorRatio; survivor_size = align_size_down(survivor_size, alignment); @@ -164,18 +171,18 @@ void PSYoungGen::compute_initial_space_boundaries() { } void PSYoungGen::set_space_boundaries(size_t eden_size, size_t survivor_size) { - assert(eden_size < _virtual_space->committed_size(), "just checking"); + assert(eden_size < virtual_space()->committed_size(), "just checking"); assert(eden_size > 0 && survivor_size > 0, "just checking"); // Initial layout is Eden, to, from. After swapping survivor spaces, // that leaves us with Eden, from, to, which is step one in our two // step resize-with-live-data procedure. - char *eden_start = _virtual_space->low(); + char *eden_start = virtual_space()->low(); char *to_start = eden_start + eden_size; char *from_start = to_start + survivor_size; char *from_end = from_start + survivor_size; - assert(from_end == _virtual_space->high(), "just checking"); + assert(from_end == virtual_space()->high(), "just checking"); assert(is_object_aligned((intptr_t)eden_start), "checking alignment"); assert(is_object_aligned((intptr_t)to_start), "checking alignment"); assert(is_object_aligned((intptr_t)from_start), "checking alignment"); @@ -184,9 +191,9 @@ void PSYoungGen::set_space_boundaries(size_t eden_size, size_t survivor_size) { MemRegion to_mr ((HeapWord*)to_start, (HeapWord*)from_start); MemRegion from_mr((HeapWord*)from_start, (HeapWord*)from_end); - eden_space()->initialize(eden_mr, true); - to_space()->initialize(to_mr , true); - from_space()->initialize(from_mr, true); + eden_space()->initialize(eden_mr, true, ZapUnusedHeapArea); + to_space()->initialize(to_mr , true, ZapUnusedHeapArea); + from_space()->initialize(from_mr, true, ZapUnusedHeapArea); } #ifndef PRODUCT @@ -207,7 +214,7 @@ void PSYoungGen::space_invariants() { char* to_start = (char*)to_space()->bottom(); char* to_end = (char*)to_space()->end(); - guarantee(eden_start >= _virtual_space->low(), "eden bottom"); + guarantee(eden_start >= virtual_space()->low(), "eden bottom"); guarantee(eden_start < eden_end, "eden space consistency"); guarantee(from_start < from_end, "from space consistency"); guarantee(to_start < to_end, "to space consistency"); @@ -217,29 +224,29 @@ void PSYoungGen::space_invariants() { // Eden, from, to guarantee(eden_end <= from_start, "eden/from boundary"); guarantee(from_end <= to_start, "from/to boundary"); - guarantee(to_end <= _virtual_space->high(), "to end"); + guarantee(to_end <= virtual_space()->high(), "to end"); } else { // Eden, to, from guarantee(eden_end <= to_start, "eden/to boundary"); guarantee(to_end <= from_start, "to/from boundary"); - guarantee(from_end <= _virtual_space->high(), "from end"); + guarantee(from_end <= virtual_space()->high(), "from end"); } // More checks that the virtual space is consistent with the spaces - assert(_virtual_space->committed_size() >= + assert(virtual_space()->committed_size() >= (eden_space()->capacity_in_bytes() + to_space()->capacity_in_bytes() + from_space()->capacity_in_bytes()), "Committed size is inconsistent"); - assert(_virtual_space->committed_size() <= _virtual_space->reserved_size(), + assert(virtual_space()->committed_size() <= virtual_space()->reserved_size(), "Space invariant"); char* eden_top = (char*)eden_space()->top(); char* from_top = (char*)from_space()->top(); char* to_top = (char*)to_space()->top(); - assert(eden_top <= _virtual_space->high(), "eden top"); - assert(from_top <= _virtual_space->high(), "from top"); - assert(to_top <= _virtual_space->high(), "to top"); + assert(eden_top <= virtual_space()->high(), "eden top"); + assert(from_top <= virtual_space()->high(), "from top"); + assert(to_top <= virtual_space()->high(), "to top"); - _virtual_space->verify(); + virtual_space()->verify(); } #endif @@ -265,8 +272,8 @@ void PSYoungGen::resize(size_t eden_size, size_t survivor_size) { bool PSYoungGen::resize_generation(size_t eden_size, size_t survivor_size) { - const size_t alignment = _virtual_space->alignment(); - size_t orig_size = _virtual_space->committed_size(); + const size_t alignment = virtual_space()->alignment(); + size_t orig_size = virtual_space()->committed_size(); bool size_changed = false; // There used to be this guarantee there. @@ -288,10 +295,18 @@ bool PSYoungGen::resize_generation(size_t eden_size, size_t survivor_size) { // Grow the generation size_t change = desired_size - orig_size; assert(change % alignment == 0, "just checking"); - if (!_virtual_space->expand_by(change)) { + HeapWord* prev_high = (HeapWord*) virtual_space()->high(); + if (!virtual_space()->expand_by(change)) { return false; // Error if we fail to resize! } - + if (ZapUnusedHeapArea) { + // Mangle newly committed space immediately because it + // can be done here more simply that after the new + // spaces have been computed. + HeapWord* new_high = (HeapWord*) virtual_space()->high(); + MemRegion mangle_region(prev_high, new_high); + SpaceMangler::mangle_region(mangle_region); + } size_changed = true; } else if (desired_size < orig_size) { size_t desired_change = orig_size - desired_size; @@ -321,19 +336,95 @@ bool PSYoungGen::resize_generation(size_t eden_size, size_t survivor_size) { post_resize(); if (Verbose && PrintGC) { - size_t current_size = _virtual_space->committed_size(); + size_t current_size = virtual_space()->committed_size(); gclog_or_tty->print_cr("PSYoung generation size changed: " SIZE_FORMAT "K->" SIZE_FORMAT "K", orig_size/K, current_size/K); } } - guarantee(eden_plus_survivors <= _virtual_space->committed_size() || - _virtual_space->committed_size() == max_size(), "Sanity"); + guarantee(eden_plus_survivors <= virtual_space()->committed_size() || + virtual_space()->committed_size() == max_size(), "Sanity"); return true; } +#ifndef PRODUCT +// In the numa case eden is not mangled so a survivor space +// moving into a region previously occupied by a survivor +// may find an unmangled region. Also in the PS case eden +// to-space and from-space may not touch (i.e., there may be +// gaps between them due to movement while resizing the +// spaces). Those gaps must be mangled. +void PSYoungGen::mangle_survivors(MutableSpace* s1, + MemRegion s1MR, + MutableSpace* s2, + MemRegion s2MR) { + // Check eden and gap between eden and from-space, in deciding + // what to mangle in from-space. Check the gap between from-space + // and to-space when deciding what to mangle. + // + // +--------+ +----+ +---+ + // | eden | |s1 | |s2 | + // +--------+ +----+ +---+ + // +-------+ +-----+ + // |s1MR | |s2MR | + // +-------+ +-----+ + // All of survivor-space is properly mangled so find the + // upper bound on the mangling for any portion above current s1. + HeapWord* delta_end = MIN2(s1->bottom(), s1MR.end()); + MemRegion delta1_left; + if (s1MR.start() < delta_end) { + delta1_left = MemRegion(s1MR.start(), delta_end); + s1->mangle_region(delta1_left); + } + // Find any portion to the right of the current s1. + HeapWord* delta_start = MAX2(s1->end(), s1MR.start()); + MemRegion delta1_right; + if (delta_start < s1MR.end()) { + delta1_right = MemRegion(delta_start, s1MR.end()); + s1->mangle_region(delta1_right); + } + + // Similarly for the second survivor space except that + // any of the new region that overlaps with the current + // region of the first survivor space has already been + // mangled. + delta_end = MIN2(s2->bottom(), s2MR.end()); + delta_start = MAX2(s2MR.start(), s1->end()); + MemRegion delta2_left; + if (s2MR.start() < delta_end) { + delta2_left = MemRegion(s2MR.start(), delta_end); + s2->mangle_region(delta2_left); + } + delta_start = MAX2(s2->end(), s2MR.start()); + MemRegion delta2_right; + if (delta_start < s2MR.end()) { + s2->mangle_region(delta2_right); + } + + if (TraceZapUnusedHeapArea) { + // s1 + gclog_or_tty->print_cr("Current region: [" PTR_FORMAT ", " PTR_FORMAT ") " + "New region: [" PTR_FORMAT ", " PTR_FORMAT ")", + s1->bottom(), s1->end(), s1MR.start(), s1MR.end()); + gclog_or_tty->print_cr(" Mangle before: [" PTR_FORMAT ", " + PTR_FORMAT ") Mangle after: [" PTR_FORMAT ", " PTR_FORMAT ")", + delta1_left.start(), delta1_left.end(), delta1_right.start(), + delta1_right.end()); + + // s2 + gclog_or_tty->print_cr("Current region: [" PTR_FORMAT ", " PTR_FORMAT ") " + "New region: [" PTR_FORMAT ", " PTR_FORMAT ")", + s2->bottom(), s2->end(), s2MR.start(), s2MR.end()); + gclog_or_tty->print_cr(" Mangle before: [" PTR_FORMAT ", " + PTR_FORMAT ") Mangle after: [" PTR_FORMAT ", " PTR_FORMAT ")", + delta2_left.start(), delta2_left.end(), delta2_right.start(), + delta2_right.end()); + } + +} +#endif // NOT PRODUCT void PSYoungGen::resize_spaces(size_t requested_eden_size, size_t requested_survivor_size) { @@ -396,9 +487,11 @@ void PSYoungGen::resize_spaces(size_t requested_eden_size, const bool maintain_minimum = (requested_eden_size + 2 * requested_survivor_size) <= min_gen_size(); + bool eden_from_to_order = from_start < to_start; // Check whether from space is below to space - if (from_start < to_start) { + if (eden_from_to_order) { // Eden, from, to + eden_from_to_order = true; if (PrintAdaptiveSizePolicy && Verbose) { gclog_or_tty->print_cr(" Eden, from, to:"); } @@ -435,7 +528,7 @@ void PSYoungGen::resize_spaces(size_t requested_eden_size, // extra calculations. // First calculate an optimal to-space - to_end = (char*)_virtual_space->high(); + to_end = (char*)virtual_space()->high(); to_start = (char*)pointer_delta(to_end, (char*)requested_survivor_size, sizeof(char)); @@ -491,7 +584,7 @@ void PSYoungGen::resize_spaces(size_t requested_eden_size, // to space as if we were able to resize from space, even though from // space is not modified. // Giving eden priority was tried and gave poorer performance. - to_end = (char*)pointer_delta(_virtual_space->high(), + to_end = (char*)pointer_delta(virtual_space()->high(), (char*)requested_survivor_size, sizeof(char)); to_end = MIN2(to_end, from_start); @@ -560,9 +653,45 @@ void PSYoungGen::resize_spaces(size_t requested_eden_size, size_t old_from = from_space()->capacity_in_bytes(); size_t old_to = to_space()->capacity_in_bytes(); - eden_space()->initialize(edenMR, true); - to_space()->initialize(toMR , true); - from_space()->initialize(fromMR, false); // Note, not cleared! + if (ZapUnusedHeapArea) { + // NUMA is a special case because a numa space is not mangled + // in order to not prematurely bind its address to memory to + // the wrong memory (i.e., don't want the GC thread to first + // touch the memory). The survivor spaces are not numa + // spaces and are mangled. + if (UseNUMA) { + if (eden_from_to_order) { + mangle_survivors(from_space(), fromMR, to_space(), toMR); + } else { + mangle_survivors(to_space(), toMR, from_space(), fromMR); + } + } + + // If not mangling the spaces, do some checking to verify that + // the spaces are already mangled. + // The spaces should be correctly mangled at this point so + // do some checking here. Note that they are not being mangled + // in the calls to initialize(). + // Must check mangling before the spaces are reshaped. Otherwise, + // the bottom or end of one space may have moved into an area + // covered by another space and a failure of the check may + // not correctly indicate which space is not properly mangled. + HeapWord* limit = (HeapWord*) virtual_space()->high(); + eden_space()->check_mangled_unused_area(limit); + from_space()->check_mangled_unused_area(limit); + to_space()->check_mangled_unused_area(limit); + } + // When an existing space is being initialized, it is not + // mangled because the space has been previously mangled. + eden_space()->initialize(edenMR, + SpaceDecorator::Clear, + SpaceDecorator::DontMangle); + to_space()->initialize(toMR, + SpaceDecorator::Clear, + SpaceDecorator::DontMangle); + from_space()->initialize(fromMR, + SpaceDecorator::DontClear, + SpaceDecorator::DontMangle); assert(from_space()->top() == old_from_top, "from top changed!"); @@ -671,7 +800,7 @@ void PSYoungGen::print_on(outputStream* st) const { st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K", capacity_in_bytes()/K, used_in_bytes()/K); } - _virtual_space->print_space_boundaries_on(st); + virtual_space()->print_space_boundaries_on(st); st->print(" eden"); eden_space()->print_on(st); st->print(" from"); from_space()->print_on(st); st->print(" to "); to_space()->print_on(st); @@ -774,7 +903,9 @@ void PSYoungGen::reset_survivors_after_shrink() { // Was there a shrink of the survivor space? if (new_end < space_shrinking->end()) { MemRegion mr(space_shrinking->bottom(), new_end); - space_shrinking->initialize(mr, false /* clear */); + space_shrinking->initialize(mr, + SpaceDecorator::DontClear, + SpaceDecorator::Mangle); } } @@ -809,3 +940,12 @@ void PSYoungGen::verify(bool allow_dirty) { from_space()->verify(allow_dirty); to_space()->verify(allow_dirty); } + +#ifndef PRODUCT +void PSYoungGen::record_spaces_top() { + assert(ZapUnusedHeapArea, "Not mangling unused space"); + eden_space()->set_top_for_allocations(); + from_space()->set_top_for_allocations(); + to_space()->set_top_for_allocations(); +} +#endif diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp index 953d4309f20..4fad1bccffb 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp @@ -179,4 +179,12 @@ class PSYoungGen : public CHeapObj { // Space boundary invariant checker void space_invariants() PRODUCT_RETURN; + + // Helper for mangling survivor spaces. + void mangle_survivors(MutableSpace* s1, + MemRegion s1MR, + MutableSpace* s2, + MemRegion s2MR) PRODUCT_RETURN; + + void record_spaces_top() PRODUCT_RETURN; }; diff --git a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp index ff58cc3a43f..20ca6d3e31f 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp @@ -42,19 +42,31 @@ MutableNUMASpace::~MutableNUMASpace() { delete lgrp_spaces(); } +#ifndef PRODUCT void MutableNUMASpace::mangle_unused_area() { - for (int i = 0; i < lgrp_spaces()->length(); i++) { - LGRPSpace *ls = lgrp_spaces()->at(i); - MutableSpace *s = ls->space(); - if (!os::numa_has_static_binding()) { - HeapWord *top = MAX2((HeapWord*)round_down((intptr_t)s->top(), page_size()), s->bottom()); - if (top < s->end()) { - ls->add_invalid_region(MemRegion(top, s->end())); - } - } - s->mangle_unused_area(); - } + // This method should do nothing. + // It can be called on a numa space during a full compaction. } +void MutableNUMASpace::mangle_unused_area_complete() { + // This method should do nothing. + // It can be called on a numa space during a full compaction. +} +void MutableNUMASpace::mangle_region(MemRegion mr) { + // This method should do nothing because numa spaces are not mangled. +} +void MutableNUMASpace::set_top_for_allocations(HeapWord* v) { + assert(false, "Do not mangle MutableNUMASpace's"); +} +void MutableNUMASpace::set_top_for_allocations() { + // This method should do nothing. +} +void MutableNUMASpace::check_mangled_unused_area(HeapWord* limit) { + // This method should do nothing. +} +void MutableNUMASpace::check_mangled_unused_area_complete() { + // This method should do nothing. +} +#endif // NOT_PRODUCT // There may be unallocated holes in the middle chunks // that should be filled with dead objects to ensure parseability. @@ -243,7 +255,10 @@ void MutableNUMASpace::update() { s->set_end(s->bottom()); s->set_top(s->bottom()); } - initialize(region(), true); + // A NUMA space is never mangled + initialize(region(), + SpaceDecorator::Clear, + SpaceDecorator::DontMangle); } else { bool should_initialize = false; if (!os::numa_has_static_binding()) { @@ -257,7 +272,10 @@ void MutableNUMASpace::update() { if (should_initialize || (UseAdaptiveNUMAChunkSizing && adaptation_cycles() < samples_count())) { - initialize(region(), true); + // A NUMA space is never mangled + initialize(region(), + SpaceDecorator::Clear, + SpaceDecorator::DontMangle); } } @@ -448,14 +466,17 @@ void MutableNUMASpace::merge_regions(MemRegion new_region, MemRegion* intersecti } } -void MutableNUMASpace::initialize(MemRegion mr, bool clear_space) { +void MutableNUMASpace::initialize(MemRegion mr, + bool clear_space, + bool mangle_space) { assert(clear_space, "Reallocation will destory data!"); assert(lgrp_spaces()->length() > 0, "There should be at least one space"); MemRegion old_region = region(), new_region; set_bottom(mr.start()); set_end(mr.end()); - MutableSpace::set_top(bottom()); + // Must always clear the space + clear(SpaceDecorator::DontMangle); // Compute chunk sizes size_t prev_page_size = page_size(); @@ -586,10 +607,8 @@ void MutableNUMASpace::initialize(MemRegion mr, bool clear_space) { bias_region(top_region, ls->lgrp_id()); } - // If we clear the region, we would mangle it in debug. That would cause page - // allocation in a different place. Hence setting the top directly. - s->initialize(new_region, false); - s->set_top(s->bottom()); + // Clear space (set top = bottom) but never mangle. + s->initialize(new_region, SpaceDecorator::Clear, SpaceDecorator::DontMangle); set_adaptation_cycles(samples_count()); } @@ -641,10 +660,12 @@ void MutableNUMASpace::set_top(HeapWord* value) { MutableSpace::set_top(value); } -void MutableNUMASpace::clear() { +void MutableNUMASpace::clear(bool mangle_space) { MutableSpace::set_top(bottom()); for (int i = 0; i < lgrp_spaces()->length(); i++) { - lgrp_spaces()->at(i)->space()->clear(); + // Never mangle NUMA spaces because the mangling will + // bind the memory to a possibly unwanted lgroup. + lgrp_spaces()->at(i)->space()->clear(SpaceDecorator::DontMangle); } } diff --git a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp index 6b5dcbbe214..54a01299beb 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp @@ -171,14 +171,21 @@ class MutableNUMASpace : public MutableSpace { MutableNUMASpace(); virtual ~MutableNUMASpace(); // Space initialization. - virtual void initialize(MemRegion mr, bool clear_space); + virtual void initialize(MemRegion mr, bool clear_space, bool mangle_space); // Update space layout if necessary. Do all adaptive resizing job. virtual void update(); // Update allocation rate averages. virtual void accumulate_statistics(); - virtual void clear(); - virtual void mangle_unused_area(); + virtual void clear(bool mangle_space); + virtual void mangle_unused_area() PRODUCT_RETURN; + virtual void mangle_unused_area_complete() PRODUCT_RETURN; + virtual void mangle_region(MemRegion mr) PRODUCT_RETURN; + virtual void check_mangled_unused_area(HeapWord* limit) PRODUCT_RETURN; + virtual void check_mangled_unused_area_complete() PRODUCT_RETURN; + virtual void set_top_for_allocations(HeapWord* v) PRODUCT_RETURN; + virtual void set_top_for_allocations() PRODUCT_RETURN; + virtual void ensure_parsability(); virtual size_t used_in_words() const; virtual size_t free_in_words() const; diff --git a/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp b/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp index a91247a80d9..a5befabf056 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp @@ -25,7 +25,17 @@ # include "incls/_precompiled.incl" # include "incls/_mutableSpace.cpp.incl" -void MutableSpace::initialize(MemRegion mr, bool clear_space) { +MutableSpace::MutableSpace(): ImmutableSpace(), _top(NULL) { + _mangler = new MutableSpaceMangler(this); +} + +MutableSpace::~MutableSpace() { + delete _mangler; +} + +void MutableSpace::initialize(MemRegion mr, + bool clear_space, + bool mangle_space) { HeapWord* bottom = mr.start(); HeapWord* end = mr.end(); @@ -34,14 +44,51 @@ void MutableSpace::initialize(MemRegion mr, bool clear_space) { set_bottom(bottom); set_end(end); - if (clear_space) clear(); + if (clear_space) { + clear(mangle_space); + } } -void MutableSpace::clear() { +void MutableSpace::clear(bool mangle_space) { set_top(bottom()); - if (ZapUnusedHeapArea) mangle_unused_area(); + if (ZapUnusedHeapArea && mangle_space) { + mangle_unused_area(); + } } +#ifndef PRODUCT +void MutableSpace::check_mangled_unused_area(HeapWord* limit) { + mangler()->check_mangled_unused_area(limit); +} + +void MutableSpace::check_mangled_unused_area_complete() { + mangler()->check_mangled_unused_area_complete(); +} + +// Mangle only the unused space that has not previously +// been mangled and that has not been allocated since being +// mangled. +void MutableSpace::mangle_unused_area() { + mangler()->mangle_unused_area(); +} + +void MutableSpace::mangle_unused_area_complete() { + mangler()->mangle_unused_area_complete(); +} + +void MutableSpace::mangle_region(MemRegion mr) { + SpaceMangler::mangle_region(mr); +} + +void MutableSpace::set_top_for_allocations(HeapWord* v) { + mangler()->set_top_for_allocations(v); +} + +void MutableSpace::set_top_for_allocations() { + mangler()->set_top_for_allocations(top()); +} +#endif + // This version requires locking. */ HeapWord* MutableSpace::allocate(size_t size) { assert(Heap_lock->owned_by_self() || diff --git a/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp b/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp index f21930123b9..9c0271245f4 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp @@ -30,14 +30,23 @@ // Invariant: (ImmutableSpace +) bottom() <= top() <= end() // top() is inclusive and end() is exclusive. +class MutableSpaceMangler; + class MutableSpace: public ImmutableSpace { friend class VMStructs; + + // Helper for mangling unused space in debug builds + MutableSpaceMangler* _mangler; + protected: HeapWord* _top; + MutableSpaceMangler* mangler() { return _mangler; } + public: - virtual ~MutableSpace() {} - MutableSpace() { _top = NULL; } + virtual ~MutableSpace(); + MutableSpace(); + // Accessors HeapWord* top() const { return _top; } virtual void set_top(HeapWord* value) { _top = value; } @@ -52,21 +61,30 @@ class MutableSpace: public ImmutableSpace { MemRegion used_region() { return MemRegion(bottom(), top()); } // Initialization - virtual void initialize(MemRegion mr, bool clear_space); - virtual void clear(); + virtual void initialize(MemRegion mr, + bool clear_space, + bool mangle_space); + virtual void clear(bool mangle_space); + // Does the usual initialization but optionally resets top to bottom. +#if 0 // MANGLE_SPACE + void initialize(MemRegion mr, bool clear_space, bool reset_top); +#endif virtual void update() { } virtual void accumulate_statistics() { } - // Overwrites the unused portion of this space. Note that some collectors - // may use this "scratch" space during collections. - virtual void mangle_unused_area() { - mangle_region(MemRegion(_top, _end)); - } + // Methods used in mangling. See descriptions under SpaceMangler. + virtual void mangle_unused_area() PRODUCT_RETURN; + virtual void mangle_unused_area_complete() PRODUCT_RETURN; + virtual void check_mangled_unused_area(HeapWord* limit) PRODUCT_RETURN; + virtual void check_mangled_unused_area_complete() PRODUCT_RETURN; + virtual void set_top_for_allocations(HeapWord* v) PRODUCT_RETURN; + + // Used to save the space's current top for later use during mangling. + virtual void set_top_for_allocations() PRODUCT_RETURN; + virtual void ensure_parsability() { } - void mangle_region(MemRegion mr) { - debug_only(Copy::fill_to_words(mr.start(), mr.word_size(), badHeapWord)); - } + virtual void mangle_region(MemRegion mr) PRODUCT_RETURN; // Boolean querries. bool is_empty() const { return used_in_words() == 0; } diff --git a/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.cpp b/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.cpp new file mode 100644 index 00000000000..2d9fc59f675 --- /dev/null +++ b/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.cpp @@ -0,0 +1,140 @@ +/* + * Copyright 2002-2005 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +# include "incls/_precompiled.incl" +# include "incls/_spaceDecorator.cpp.incl" + +// Catch-all file for utility classes + +#ifndef PRODUCT + +// Returns true is the location q matches the mangling +// pattern. +bool SpaceMangler::is_mangled(HeapWord* q) { + // This test loses precision but is good enough + return badHeapWord == (max_juint & (uintptr_t) q->value()); +} + + +void SpaceMangler::set_top_for_allocations(HeapWord* v) { + if (v < end()) { + assert(is_mangled(v), "The high water mark is not mangled"); + } + _top_for_allocations = v; +} + +// Mangle only the unused space that has not previously +// been mangled and that has not been allocated since being +// mangled. +void SpaceMangler::mangle_unused_area() { + assert(ZapUnusedHeapArea, "Mangling should not be in use"); + // Mangle between top and the high water mark. Safeguard + // against the space changing since top_for_allocations was + // set. + HeapWord* mangled_end = MIN2(top_for_allocations(), end()); + if (top() < mangled_end) { + MemRegion mangle_mr(top(), mangled_end); + SpaceMangler::mangle_region(mangle_mr); + // Light weight check of mangling. + check_mangled_unused_area(end()); + } + // Complete check of unused area which is functional when + // DEBUG_MANGLING is defined. + check_mangled_unused_area_complete(); +} + +// A complete mangle is expected in the +// exceptional case where top_for_allocations is not +// properly tracking the high water mark for mangling. +// This can be the case when to-space is being used for +// scratch space during a mark-sweep-compact. See +// contribute_scratch() and PSMarkSweep::allocate_stacks(). +void SpaceMangler::mangle_unused_area_complete() { + assert(ZapUnusedHeapArea, "Mangling should not be in use"); + MemRegion mangle_mr(top(), end()); + SpaceMangler::mangle_region(mangle_mr); +} + +// Simply mangle the MemRegion mr. +void SpaceMangler::mangle_region(MemRegion mr) { + assert(ZapUnusedHeapArea, "Mangling should not be in use"); +#ifdef ASSERT + if(TraceZapUnusedHeapArea) { + gclog_or_tty->print("Mangling [0x%x to 0x%x)", mr.start(), mr.end()); + } + Copy::fill_to_words(mr.start(), mr.word_size(), badHeapWord); + if(TraceZapUnusedHeapArea) { + gclog_or_tty->print_cr(" done"); + } +#endif +} + +// Check that top, top_for_allocations and the last +// word of the space are mangled. In a tight memory +// situation even this light weight mangling could +// cause paging by touching the end of the space. +void SpaceMangler::check_mangled_unused_area(HeapWord* limit) { + if (CheckZapUnusedHeapArea) { + // This method can be called while the spaces are + // being reshaped so skip the test if the end of the + // space is beyond the specified limit; + if (end() > limit) return; + + assert(top() == end() || + (is_mangled(top())), "Top not mangled"); + assert((top_for_allocations() < top()) || + (top_for_allocations() >= end()) || + (is_mangled(top_for_allocations())), + "Older unused not mangled"); + assert(top() == end() || + (is_mangled(end() - 1)), "End not properly mangled"); + // Only does checking when DEBUG_MANGLING is defined. + check_mangled_unused_area_complete(); + } +} + +#undef DEBUG_MANGLING +// This should only be used while debugging the mangling +// because of the high cost of checking the completeness. +void SpaceMangler::check_mangled_unused_area_complete() { + if (CheckZapUnusedHeapArea) { + assert(ZapUnusedHeapArea, "Not mangling unused area"); +#ifdef DEBUG_MANGLING + HeapWord* q = top(); + HeapWord* limit = end(); + + bool passed = true; + while (q < limit) { + if (!is_mangled(q)) { + passed = false; + break; + } + q++; + } + assert(passed, "Mangling is not complete"); +#endif + } +} +#undef DEBUG_MANGLING +#endif // not PRODUCT diff --git a/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.hpp b/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.hpp new file mode 100644 index 00000000000..7298c47a91b --- /dev/null +++ b/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.hpp @@ -0,0 +1,141 @@ +/* + * Copyright 2002-2005 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +class SpaceDecorator: public AllStatic { + public: + // Initialization flags. + static const bool Clear = true; + static const bool DontClear = false; + static const bool Mangle = true; + static const bool DontMangle = false; +}; + +// Functionality for use with class Space and class MutableSpace. +// The approach taken with the mangling is to mangle all +// the space initially and then to mangle areas that have +// been allocated since the last collection. Mangling is +// done in the context of a generation and in the context +// of a space. +// The space in a generation is mangled when it is first +// initialized and when the generation grows. The spaces +// are not necessarily up-to-date when this mangling occurs +// and the method mangle_region() is used. +// After allocations have been done in a space, the space generally +// need to be remangled. Remangling is only done on the +// recently allocated regions in the space. Typically, that is +// the region between the new top and the top just before a +// garbage collection. +// An exception to the usual mangling in a space is done when the +// space is used for an extraordinary purpose. Specifically, when +// to-space is used as scratch space for a mark-sweep-compact +// collection. +// Spaces are mangled after a collection. If the generation +// grows after a collection, the added space is mangled as part of +// the growth of the generation. No additional mangling is needed when the +// spaces are resized after an expansion. +// The class SpaceMangler keeps a pointer to the top of the allocated +// area and provides the methods for doing the piece meal mangling. +// Methods for doing sparces and full checking of the mangling are +// included. The full checking is done if DEBUG_MANGLING is defined. +// GenSpaceMangler is used with the GenCollectedHeap collectors and +// MutableSpaceMangler is used with the ParallelScavengeHeap collectors. +// These subclasses abstract the differences in the types of spaces used +// by each heap. + +class SpaceMangler: public CHeapObj { + friend class VMStructs; + + // High water mark for allocations. Typically, the space above + // this point have been mangle previously and don't need to be + // touched again. Space belows this point has been allocated + // and remangling is needed between the current top and this + // high water mark. + HeapWord* _top_for_allocations; + HeapWord* top_for_allocations() { return _top_for_allocations; } + + public: + + // Setting _top_for_allocations to NULL at initialization + // makes it always below top so that mangling done as part + // of the initialize() call of a space does nothing (as it + // should since the mangling is done as part of the constructor + // for the space. + SpaceMangler() : _top_for_allocations(NULL) {} + + // Methods for top and end that delegate to the specific + // space type. + virtual HeapWord* top() const = 0; + virtual HeapWord* end() const = 0; + + // Return true if q matches the mangled pattern. + static bool is_mangled(HeapWord* q) PRODUCT_RETURN0; + + // Used to save the an address in a space for later use during mangling. + void set_top_for_allocations(HeapWord* v); + + // Overwrites the unused portion of this space. + // Mangle only the region not previously mangled [top, top_previously_mangled) + void mangle_unused_area(); + // Mangle all the unused region [top, end) + void mangle_unused_area_complete(); + // Do some sparse checking on the area that should have been mangled. + void check_mangled_unused_area(HeapWord* limit) PRODUCT_RETURN; + // Do a complete check of the area that should be mangled. + void check_mangled_unused_area_complete() PRODUCT_RETURN; + + // Mangle the MemRegion. This is a non-space specific mangler. It + // is used during the initial mangling of a space before the space + // is fully constructed. Also is used when a generation is expanded + // and possibly before the spaces have been reshaped to to the new + // size of the generation. + static void mangle_region(MemRegion mr); +}; + +class ContiguousSpace; + +// For use with GenCollectedHeap's +class GenSpaceMangler: public SpaceMangler { + ContiguousSpace* _sp; + + ContiguousSpace* sp() { return _sp; } + + HeapWord* top() const { return _sp->top(); } + HeapWord* end() const { return _sp->end(); } + + public: + GenSpaceMangler(ContiguousSpace* sp) : SpaceMangler(), _sp(sp) {} +}; + +// For use with ParallelScavengeHeap's. +class MutableSpaceMangler: public SpaceMangler { + MutableSpace* _sp; + + MutableSpace* sp() { return _sp; } + + HeapWord* top() const { return _sp->top(); } + HeapWord* end() const { return _sp->end(); } + + public: + MutableSpaceMangler(MutableSpace* sp) : SpaceMangler(), _sp(sp) {} +}; diff --git a/hotspot/src/share/vm/includeDB_core b/hotspot/src/share/vm/includeDB_core index 2af8fd826f1..8fade1d4d27 100644 --- a/hotspot/src/share/vm/includeDB_core +++ b/hotspot/src/share/vm/includeDB_core @@ -1405,6 +1405,7 @@ defNewGeneration.cpp java.hpp defNewGeneration.cpp oop.inline.hpp defNewGeneration.cpp referencePolicy.hpp defNewGeneration.cpp space.inline.hpp +defNewGeneration.cpp spaceDecorator.hpp defNewGeneration.cpp thread_.inline.hpp defNewGeneration.hpp ageTable.hpp @@ -1789,6 +1790,7 @@ generation.cpp generation.inline.hpp generation.cpp java.hpp generation.cpp oop.hpp generation.cpp oop.inline.hpp +generation.cpp spaceDecorator.hpp generation.cpp space.inline.hpp generation.hpp allocation.hpp @@ -3722,6 +3724,7 @@ space.cpp oop.inline2.hpp space.cpp safepoint.hpp space.cpp space.hpp space.cpp space.inline.hpp +space.cpp spaceDecorator.hpp space.cpp systemDictionary.hpp space.cpp universe.inline.hpp space.cpp vmSymbols.hpp @@ -3744,6 +3747,13 @@ space.inline.hpp safepoint.hpp space.inline.hpp space.hpp space.inline.hpp universe.hpp +spaceDecorator.hpp globalDefinitions.hpp +spaceDecorator.hpp mutableSpace.hpp +spaceDecorator.hpp space.hpp + +spaceDecorator.cpp copy.hpp +spaceDecorator.cpp spaceDecorator.hpp + specialized_oop_closures.cpp ostream.hpp specialized_oop_closures.cpp specialized_oop_closures.hpp diff --git a/hotspot/src/share/vm/includeDB_features b/hotspot/src/share/vm/includeDB_features index eec1c35259e..88f4c293643 100644 --- a/hotspot/src/share/vm/includeDB_features +++ b/hotspot/src/share/vm/includeDB_features @@ -51,6 +51,7 @@ dump.cpp oop.hpp dump.cpp oopFactory.hpp dump.cpp resourceArea.hpp dump.cpp signature.hpp +dump.cpp spaceDecorator.hpp dump.cpp symbolTable.hpp dump.cpp systemDictionary.hpp dump.cpp vmThread.hpp diff --git a/hotspot/src/share/vm/memory/defNewGeneration.cpp b/hotspot/src/share/vm/memory/defNewGeneration.cpp index d13c9e9adff..23449688dd7 100644 --- a/hotspot/src/share/vm/memory/defNewGeneration.cpp +++ b/hotspot/src/share/vm/memory/defNewGeneration.cpp @@ -172,15 +172,25 @@ DefNewGeneration::DefNewGeneration(ReservedSpace rs, _to_counters = new CSpaceCounters("s1", 2, _max_survivor_size, _to_space, _gen_counters); - compute_space_boundaries(0); + compute_space_boundaries(0, SpaceDecorator::Clear, SpaceDecorator::Mangle); update_counters(); _next_gen = NULL; _tenuring_threshold = MaxTenuringThreshold; _pretenure_size_threshold_words = PretenureSizeThreshold >> LogHeapWordSize; } -void DefNewGeneration::compute_space_boundaries(uintx minimum_eden_size) { - uintx alignment = GenCollectedHeap::heap()->collector_policy()->min_alignment(); +void DefNewGeneration::compute_space_boundaries(uintx minimum_eden_size, + bool clear_space, + bool mangle_space) { + uintx alignment = + GenCollectedHeap::heap()->collector_policy()->min_alignment(); + + // If the spaces are being cleared (only done at heap initialization + // currently), the survivor spaces need not be empty. + // Otherwise, no care is taken for used areas in the survivor spaces + // so check. + assert(clear_space || (to()->is_empty() && from()->is_empty()), + "Initialization of the survivor spaces assumes these are empty"); // Compute sizes uintx size = _virtual_space.committed_size(); @@ -214,16 +224,41 @@ void DefNewGeneration::compute_space_boundaries(uintx minimum_eden_size) { MemRegion fromMR((HeapWord*)from_start, (HeapWord*)to_start); MemRegion toMR ((HeapWord*)to_start, (HeapWord*)to_end); - eden()->initialize(edenMR, (minimum_eden_size == 0)); - // If minumum_eden_size != 0, we will not have cleared any + // A minimum eden size implies that there is a part of eden that + // is being used and that affects the initialization of any + // newly formed eden. + bool live_in_eden = minimum_eden_size > 0; + + // If not clearing the spaces, do some checking to verify that + // the space are already mangled. + if (!clear_space) { + // Must check mangling before the spaces are reshaped. Otherwise, + // the bottom or end of one space may have moved into another + // a failure of the check may not correctly indicate which space + // is not properly mangled. + if (ZapUnusedHeapArea) { + HeapWord* limit = (HeapWord*) _virtual_space.high(); + eden()->check_mangled_unused_area(limit); + from()->check_mangled_unused_area(limit); + to()->check_mangled_unused_area(limit); + } + } + + // Reset the spaces for their new regions. + eden()->initialize(edenMR, + clear_space && !live_in_eden, + SpaceDecorator::Mangle); + // If clear_space and live_in_eden, we will not have cleared any // portion of eden above its top. This can cause newly // expanded space not to be mangled if using ZapUnusedHeapArea. // We explicitly do such mangling here. - if (ZapUnusedHeapArea && (minimum_eden_size != 0)) { + if (ZapUnusedHeapArea && clear_space && live_in_eden && mangle_space) { eden()->mangle_unused_area(); } - from()->initialize(fromMR, true); - to()->initialize(toMR , true); + from()->initialize(fromMR, clear_space, mangle_space); + to()->initialize(toMR, clear_space, mangle_space); + + // Set next compaction spaces. eden()->set_next_compaction_space(from()); // The to-space is normally empty before a compaction so need // not be considered. The exception is during promotion @@ -250,7 +285,16 @@ void DefNewGeneration::swap_spaces() { bool DefNewGeneration::expand(size_t bytes) { MutexLocker x(ExpandHeap_lock); + HeapWord* prev_high = (HeapWord*) _virtual_space.high(); bool success = _virtual_space.expand_by(bytes); + if (success && ZapUnusedHeapArea) { + // Mangle newly committed space immediately because it + // can be done here more simply that after the new + // spaces have been computed. + HeapWord* new_high = (HeapWord*) _virtual_space.high(); + MemRegion mangle_region(prev_high, new_high); + SpaceMangler::mangle_region(mangle_region); + } // Do not attempt an expand-to-the reserve size. The // request should properly observe the maximum size of @@ -262,7 +306,8 @@ bool DefNewGeneration::expand(size_t bytes) { // value. if (GC_locker::is_active()) { if (PrintGC && Verbose) { - gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead"); + gclog_or_tty->print_cr("Garbage collection disabled, " + "expanded heap instead"); } } @@ -326,16 +371,24 @@ void DefNewGeneration::compute_new_size() { changed = true; } if (changed) { - compute_space_boundaries(eden()->used()); - MemRegion cmr((HeapWord*)_virtual_space.low(), (HeapWord*)_virtual_space.high()); + // The spaces have already been mangled at this point but + // may not have been cleared (set top = bottom) and should be. + // Mangling was done when the heap was being expanded. + compute_space_boundaries(eden()->used(), + SpaceDecorator::Clear, + SpaceDecorator::DontMangle); + MemRegion cmr((HeapWord*)_virtual_space.low(), + (HeapWord*)_virtual_space.high()); Universe::heap()->barrier_set()->resize_covered_region(cmr); if (Verbose && PrintGC) { size_t new_size_after = _virtual_space.committed_size(); size_t eden_size_after = eden()->capacity(); size_t survivor_size_after = from()->capacity(); - gclog_or_tty->print("New generation size " SIZE_FORMAT "K->" SIZE_FORMAT "K [eden=" + gclog_or_tty->print("New generation size " SIZE_FORMAT "K->" + SIZE_FORMAT "K [eden=" SIZE_FORMAT "K,survivor=" SIZE_FORMAT "K]", - new_size_before/K, new_size_after/K, eden_size_after/K, survivor_size_after/K); + new_size_before/K, new_size_after/K, + eden_size_after/K, survivor_size_after/K); if (WizardMode) { gclog_or_tty->print("[allowed " SIZE_FORMAT "K extra for %d threads]", thread_increase_size/K, threads_count); @@ -480,7 +533,7 @@ void DefNewGeneration::collect(bool full, ScanWeakRefClosure scan_weak_ref(this); age_table()->clear(); - to()->clear(); + to()->clear(SpaceDecorator::Mangle); gch->rem_set()->prepare_for_younger_refs_iterate(false); @@ -525,8 +578,18 @@ void DefNewGeneration::collect(bool full, soft_ref_policy, &is_alive, &keep_alive, &evacuate_followers, NULL); if (!promotion_failed()) { // Swap the survivor spaces. - eden()->clear(); - from()->clear(); + eden()->clear(SpaceDecorator::Mangle); + from()->clear(SpaceDecorator::Mangle); + if (ZapUnusedHeapArea) { + // This is now done here because of the piece-meal mangling which + // can check for valid mangling at intermediate points in the + // collection(s). When a minor collection fails to collect + // sufficient space resizing of the young generation can occur + // an redistribute the spaces in the young generation. Mangle + // here so that unzapped regions don't get distributed to + // other spaces. + to()->mangle_unused_area(); + } swap_spaces(); assert(to()->is_empty(), "to space should be empty now"); @@ -753,6 +816,15 @@ void DefNewGeneration::contribute_scratch(ScratchBlock*& list, Generation* reque } } +void DefNewGeneration::reset_scratch() { + // If contributing scratch in to_space, mangle all of + // to_space if ZapUnusedHeapArea. This is needed because + // top is not maintained while using to-space as scratch. + if (ZapUnusedHeapArea) { + to()->mangle_unused_area_complete(); + } +} + bool DefNewGeneration::collection_attempt_is_safe() { if (!to()->is_empty()) { return false; @@ -806,11 +878,25 @@ void DefNewGeneration::gc_epilogue(bool full) { } } + if (ZapUnusedHeapArea) { + eden()->check_mangled_unused_area_complete(); + from()->check_mangled_unused_area_complete(); + to()->check_mangled_unused_area_complete(); + } + // update the generation and space performance counters update_counters(); gch->collector_policy()->counters()->update_counters(); } +void DefNewGeneration::record_spaces_top() { + assert(ZapUnusedHeapArea, "Not mangling unused space"); + eden()->set_top_for_allocations(); + to()->set_top_for_allocations(); + from()->set_top_for_allocations(); +} + + void DefNewGeneration::update_counters() { if (UsePerfData) { _eden_counters->update_all(); diff --git a/hotspot/src/share/vm/memory/defNewGeneration.hpp b/hotspot/src/share/vm/memory/defNewGeneration.hpp index 893afc055c7..9d0cd68364a 100644 --- a/hotspot/src/share/vm/memory/defNewGeneration.hpp +++ b/hotspot/src/share/vm/memory/defNewGeneration.hpp @@ -279,6 +279,9 @@ protected: virtual void gc_prologue(bool full); virtual void gc_epilogue(bool full); + // Save the tops for eden, from, and to + virtual void record_spaces_top(); + // Doesn't require additional work during GC prologue and epilogue virtual bool performs_in_place_marking() const { return false; } @@ -299,9 +302,12 @@ protected: // For non-youngest collection, the DefNewGeneration can contribute // "to-space". - void contribute_scratch(ScratchBlock*& list, Generation* requestor, + virtual void contribute_scratch(ScratchBlock*& list, Generation* requestor, size_t max_alloc_words); + // Reset for contribution of "to-space". + virtual void reset_scratch(); + // GC support virtual void compute_new_size(); virtual void collect(bool full, @@ -331,7 +337,12 @@ protected: void verify(bool allow_dirty); protected: - void compute_space_boundaries(uintx minimum_eden_size); + // If clear_space is true, clear the survivor spaces. Eden is + // cleared if the minimum size of eden is 0. If mangle_space + // is true, also mangle the space in debug mode. + void compute_space_boundaries(uintx minimum_eden_size, + bool clear_space, + bool mangle_space); // Scavenge support void swap_spaces(); }; diff --git a/hotspot/src/share/vm/memory/dump.cpp b/hotspot/src/share/vm/memory/dump.cpp index 9499336282b..c5b938ea73f 100644 --- a/hotspot/src/share/vm/memory/dump.cpp +++ b/hotspot/src/share/vm/memory/dump.cpp @@ -645,7 +645,7 @@ public: class ClearSpaceClosure : public SpaceClosure { public: void do_space(Space* s) { - s->clear(); + s->clear(SpaceDecorator::Mangle); } }; diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.cpp b/hotspot/src/share/vm/memory/genCollectedHeap.cpp index dc3ba9b3cf3..efb3a95596f 100644 --- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp +++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp @@ -465,6 +465,11 @@ void GenCollectedHeap::do_collection(bool full, _gens[i]->stat_record()->invocations++; _gens[i]->stat_record()->accumulated_time.start(); + // Must be done anew before each collection because + // a previous collection will do mangling and will + // change top of some spaces. + record_gen_tops_before_GC(); + if (PrintGC && Verbose) { gclog_or_tty->print("level=%d invoke=%d size=" SIZE_FORMAT, i, @@ -1058,6 +1063,12 @@ ScratchBlock* GenCollectedHeap::gather_scratch(Generation* requestor, return res; } +void GenCollectedHeap::release_scratch() { + for (int i = 0; i < _n_gens; i++) { + _gens[i]->reset_scratch(); + } +} + size_t GenCollectedHeap::large_typearray_limit() { return gen_policy()->large_typearray_limit(); } @@ -1285,6 +1296,24 @@ void GenCollectedHeap::gc_epilogue(bool full) { always_do_update_barrier = UseConcMarkSweepGC; }; +#ifndef PRODUCT +class GenGCSaveTopsBeforeGCClosure: public GenCollectedHeap::GenClosure { + private: + public: + void do_generation(Generation* gen) { + gen->record_spaces_top(); + } +}; + +void GenCollectedHeap::record_gen_tops_before_GC() { + if (ZapUnusedHeapArea) { + GenGCSaveTopsBeforeGCClosure blk; + generation_iterate(&blk, false); // not old-to-young. + perm_gen()->record_spaces_top(); + } +} +#endif // not PRODUCT + class GenEnsureParsabilityClosure: public GenCollectedHeap::GenClosure { public: void do_generation(Generation* gen) { diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.hpp b/hotspot/src/share/vm/memory/genCollectedHeap.hpp index 54dce33bb80..1872c01ae6d 100644 --- a/hotspot/src/share/vm/memory/genCollectedHeap.hpp +++ b/hotspot/src/share/vm/memory/genCollectedHeap.hpp @@ -259,6 +259,9 @@ public: // be provided are returned as a list of ScratchBlocks, sorted by // decreasing size. ScratchBlock* gather_scratch(Generation* requestor, size_t max_alloc_words); + // Allow each generation to reset any scratch space that it has + // contributed as it needs. + void release_scratch(); size_t large_typearray_limit(); @@ -482,6 +485,9 @@ private: bool should_do_concurrent_full_gc(GCCause::Cause cause); void collect_mostly_concurrent(GCCause::Cause cause); + // Save the tops of the spaces in all generations + void record_gen_tops_before_GC() PRODUCT_RETURN; + protected: virtual void gc_prologue(bool full); virtual void gc_epilogue(bool full); diff --git a/hotspot/src/share/vm/memory/genMarkSweep.cpp b/hotspot/src/share/vm/memory/genMarkSweep.cpp index e98f6793001..318a3525cb7 100644 --- a/hotspot/src/share/vm/memory/genMarkSweep.cpp +++ b/hotspot/src/share/vm/memory/genMarkSweep.cpp @@ -190,6 +190,10 @@ void GenMarkSweep::allocate_stacks() { void GenMarkSweep::deallocate_stacks() { + + GenCollectedHeap* gch = GenCollectedHeap::heap(); + gch->release_scratch(); + if (_preserved_oop_stack) { delete _preserved_mark_stack; _preserved_mark_stack = NULL; diff --git a/hotspot/src/share/vm/memory/generation.cpp b/hotspot/src/share/vm/memory/generation.cpp index 5ed3ec09b7b..efefddf96d4 100644 --- a/hotspot/src/share/vm/memory/generation.cpp +++ b/hotspot/src/share/vm/memory/generation.cpp @@ -32,6 +32,12 @@ Generation::Generation(ReservedSpace rs, size_t initial_size, int level) : vm_exit_during_initialization("Could not reserve enough space for " "object heap"); } + // Mangle all of the the initial generation. + if (ZapUnusedHeapArea) { + MemRegion mangle_region((HeapWord*)_virtual_space.low(), + (HeapWord*)_virtual_space.high()); + SpaceMangler::mangle_region(mangle_region); + } _reserved = MemRegion((HeapWord*)_virtual_space.low_boundary(), (HeapWord*)_virtual_space.high_boundary()); } @@ -505,8 +511,11 @@ bool OneContigSpaceCardGeneration::grow_by(size_t bytes) { _bts->resize(new_word_size); // Fix for bug #4668531 - MemRegion mangle_region(_the_space->end(), (HeapWord*)_virtual_space.high()); - _the_space->mangle_region(mangle_region); + if (ZapUnusedHeapArea) { + MemRegion mangle_region(_the_space->end(), + (HeapWord*)_virtual_space.high()); + SpaceMangler::mangle_region(mangle_region); + } // Expand space -- also expands space's BOT // (which uses (part of) shared array above) @@ -622,6 +631,14 @@ void OneContigSpaceCardGeneration::gc_epilogue(bool full) { // update the generation and space performance counters update_counters(); + if (ZapUnusedHeapArea) { + the_space()->check_mangled_unused_area_complete(); + } +} + +void OneContigSpaceCardGeneration::record_spaces_top() { + assert(ZapUnusedHeapArea, "Not mangling unused space"); + the_space()->set_top_for_allocations(); } void OneContigSpaceCardGeneration::verify(bool allow_dirty) { diff --git a/hotspot/src/share/vm/memory/generation.hpp b/hotspot/src/share/vm/memory/generation.hpp index 2e146d53844..d87ebc3e529 100644 --- a/hotspot/src/share/vm/memory/generation.hpp +++ b/hotspot/src/share/vm/memory/generation.hpp @@ -376,6 +376,9 @@ class Generation: public CHeapObj { // The default is to do nothing. virtual void gc_epilogue(bool full) {}; + // Save the high water marks for the used space in a generation. + virtual void record_spaces_top() {}; + // Some generations may need to be "fixed-up" after some allocation // activity to make them parsable again. The default is to do nothing. virtual void ensure_parsability() {}; @@ -476,6 +479,10 @@ class Generation: public CHeapObj { virtual void contribute_scratch(ScratchBlock*& list, Generation* requestor, size_t max_alloc_words) {} + // Give each generation an opportunity to do clean up for any + // contributed scratch. + virtual void reset_scratch() {}; + // When an older generation has been collected, and perhaps resized, // this method will be invoked on all younger generations (from older to // younger), allowing them to resize themselves as appropriate. @@ -699,6 +706,8 @@ class OneContigSpaceCardGeneration: public CardGeneration { virtual void gc_epilogue(bool full); + virtual void record_spaces_top(); + virtual void verify(bool allow_dirty); virtual void print_on(outputStream* st) const; }; diff --git a/hotspot/src/share/vm/memory/space.cpp b/hotspot/src/share/vm/memory/space.cpp index 50dfd1df8d6..b3dab36a045 100644 --- a/hotspot/src/share/vm/memory/space.cpp +++ b/hotspot/src/share/vm/memory/space.cpp @@ -232,30 +232,44 @@ ContiguousSpace::new_dcto_cl(OopClosure* cl, return new ContiguousSpaceDCTOC(this, cl, precision, boundary); } -void Space::initialize(MemRegion mr, bool clear_space) { +void Space::initialize(MemRegion mr, + bool clear_space, + bool mangle_space) { HeapWord* bottom = mr.start(); HeapWord* end = mr.end(); assert(Universe::on_page_boundary(bottom) && Universe::on_page_boundary(end), "invalid space boundaries"); set_bottom(bottom); set_end(end); - if (clear_space) clear(); + if (clear_space) clear(mangle_space); } -void Space::clear() { - if (ZapUnusedHeapArea) mangle_unused_area(); +void Space::clear(bool mangle_space) { + if (ZapUnusedHeapArea && mangle_space) { + mangle_unused_area(); + } } -void ContiguousSpace::initialize(MemRegion mr, bool clear_space) +ContiguousSpace::ContiguousSpace(): CompactibleSpace(), _top(NULL) { + _mangler = new GenSpaceMangler(this); +} + +ContiguousSpace::~ContiguousSpace() { + delete _mangler; +} + +void ContiguousSpace::initialize(MemRegion mr, + bool clear_space, + bool mangle_space) { - CompactibleSpace::initialize(mr, clear_space); + CompactibleSpace::initialize(mr, clear_space, mangle_space); _concurrent_iteration_safe_limit = top(); } -void ContiguousSpace::clear() { +void ContiguousSpace::clear(bool mangle_space) { set_top(bottom()); set_saved_mark(); - Space::clear(); + Space::clear(mangle_space); } bool Space::is_in(const void* p) const { @@ -271,8 +285,8 @@ bool ContiguousSpace::is_free_block(const HeapWord* p) const { return p >= _top; } -void OffsetTableContigSpace::clear() { - ContiguousSpace::clear(); +void OffsetTableContigSpace::clear(bool mangle_space) { + ContiguousSpace::clear(mangle_space); _offsets.initialize_threshold(); } @@ -288,17 +302,46 @@ void OffsetTableContigSpace::set_end(HeapWord* new_end) { Space::set_end(new_end); } +#ifndef PRODUCT + +void ContiguousSpace::set_top_for_allocations(HeapWord* v) { + mangler()->set_top_for_allocations(v); +} +void ContiguousSpace::set_top_for_allocations() { + mangler()->set_top_for_allocations(top()); +} +void ContiguousSpace::check_mangled_unused_area(HeapWord* limit) { + mangler()->check_mangled_unused_area(limit); +} + +void ContiguousSpace::check_mangled_unused_area_complete() { + mangler()->check_mangled_unused_area_complete(); +} + +// Mangled only the unused space that has not previously +// been mangled and that has not been allocated since being +// mangled. void ContiguousSpace::mangle_unused_area() { - // to-space is used for storing marks during mark-sweep - mangle_region(MemRegion(top(), end())); + mangler()->mangle_unused_area(); +} +void ContiguousSpace::mangle_unused_area_complete() { + mangler()->mangle_unused_area_complete(); } - void ContiguousSpace::mangle_region(MemRegion mr) { - debug_only(Copy::fill_to_words(mr.start(), mr.word_size(), badHeapWord)); + // Although this method uses SpaceMangler::mangle_region() which + // is not specific to a space, the when the ContiguousSpace version + // is called, it is always with regard to a space and this + // bounds checking is appropriate. + MemRegion space_mr(bottom(), end()); + assert(space_mr.contains(mr), "Mangling outside space"); + SpaceMangler::mangle_region(mr); } +#endif // NOT_PRODUCT -void CompactibleSpace::initialize(MemRegion mr, bool clear_space) { - Space::initialize(mr, clear_space); +void CompactibleSpace::initialize(MemRegion mr, + bool clear_space, + bool mangle_space) { + Space::initialize(mr, clear_space, mangle_space); _compaction_top = bottom(); _next_compaction_space = NULL; } @@ -820,8 +863,8 @@ void ContiguousSpace::allocate_temporary_filler(int factor) { } } -void EdenSpace::clear() { - ContiguousSpace::clear(); +void EdenSpace::clear(bool mangle_space) { + ContiguousSpace::clear(mangle_space); set_soft_end(end()); } @@ -878,7 +921,7 @@ OffsetTableContigSpace::OffsetTableContigSpace(BlockOffsetSharedArray* sharedOff _par_alloc_lock(Mutex::leaf, "OffsetTableContigSpace par alloc lock", true) { _offsets.set_contig_space(this); - initialize(mr, true); + initialize(mr, SpaceDecorator::Clear, SpaceDecorator::Mangle); } diff --git a/hotspot/src/share/vm/memory/space.hpp b/hotspot/src/share/vm/memory/space.hpp index 37f726e5b3f..1cecd3a06ab 100644 --- a/hotspot/src/share/vm/memory/space.hpp +++ b/hotspot/src/share/vm/memory/space.hpp @@ -131,15 +131,17 @@ class Space: public CHeapObj { return MemRegion(bottom(), saved_mark_word()); } - // Initialization - virtual void initialize(MemRegion mr, bool clear_space); - virtual void clear(); + // Initialization. These may be run to reset an existing + // Space. + virtual void initialize(MemRegion mr, bool clear_space, bool mangle_space); + virtual void clear(bool mangle_space); // For detecting GC bugs. Should only be called at GC boundaries, since // some unused space may be used as scratch space during GC's. // Default implementation does nothing. We also call this when expanding // a space to satisfy an allocation request. See bug #4668531 virtual void mangle_unused_area() {} + virtual void mangle_unused_area_complete() {} virtual void mangle_region(MemRegion mr) {} // Testers @@ -354,7 +356,7 @@ private: CompactibleSpace* _next_compaction_space; public: - virtual void initialize(MemRegion mr, bool clear_space); + virtual void initialize(MemRegion mr, bool clear_space, bool mangle_space); // Used temporarily during a compaction phase to hold the value // top should have when compaction is complete. @@ -724,12 +726,14 @@ protected: /* continuously, but those that weren't need to have their thresholds */ \ /* re-initialized. Also mangles unused area for debugging. */ \ if (is_empty()) { \ - clear(); \ + clear(SpaceDecorator::Mangle); \ } else { \ if (ZapUnusedHeapArea) mangle_unused_area(); \ } \ } +class GenSpaceMangler; + // A space in which the free area is contiguous. It therefore supports // faster allocation, and compaction. class ContiguousSpace: public CompactibleSpace { @@ -738,13 +742,21 @@ class ContiguousSpace: public CompactibleSpace { protected: HeapWord* _top; HeapWord* _concurrent_iteration_safe_limit; + // A helper for mangling the unused area of the space in debug builds. + GenSpaceMangler* _mangler; + + GenSpaceMangler* mangler() { return _mangler; } // Allocation helpers (return NULL if full). inline HeapWord* allocate_impl(size_t word_size, HeapWord* end_value); inline HeapWord* par_allocate_impl(size_t word_size, HeapWord* end_value); public: - virtual void initialize(MemRegion mr, bool clear_space); + + ContiguousSpace(); + ~ContiguousSpace(); + + virtual void initialize(MemRegion mr, bool clear_space, bool mangle_space); // Accessors HeapWord* top() const { return _top; } @@ -753,15 +765,34 @@ class ContiguousSpace: public CompactibleSpace { void set_saved_mark() { _saved_mark_word = top(); } void reset_saved_mark() { _saved_mark_word = bottom(); } - virtual void clear(); + virtual void clear(bool mangle_space); WaterMark bottom_mark() { return WaterMark(this, bottom()); } WaterMark top_mark() { return WaterMark(this, top()); } WaterMark saved_mark() { return WaterMark(this, saved_mark_word()); } bool saved_mark_at_top() const { return saved_mark_word() == top(); } - void mangle_unused_area(); - void mangle_region(MemRegion mr); + // In debug mode mangle (write it with a particular bit + // pattern) the unused part of a space. + + // Used to save the an address in a space for later use during mangling. + void set_top_for_allocations(HeapWord* v) PRODUCT_RETURN; + // Used to save the space's current top for later use during mangling. + void set_top_for_allocations() PRODUCT_RETURN; + + // Mangle regions in the space from the current top up to the + // previously mangled part of the space. + void mangle_unused_area() PRODUCT_RETURN; + // Mangle [top, end) + void mangle_unused_area_complete() PRODUCT_RETURN; + // Mangle the given MemRegion. + void mangle_region(MemRegion mr) PRODUCT_RETURN; + + // Do some sparse checking on the area that should have been mangled. + void check_mangled_unused_area(HeapWord* limit) PRODUCT_RETURN; + // Check the complete area that should have been mangled. + // This code may be NULL depending on the macro DEBUG_MANGLING. + void check_mangled_unused_area_complete() PRODUCT_RETURN; // Size computations: sizes in bytes. size_t capacity() const { return byte_size(bottom(), end()); } @@ -956,7 +987,7 @@ class EdenSpace : public ContiguousSpace { void set_soft_end(HeapWord* value) { _soft_end = value; } // Override. - void clear(); + void clear(bool mangle_space); // Set both the 'hard' and 'soft' limits (_end and _soft_end). void set_end(HeapWord* value) { @@ -1000,7 +1031,7 @@ class OffsetTableContigSpace: public ContiguousSpace { void set_bottom(HeapWord* value); void set_end(HeapWord* value); - void clear(); + void clear(bool mangle_space); inline HeapWord* block_start(const void* p) const; diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index f54347f0251..fd490c9c033 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -589,9 +589,15 @@ class CommandLineFlags { develop(bool, ZapJNIHandleArea, trueInDebug, \ "Zap freed JNI handle space with 0xFEFEFEFE") \ \ - develop(bool, ZapUnusedHeapArea, false, \ + develop(bool, ZapUnusedHeapArea, trueInDebug, \ "Zap unused heap space with 0xBAADBABE") \ \ + develop(bool, TraceZapUnusedHeapArea, false, \ + "Trace zapping of unused heap space") \ + \ + develop(bool, CheckZapUnusedHeapArea, false, \ + "Check zapping of unused heap space") \ + \ develop(bool, PrintVMMessages, true, \ "Print vm messages on console") \ \ diff --git a/hotspot/src/share/vm/utilities/globalDefinitions.hpp b/hotspot/src/share/vm/utilities/globalDefinitions.hpp index c46312f49d7..120ef1f43ec 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp +++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp @@ -97,8 +97,12 @@ const int SerializePageShiftCount = 3; // object size. class HeapWord { friend class VMStructs; -private: + private: char* i; +#ifdef ASSERT + public: + char* value() { return i; } +#endif }; // HeapWordSize must be 2^LogHeapWordSize. From 398aa66a77bc8086ba00eb1a36295aca912cf39c Mon Sep 17 00:00:00 2001 From: John Coomes Date: Fri, 11 Jul 2008 16:11:34 -0700 Subject: [PATCH 03/52] 6718283: existing uses of *_FORMAT_W() were broken by 6521491 Reviewed-by: ysr, pbk --- .../parallelScavenge/psParallelCompact.cpp | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp index 2b25332ab96..7a41736fb63 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp @@ -200,8 +200,8 @@ void PSParallelCompact::print_chunk_ranges() for (unsigned int id = 0; id < last_space_id; ++id) { const MutableSpace* space = _space_info[id].space(); tty->print_cr("%u %s " - SIZE_FORMAT_W("10") " " SIZE_FORMAT_W("10") " " - SIZE_FORMAT_W("10") " " SIZE_FORMAT_W("10") " ", + SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " " + SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " ", id, space_names[id], summary_data().addr_to_chunk_idx(space->bottom()), summary_data().addr_to_chunk_idx(space->top()), @@ -213,8 +213,8 @@ void PSParallelCompact::print_chunk_ranges() void print_generic_summary_chunk(size_t i, const ParallelCompactData::ChunkData* c) { -#define CHUNK_IDX_FORMAT SIZE_FORMAT_W("7") -#define CHUNK_DATA_FORMAT SIZE_FORMAT_W("5") +#define CHUNK_IDX_FORMAT SIZE_FORMAT_W(7) +#define CHUNK_DATA_FORMAT SIZE_FORMAT_W(5) ParallelCompactData& sd = PSParallelCompact::summary_data(); size_t dci = c->destination() ? sd.addr_to_chunk_idx(c->destination()) : 0; @@ -269,9 +269,9 @@ print_initial_summary_chunk(size_t i, const ParallelCompactData::ChunkData* c, bool newline = true) { - tty->print(SIZE_FORMAT_W("5") " " PTR_FORMAT " " - SIZE_FORMAT_W("5") " " SIZE_FORMAT_W("5") " " - SIZE_FORMAT_W("5") " " SIZE_FORMAT_W("5") " %d", + tty->print(SIZE_FORMAT_W(5) " " PTR_FORMAT " " + SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " " + SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " %d", i, c->destination(), c->partial_obj_size(), c->live_obj_size(), c->data_size(), c->source_chunk(), c->destination_count()); @@ -326,7 +326,7 @@ print_initial_summary_data(ParallelCompactData& summary_data, } print_initial_summary_chunk(i, c, false); - tty->print_cr(" %12.10f " SIZE_FORMAT_W("10") " " SIZE_FORMAT_W("10"), + tty->print_cr(" %12.10f " SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10), reclaimed_ratio, dead_to_right, live_to_right); live_to_right -= c->data_size(); @@ -338,8 +338,8 @@ print_initial_summary_data(ParallelCompactData& summary_data, print_initial_summary_chunk(i, summary_data.chunk(i)); } - tty->print_cr("max: " SIZE_FORMAT_W("4") " d2r=" SIZE_FORMAT_W("10") " " - "l2r=" SIZE_FORMAT_W("10") " max_ratio=%14.12f", + tty->print_cr("max: " SIZE_FORMAT_W(4) " d2r=" SIZE_FORMAT_W(10) " " + "l2r=" SIZE_FORMAT_W(10) " max_ratio=%14.12f", max_reclaimed_ratio_chunk, max_dead_to_right, max_live_to_right, max_reclaimed_ratio); } @@ -1121,8 +1121,8 @@ PSParallelCompact::compute_dense_prefix_via_density(const SpaceId id, HeapWord* chunk_destination = cp->destination(); const size_t cur_deadwood = pointer_delta(dense_prefix, chunk_destination); if (TraceParallelOldGCDensePrefix && Verbose) { - tty->print_cr("c#=" SIZE_FORMAT_W("04") " dst=" PTR_FORMAT " " - "dp=" SIZE_FORMAT_W("08") " " "cdw=" SIZE_FORMAT_W("08"), + tty->print_cr("c#=" SIZE_FORMAT_W(4) " dst=" PTR_FORMAT " " + "dp=" SIZE_FORMAT_W(8) " " "cdw=" SIZE_FORMAT_W(8), sd.chunk(cp), chunk_destination, dense_prefix, cur_deadwood); } @@ -1147,7 +1147,7 @@ PSParallelCompact::compute_dense_prefix_via_density(const SpaceId id, return dense_prefix; } if (TraceParallelOldGCDensePrefix && Verbose) { - tty->print_cr("backing up from c=" SIZE_FORMAT_W("4") " d2r=%10.8f " + tty->print_cr("backing up from c=" SIZE_FORMAT_W(4) " d2r=%10.8f " "pc_d2r=%10.8f", sd.chunk(cp), density_to_right, prev_chunk_density_to_right); } @@ -1184,7 +1184,7 @@ void PSParallelCompact::print_dense_prefix_stats(const char* const algorithm, const size_t live_to_right = new_top - cp->destination(); const size_t dead_to_right = space->top() - addr - live_to_right; - tty->print_cr("%s=" PTR_FORMAT " dpc=" SIZE_FORMAT_W("05") " " + tty->print_cr("%s=" PTR_FORMAT " dpc=" SIZE_FORMAT_W(5) " " "spl=" SIZE_FORMAT " " "d2l=" SIZE_FORMAT " d2l%%=%6.4f " "d2r=" SIZE_FORMAT " l2r=" SIZE_FORMAT @@ -2513,7 +2513,7 @@ void PSParallelCompact::enqueue_chunk_draining_tasks(GCTaskQueue* q, if (TraceParallelOldGCCompactionPhase && Verbose) { const size_t count_mod_8 = fillable_chunks & 7; if (count_mod_8 == 0) gclog_or_tty->print("fillable: "); - gclog_or_tty->print(" " SIZE_FORMAT_W("7"), cur); + gclog_or_tty->print(" " SIZE_FORMAT_W(7), cur); if (count_mod_8 == 7) gclog_or_tty->cr(); } From 038a30dde34c5e17ed802ff43397099e6d3a4b77 Mon Sep 17 00:00:00 2001 From: John Coomes Date: Fri, 11 Jul 2008 16:11:43 -0700 Subject: [PATCH 04/52] 6483129: par compact assertion failure (new_top > bottom) Avoid computing the dense prefix if a space is empty Reviewed-by: pbk, tonyp --- .../parallelScavenge/psParallelCompact.cpp | 53 ++++++++++--------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp index 7a41736fb63..27b4ea90f56 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp @@ -1524,48 +1524,53 @@ void PSParallelCompact::summarize_space(SpaceId id, bool maximum_compaction) { assert(id < last_space_id, "id out of range"); + assert(_space_info[id].dense_prefix() == _space_info[id].space()->bottom(), + "should have been set in summarize_spaces_quick()"); const MutableSpace* space = _space_info[id].space(); - HeapWord** new_top_addr = _space_info[id].new_top_addr(); - - HeapWord* dense_prefix_end = compute_dense_prefix(id, maximum_compaction); - _space_info[id].set_dense_prefix(dense_prefix_end); + if (_space_info[id].new_top() != space->bottom()) { + HeapWord* dense_prefix_end = compute_dense_prefix(id, maximum_compaction); + _space_info[id].set_dense_prefix(dense_prefix_end); #ifndef PRODUCT - if (TraceParallelOldGCDensePrefix) { - print_dense_prefix_stats("ratio", id, maximum_compaction, dense_prefix_end); - HeapWord* addr = compute_dense_prefix_via_density(id, maximum_compaction); - print_dense_prefix_stats("density", id, maximum_compaction, addr); - } + if (TraceParallelOldGCDensePrefix) { + print_dense_prefix_stats("ratio", id, maximum_compaction, + dense_prefix_end); + HeapWord* addr = compute_dense_prefix_via_density(id, maximum_compaction); + print_dense_prefix_stats("density", id, maximum_compaction, addr); + } #endif // #ifndef PRODUCT - // If dead space crosses the dense prefix boundary, it is (at least partially) - // filled with a dummy object, marked live and added to the summary data. - // This simplifies the copy/update phase and must be done before the final - // locations of objects are determined, to prevent leaving a fragment of dead - // space that is too small to fill with an object. - if (!maximum_compaction && dense_prefix_end != space->bottom()) { - fill_dense_prefix_end(id); - } + // If dead space crosses the dense prefix boundary, it is (at least + // partially) filled with a dummy object, marked live and added to the + // summary data. This simplifies the copy/update phase and must be done + // before the final locations of objects are determined, to prevent leaving + // a fragment of dead space that is too small to fill with an object. + if (!maximum_compaction && dense_prefix_end != space->bottom()) { + fill_dense_prefix_end(id); + } - // Compute the destination of each Chunk, and thus each object. - _summary_data.summarize_dense_prefix(space->bottom(), dense_prefix_end); - _summary_data.summarize(dense_prefix_end, space->end(), - dense_prefix_end, space->top(), - new_top_addr); + // Compute the destination of each Chunk, and thus each object. + _summary_data.summarize_dense_prefix(space->bottom(), dense_prefix_end); + _summary_data.summarize(dense_prefix_end, space->end(), + dense_prefix_end, space->top(), + _space_info[id].new_top_addr()); + } if (TraceParallelOldGCSummaryPhase) { const size_t chunk_size = ParallelCompactData::ChunkSize; + HeapWord* const dense_prefix_end = _space_info[id].dense_prefix(); const size_t dp_chunk = _summary_data.addr_to_chunk_idx(dense_prefix_end); const size_t dp_words = pointer_delta(dense_prefix_end, space->bottom()); - const HeapWord* nt_aligned_up = _summary_data.chunk_align_up(*new_top_addr); + HeapWord* const new_top = _space_info[id].new_top(); + const HeapWord* nt_aligned_up = _summary_data.chunk_align_up(new_top); const size_t cr_words = pointer_delta(nt_aligned_up, dense_prefix_end); tty->print_cr("id=%d cap=" SIZE_FORMAT " dp=" PTR_FORMAT " " "dp_chunk=" SIZE_FORMAT " " "dp_count=" SIZE_FORMAT " " "cr_count=" SIZE_FORMAT " " "nt=" PTR_FORMAT, id, space->capacity_in_words(), dense_prefix_end, dp_chunk, dp_words / chunk_size, - cr_words / chunk_size, *new_top_addr); + cr_words / chunk_size, new_top); } } From 26625ab7f58d0741a1a3536746a819fd4da7c7b5 Mon Sep 17 00:00:00 2001 From: John Coomes Date: Fri, 11 Jul 2008 16:11:50 -0700 Subject: [PATCH 05/52] 6724367: par compact could clear less young gen summary data Reviewed-by: jmasa, apetrusenko --- .../parallelScavenge/psParallelCompact.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp index 27b4ea90f56..0b0d981fdc4 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp @@ -1639,7 +1639,7 @@ void PSParallelCompact::summary_phase(ParCompactionManager* cm, const size_t live = pointer_delta(_space_info[id].new_top(), space->bottom()); const size_t available = pointer_delta(target_space_end, *new_top_addr); - if (live <= available) { + if (live > 0 && live <= available) { // All the live data will fit. if (TraceParallelOldGCSummaryPhase) { tty->print_cr("summarizing %d into old_space @ " PTR_FORMAT, @@ -1649,16 +1649,18 @@ void PSParallelCompact::summary_phase(ParCompactionManager* cm, space->bottom(), space->top(), new_top_addr); - // Reset the new_top value for the space. - _space_info[id].set_new_top(space->bottom()); - // Clear the source_chunk field for each chunk in the space. + HeapWord* const new_top = _space_info[id].new_top(); + HeapWord* const clear_end = _summary_data.chunk_align_up(new_top); ChunkData* beg_chunk = _summary_data.addr_to_chunk_ptr(space->bottom()); - ChunkData* end_chunk = _summary_data.addr_to_chunk_ptr(space->top() - 1); - while (beg_chunk <= end_chunk) { + ChunkData* end_chunk = _summary_data.addr_to_chunk_ptr(clear_end); + while (beg_chunk < end_chunk) { beg_chunk->set_source_chunk(0); ++beg_chunk; } + + // Reset the new_top value for the space. + _space_info[id].set_new_top(space->bottom()); } } From e9e432633bdaa3b094c84f1d85ed476d5cc0eab2 Mon Sep 17 00:00:00 2001 From: Igor Veresov Date: Mon, 14 Jul 2008 04:12:47 -0700 Subject: [PATCH 06/52] 6720130: NUMA allocator: The linux version should search for libnuma.so.1 Search for libnuma.so.1 on Linux and liblgrp.so.1 on Solaris. Reviewed-by: jmasa --- hotspot/src/os/linux/vm/os_linux.cpp | 2 +- hotspot/src/os/solaris/vm/os_solaris.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index 73bcd1d0733..831cffcb81b 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -2278,7 +2278,7 @@ void os::Linux::libnuma_init() { dlsym(RTLD_DEFAULT, "sched_getcpu"))); if (sched_getcpu() != -1) { // Does it work? - void *handle = dlopen("libnuma.so", RTLD_LAZY); + void *handle = dlopen("libnuma.so.1", RTLD_LAZY); if (handle != NULL) { set_numa_node_to_cpus(CAST_TO_FN_PTR(numa_node_to_cpus_func_t, dlsym(handle, "numa_node_to_cpus"))); diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp index ce6765e8d50..99005264c7b 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.cpp +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp @@ -4570,7 +4570,7 @@ void os::Solaris::synchronization_init() { } void os::Solaris::liblgrp_init() { - void *handle = dlopen("liblgrp.so", RTLD_LAZY); + void *handle = dlopen("liblgrp.so.1", RTLD_LAZY); if (handle != NULL) { os::Solaris::set_lgrp_home(CAST_TO_FN_PTR(lgrp_home_func_t, dlsym(handle, "lgrp_home"))); os::Solaris::set_lgrp_init(CAST_TO_FN_PTR(lgrp_init_func_t, dlsym(handle, "lgrp_init"))); From a8fc1db8c1e873443bdc011e0803f45c265528ff Mon Sep 17 00:00:00 2001 From: Chuck Rasbold Date: Wed, 16 Jul 2008 10:08:57 -0700 Subject: [PATCH 07/52] 6707044: uncommon_trap of ifnull bytecode leaves garbage on expression stack Remove call to repush_if_args() Reviewed-by: kvn, jrose --- hotspot/src/share/vm/opto/parse2.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/opto/parse2.cpp b/hotspot/src/share/vm/opto/parse2.cpp index b3e0a9aff10..e244d6a098e 100644 --- a/hotspot/src/share/vm/opto/parse2.cpp +++ b/hotspot/src/share/vm/opto/parse2.cpp @@ -875,6 +875,8 @@ bool Parse::seems_never_taken(float prob) { return prob < PROB_MIN; } +//-------------------------------repush_if_args-------------------------------- +// Push arguments of an "if" bytecode back onto the stack by adjusting _sp. inline void Parse::repush_if_args() { #ifndef PRODUCT if (PrintOpto && WizardMode) { @@ -906,7 +908,6 @@ void Parse::do_ifnull(BoolTest::mask btest) { if (PrintOpto && Verbose) tty->print_cr("Never-taken backedge stops compilation at bci %d",bci()); #endif - repush_if_args(); // to gather stats on loop // We need to mark this branch as taken so that if we recompile we will // see that it is possible. In the tiered system the interpreter doesn't // do profiling and by the time we get to the lower tier from the interpreter From fae39068e8e2e14e65ac5f4e906e60efc90ba241 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Wed, 16 Jul 2008 16:04:39 -0700 Subject: [PATCH 08/52] 6723160: Nightly failure: Error: meet not symmetric Add missing _instance_id settings and other EA fixes. Reviewed-by: rasbold --- hotspot/src/share/vm/adlc/formssel.cpp | 2 + hotspot/src/share/vm/opto/callnode.cpp | 58 ++------------- hotspot/src/share/vm/opto/cfgnode.cpp | 6 +- hotspot/src/share/vm/opto/compile.cpp | 44 ++++++++--- hotspot/src/share/vm/opto/escape.cpp | 23 ++++-- hotspot/src/share/vm/opto/macro.cpp | 77 +++++++++++-------- hotspot/src/share/vm/opto/macro.hpp | 2 +- hotspot/src/share/vm/opto/memnode.cpp | 4 +- hotspot/src/share/vm/opto/node.hpp | 4 + hotspot/src/share/vm/opto/type.cpp | 35 +++------ hotspot/test/compiler/6724218/Test.java | 98 +++++++++++++++++++++++++ 11 files changed, 224 insertions(+), 129 deletions(-) create mode 100644 hotspot/test/compiler/6724218/Test.java diff --git a/hotspot/src/share/vm/adlc/formssel.cpp b/hotspot/src/share/vm/adlc/formssel.cpp index 47fe6ae04eb..b45de088afb 100644 --- a/hotspot/src/share/vm/adlc/formssel.cpp +++ b/hotspot/src/share/vm/adlc/formssel.cpp @@ -3825,6 +3825,8 @@ int MatchRule::is_expensive() const { strcmp(opType,"ConvL2D")==0 || strcmp(opType,"ConvL2F")==0 || strcmp(opType,"ConvL2I")==0 || + strcmp(opType,"DecodeN")==0 || + strcmp(opType,"EncodeP")==0 || strcmp(opType,"RoundDouble")==0 || strcmp(opType,"RoundFloat")==0 || strcmp(opType,"ReverseBytesI")==0 || diff --git a/hotspot/src/share/vm/opto/callnode.cpp b/hotspot/src/share/vm/opto/callnode.cpp index 84015b5335c..389db14fed5 100644 --- a/hotspot/src/share/vm/opto/callnode.cpp +++ b/hotspot/src/share/vm/opto/callnode.cpp @@ -631,61 +631,13 @@ uint CallNode::match_edge(uint idx) const { bool CallNode::may_modify(const TypePtr *addr_t, PhaseTransform *phase) { const TypeOopPtr *adrInst_t = addr_t->isa_oopptr(); - // if not an InstPtr or not an instance type, assume the worst - if (adrInst_t == NULL || !adrInst_t->is_known_instance_field()) { + // If not an OopPtr or not an instance type, assume the worst. + // Note: currently this method is called only for instance types. + if (adrInst_t == NULL || !adrInst_t->is_known_instance()) { return true; } - Compile *C = phase->C; - int offset = adrInst_t->offset(); - assert(adrInst_t->klass_is_exact() && offset >= 0, "should be valid offset"); - ciKlass* adr_k = adrInst_t->klass(); - assert(adr_k->is_loaded() && - adr_k->is_java_klass() && - !adr_k->is_interface(), - "only non-abstract classes are expected"); - - int base_idx = C->get_alias_index(adrInst_t); - int size = BytesPerLong; // If we don't know the size, assume largest. - if (adrInst_t->isa_instptr()) { - ciField* field = C->alias_type(base_idx)->field(); - if (field != NULL) { - size = field->size_in_bytes(); - } - } else { - assert(adrInst_t->isa_aryptr(), "only arrays are expected"); - size = type2aelembytes(adr_k->as_array_klass()->element_type()->basic_type()); - } - - ciMethod * meth = is_CallStaticJava() ? as_CallStaticJava()->method() : NULL; - BCEscapeAnalyzer *bcea = (meth != NULL) ? meth->get_bcea() : NULL; - - const TypeTuple * d = tf()->domain(); - for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { - const Type* t = d->field_at(i); - Node *arg = in(i); - const Type *at = phase->type(arg); - if (at == TypePtr::NULL_PTR || at == Type::TOP) - continue; // null can't affect anything - - const TypeOopPtr *at_ptr = at->isa_oopptr(); - if (!arg->is_top() && (t->isa_oopptr() != NULL || - t->isa_ptr() && at_ptr != NULL)) { - assert(at_ptr != NULL, "expecting an OopPtr"); - ciKlass* at_k = at_ptr->klass(); - if ((adrInst_t->base() == at_ptr->base()) && - at_k->is_loaded() && - at_k->is_java_klass()) { - // If we have found an argument matching addr_t, check if the field - // at the specified offset is modified. - if ((at_k->is_interface() || adr_k == at_k || - adr_k->is_subclass_of(at_k) && !at_ptr->klass_is_exact()) && - (bcea == NULL || - bcea->is_arg_modified(i - TypeFunc::Parms, offset, size))) { - return true; - } - } - } - } + // The instance_id is set only for scalar-replaceable allocations which + // are not passed as arguments according to Escape Analysis. return false; } diff --git a/hotspot/src/share/vm/opto/cfgnode.cpp b/hotspot/src/share/vm/opto/cfgnode.cpp index 6087c17e0dd..0e7b2845dbc 100644 --- a/hotspot/src/share/vm/opto/cfgnode.cpp +++ b/hotspot/src/share/vm/opto/cfgnode.cpp @@ -713,7 +713,9 @@ PhiNode* PhiNode::split_out_instance(const TypePtr* at, PhaseIterGVN *igvn) cons assert(type() == Type::MEMORY && (t == TypePtr::BOTTOM || t == TypeRawPtr::BOTTOM || t->isa_oopptr() && !t->is_oopptr()->is_known_instance() && - t->is_oopptr()->cast_to_instance_id(t_oop->instance_id()) == t_oop), + t->is_oopptr()->cast_to_exactness(true) + ->is_oopptr()->cast_to_ptr_type(t_oop->ptr()) + ->is_oopptr()->cast_to_instance_id(t_oop->instance_id()) == t_oop), "bottom or raw memory required"); // Check if an appropriate node already exists. @@ -1089,6 +1091,8 @@ Node* PhiNode::unique_input(PhaseTransform* phase) { if (rc == NULL || phase->type(rc) == Type::TOP) continue; // ignore unreachable control path Node* n = in(i); + if (n == NULL) + continue; Node* un = n->uncast(); if (un == NULL || un == this || phase->type(un) == Type::TOP) { continue; // ignore if top, or in(i) and "this" are in a data cycle diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp index 117fa54ff1b..c57a460d45d 100644 --- a/hotspot/src/share/vm/opto/compile.cpp +++ b/hotspot/src/share/vm/opto/compile.cpp @@ -999,9 +999,14 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const { int offset = tj->offset(); TypePtr::PTR ptr = tj->ptr(); + // Known instance (scalarizable allocation) alias only with itself. + bool is_known_inst = tj->isa_oopptr() != NULL && + tj->is_oopptr()->is_known_instance(); + // Process weird unsafe references. if (offset == Type::OffsetBot && (tj->isa_instptr() /*|| tj->isa_klassptr()*/)) { assert(InlineUnsafeOps, "indeterminate pointers come only from unsafe ops"); + assert(!is_known_inst, "scalarizable allocation should not have unsafe references"); tj = TypeOopPtr::BOTTOM; ptr = tj->ptr(); offset = tj->offset(); @@ -1009,14 +1014,20 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const { // Array pointers need some flattening const TypeAryPtr *ta = tj->isa_aryptr(); - if( ta && _AliasLevel >= 2 ) { + if( ta && is_known_inst ) { + if ( offset != Type::OffsetBot && + offset > arrayOopDesc::length_offset_in_bytes() ) { + offset = Type::OffsetBot; // Flatten constant access into array body only + tj = ta = TypeAryPtr::make(ptr, ta->ary(), ta->klass(), true, offset, ta->instance_id()); + } + } else if( ta && _AliasLevel >= 2 ) { // For arrays indexed by constant indices, we flatten the alias // space to include all of the array body. Only the header, klass // and array length can be accessed un-aliased. if( offset != Type::OffsetBot ) { if( ta->const_oop() ) { // methodDataOop or methodOop offset = Type::OffsetBot; // Flatten constant access into array body - tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),ta->ary(),ta->klass(),false,Type::OffsetBot, ta->instance_id()); + tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),ta->ary(),ta->klass(),false,offset); } else if( offset == arrayOopDesc::length_offset_in_bytes() ) { // range is OK as-is. tj = ta = TypeAryPtr::RANGE; @@ -1030,29 +1041,29 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const { ptr = TypePtr::BotPTR; } else { // Random constant offset into array body offset = Type::OffsetBot; // Flatten constant access into array body - tj = ta = TypeAryPtr::make(ptr,ta->ary(),ta->klass(),false,Type::OffsetBot, ta->instance_id()); + tj = ta = TypeAryPtr::make(ptr,ta->ary(),ta->klass(),false,offset); } } // Arrays of fixed size alias with arrays of unknown size. if (ta->size() != TypeInt::POS) { const TypeAry *tary = TypeAry::make(ta->elem(), TypeInt::POS); - tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,ta->klass(),false,offset, ta->instance_id()); + tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,ta->klass(),false,offset); } // Arrays of known objects become arrays of unknown objects. if (ta->elem()->isa_narrowoop() && ta->elem() != TypeNarrowOop::BOTTOM) { const TypeAry *tary = TypeAry::make(TypeNarrowOop::BOTTOM, ta->size()); - tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset, ta->instance_id()); + tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset); } if (ta->elem()->isa_oopptr() && ta->elem() != TypeInstPtr::BOTTOM) { const TypeAry *tary = TypeAry::make(TypeInstPtr::BOTTOM, ta->size()); - tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset, ta->instance_id()); + tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset); } // Arrays of bytes and of booleans both use 'bastore' and 'baload' so // cannot be distinguished by bytecode alone. if (ta->elem() == TypeInt::BOOL) { const TypeAry *tary = TypeAry::make(TypeInt::BYTE, ta->size()); ciKlass* aklass = ciTypeArrayKlass::make(T_BYTE); - tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,aklass,false,offset, ta->instance_id()); + tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,aklass,false,offset); } // During the 2nd round of IterGVN, NotNull castings are removed. // Make sure the Bottom and NotNull variants alias the same. @@ -1072,21 +1083,24 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const { if( ptr == TypePtr::Constant ) { // No constant oop pointers (such as Strings); they alias with // unknown strings. + assert(!is_known_inst, "not scalarizable allocation"); tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset); - } else if( to->is_known_instance_field() ) { + } else if( is_known_inst ) { tj = to; // Keep NotNull and klass_is_exact for instance type } else if( ptr == TypePtr::NotNull || to->klass_is_exact() ) { // During the 2nd round of IterGVN, NotNull castings are removed. // Make sure the Bottom and NotNull variants alias the same. // Also, make sure exact and non-exact variants alias the same. - tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset, to->instance_id()); + tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset); } // Canonicalize the holder of this field ciInstanceKlass *k = to->klass()->as_instance_klass(); if (offset >= 0 && offset < instanceOopDesc::base_offset_in_bytes()) { // First handle header references such as a LoadKlassNode, even if the // object's klass is unloaded at compile time (4965979). - tj = to = TypeInstPtr::make(TypePtr::BotPTR, env()->Object_klass(), false, NULL, offset, to->instance_id()); + if (!is_known_inst) { // Do it only for non-instance types + tj = to = TypeInstPtr::make(TypePtr::BotPTR, env()->Object_klass(), false, NULL, offset); + } } else if (offset < 0 || offset >= k->size_helper() * wordSize) { to = NULL; tj = TypeOopPtr::BOTTOM; @@ -1094,7 +1108,11 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const { } else { ciInstanceKlass *canonical_holder = k->get_canonical_holder(offset); if (!k->equals(canonical_holder) || tj->offset() != offset) { - tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, false, NULL, offset, to->instance_id()); + if( is_known_inst ) { + tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, true, NULL, offset, to->instance_id()); + } else { + tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, false, NULL, offset); + } } } } @@ -1280,7 +1298,9 @@ Compile::AliasType* Compile::find_alias_type(const TypePtr* adr_type, bool no_cr assert(flat != TypePtr::BOTTOM, "cannot alias-analyze an untyped ptr"); if (flat->isa_oopptr() && !flat->isa_klassptr()) { const TypeOopPtr* foop = flat->is_oopptr(); - const TypePtr* xoop = foop->cast_to_exactness(!foop->klass_is_exact())->is_ptr(); + // Scalarizable allocations have exact klass always. + bool exact = !foop->klass_is_exact() || foop->is_known_instance(); + const TypePtr* xoop = foop->cast_to_exactness(exact)->is_ptr(); assert(foop == flatten_alias_type(xoop), "exactness must not affect alias type"); } assert(flat == flatten_alias_type(flat), "exact bit doesn't matter"); diff --git a/hotspot/src/share/vm/opto/escape.cpp b/hotspot/src/share/vm/opto/escape.cpp index 795741284b0..8a779f59431 100644 --- a/hotspot/src/share/vm/opto/escape.cpp +++ b/hotspot/src/share/vm/opto/escape.cpp @@ -717,12 +717,17 @@ Node* ConnectionGraph::find_inst_mem(Node *orig_mem, int alias_idx, GrowableArra } } } - if (is_instance && result->is_Phi()) { + if (result->is_Phi()) { PhiNode *mphi = result->as_Phi(); assert(mphi->bottom_type() == Type::MEMORY, "memory phi required"); const TypePtr *t = mphi->adr_type(); if (C->get_alias_index(t) != alias_idx) { + // Create a new Phi with the specified alias index type. result = split_memory_phi(mphi, alias_idx, orig_phis, phase); + } else if (!is_instance) { + // Push all non-instance Phis on the orig_phis worklist to update inputs + // during Phase 4 if needed. + orig_phis.append_if_missing(mphi); } } // the result is either MemNode, PhiNode, InitializeNode. @@ -859,10 +864,14 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) !n->is_CheckCastPP()) // not unique CheckCastPP. continue; // The inline code for Object.clone() casts the allocation result to - // java.lang.Object and then to the the actual type of the allocated + // java.lang.Object and then to the actual type of the allocated // object. Detect this case and use the second cast. + // Also detect j.l.reflect.Array.newInstance(jobject, jint) case when + // the allocation result is cast to java.lang.Object and then + // to the actual Array type. if (alloc->is_Allocate() && n->as_Type()->type() == TypeInstPtr::NOTNULL - && igvn->type(alloc->in(AllocateNode::KlassNode)) != TypeKlassPtr::OBJECT) { + && (alloc->is_AllocateArray() || + igvn->type(alloc->in(AllocateNode::KlassNode)) != TypeKlassPtr::OBJECT)) { Node *cast2 = NULL; for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { Node *use = n->fast_out(i); @@ -878,7 +887,7 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) } } set_escape_state(n->_idx, es); - // in order for an object to be stackallocatable, it must be: + // in order for an object to be scalar-replaceable, it must be: // - a direct allocation (not a call returning an object) // - non-escaping // - eligible to be a unique type @@ -888,7 +897,7 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) const TypeOopPtr *t = igvn->type(n)->isa_oopptr(); if (t == NULL) continue; // not a TypeInstPtr - tinst = t->cast_to_instance_id(ni); + tinst = t->cast_to_exactness(true)->is_oopptr()->cast_to_instance_id(ni); igvn->hash_delete(n); igvn->set_type(n, tinst); n->raise_bottom_type(tinst); @@ -1204,8 +1213,8 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) // to recursively process Phi's encounted on the input memory // chains as is done in split_memory_phi() since they will // also be processed here. - while (orig_phis.length() != 0) { - PhiNode *phi = orig_phis.pop(); + for (int j = 0; j < orig_phis.length(); j++) { + PhiNode *phi = orig_phis.at(j); int alias_idx = _compile->get_alias_index(phi->adr_type()); igvn->hash_delete(phi); for (uint i = 1; i < phi->req(); i++) { diff --git a/hotspot/src/share/vm/opto/macro.cpp b/hotspot/src/share/vm/opto/macro.cpp index cd38a4be324..3e036249edd 100644 --- a/hotspot/src/share/vm/opto/macro.cpp +++ b/hotspot/src/share/vm/opto/macro.cpp @@ -231,8 +231,7 @@ static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_me } else { return mem; } - if (mem == orig_mem) - return mem; + assert(mem != orig_mem, "dead memory loop"); } } @@ -241,21 +240,44 @@ static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_me // on the input paths. // Note: this function is recursive, its depth is limied by the "level" argument // Returns the computed Phi, or NULL if it cannot compute it. -Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type *phi_type, const TypeOopPtr *adr_t, Node *alloc, int level) { - - if (level <= 0) { - return NULL; - } +Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type *phi_type, const TypeOopPtr *adr_t, Node *alloc, Node_Stack *value_phis, int level) { + assert(mem->is_Phi(), "sanity"); int alias_idx = C->get_alias_index(adr_t); int offset = adr_t->offset(); int instance_id = adr_t->instance_id(); + // Check if an appropriate value phi already exists. + Node* region = mem->in(0); + for (DUIterator_Fast kmax, k = region->fast_outs(kmax); k < kmax; k++) { + Node* phi = region->fast_out(k); + if (phi->is_Phi() && phi != mem && + phi->as_Phi()->is_same_inst_field(phi_type, instance_id, alias_idx, offset)) { + return phi; + } + } + // Check if an appropriate new value phi already exists. + Node* new_phi = NULL; + uint size = value_phis->size(); + for (uint i=0; i < size; i++) { + if ( mem->_idx == value_phis->index_at(i) ) { + return value_phis->node_at(i); + } + } + + if (level <= 0) { + return NULL; + } Node *start_mem = C->start()->proj_out(TypeFunc::Memory); Node *alloc_mem = alloc->in(TypeFunc::Memory); uint length = mem->req(); GrowableArray values(length, length, NULL); + // create a new Phi for the value + PhiNode *phi = new (C, length) PhiNode(mem->in(0), phi_type, NULL, instance_id, alias_idx, offset); + transform_later(phi); + value_phis->push(phi, mem->_idx); + for (uint j = 1; j < length; j++) { Node *in = mem->in(j); if (in == NULL || in->is_top()) { @@ -280,33 +302,17 @@ Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type * } else if(val->is_Proj() && val->in(0) == alloc) { values.at_put(j, _igvn.zerocon(ft)); } else if (val->is_Phi()) { - // Check if an appropriate node already exists. - Node* region = val->in(0); - Node* old_phi = NULL; - for (DUIterator_Fast kmax, k = region->fast_outs(kmax); k < kmax; k++) { - Node* phi = region->fast_out(k); - if (phi->is_Phi() && phi != val && - phi->as_Phi()->is_same_inst_field(phi_type, instance_id, alias_idx, offset)) { - old_phi = phi; - break; - } - } - if (old_phi == NULL) { - val = value_from_mem_phi(val, ft, phi_type, adr_t, alloc, level-1); - if (val == NULL) { - return NULL; - } - values.at_put(j, val); - } else { - values.at_put(j, old_phi); + val = value_from_mem_phi(val, ft, phi_type, adr_t, alloc, value_phis, level-1); + if (val == NULL) { + return NULL; } + values.at_put(j, val); } else { return NULL; // unknown node on this path } } } - // create a new Phi for the value - PhiNode *phi = new (C, length) PhiNode(mem->in(0), phi_type, NULL, instance_id, alias_idx, offset); + // Set Phi's inputs for (uint j = 1; j < length; j++) { if (values.at(j) == mem) { phi->init_req(j, phi); @@ -314,7 +320,6 @@ Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type * phi->init_req(j, values.at(j)); } } - transform_later(phi); return phi; } @@ -329,7 +334,8 @@ Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, BasicType ft, const Type Node *start_mem = C->start()->proj_out(TypeFunc::Memory); Node *alloc_ctrl = alloc->in(TypeFunc::Control); Node *alloc_mem = alloc->in(TypeFunc::Memory); - VectorSet visited(Thread::current()->resource_area()); + Arena *a = Thread::current()->resource_area(); + VectorSet visited(a); bool done = sfpt_mem == alloc_mem; @@ -389,9 +395,18 @@ Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, BasicType ft, const Type return mem->in(MemNode::ValueIn); } else if (mem->is_Phi()) { // attempt to produce a Phi reflecting the values on the input paths of the Phi - Node * phi = value_from_mem_phi(mem, ft, ftype, adr_t, alloc, 8); + Node_Stack value_phis(a, 8); + Node * phi = value_from_mem_phi(mem, ft, ftype, adr_t, alloc, &value_phis, 8); if (phi != NULL) { return phi; + } else { + // Kill all new Phis + while(value_phis.is_nonempty()) { + Node* n = value_phis.node(); + _igvn.hash_delete(n); + _igvn.subsume_node(n, C->top()); + value_phis.pop(); + } } } } diff --git a/hotspot/src/share/vm/opto/macro.hpp b/hotspot/src/share/vm/opto/macro.hpp index 0f784aafc02..89ed2bd2f47 100644 --- a/hotspot/src/share/vm/opto/macro.hpp +++ b/hotspot/src/share/vm/opto/macro.hpp @@ -79,7 +79,7 @@ private: const TypeFunc* slow_call_type, address slow_call_address); Node *value_from_mem(Node *mem, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, Node *alloc); - Node *value_from_mem_phi(Node *mem, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, Node *alloc, int level); + Node *value_from_mem_phi(Node *mem, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, Node *alloc, Node_Stack *value_phis, int level); bool eliminate_allocate_node(AllocateNode *alloc); bool can_eliminate_allocation(AllocateNode *alloc, GrowableArray & safepoints); diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp index 5015d99c483..8388753e937 100644 --- a/hotspot/src/share/vm/opto/memnode.cpp +++ b/hotspot/src/share/vm/opto/memnode.cpp @@ -135,7 +135,9 @@ Node *MemNode::optimize_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGV const TypePtr *t = mphi->adr_type(); if (t == TypePtr::BOTTOM || t == TypeRawPtr::BOTTOM || t->isa_oopptr() && !t->is_oopptr()->is_known_instance() && - t->is_oopptr()->cast_to_instance_id(t_oop->instance_id()) == t_oop) { + t->is_oopptr()->cast_to_exactness(true) + ->is_oopptr()->cast_to_ptr_type(t_oop->ptr()) + ->is_oopptr()->cast_to_instance_id(t_oop->instance_id()) == t_oop) { // clone the Phi with our address type result = mphi->split_out_instance(t_adr, igvn); } else { diff --git a/hotspot/src/share/vm/opto/node.hpp b/hotspot/src/share/vm/opto/node.hpp index 7f78b426b1c..e027265bf67 100644 --- a/hotspot/src/share/vm/opto/node.hpp +++ b/hotspot/src/share/vm/opto/node.hpp @@ -1399,6 +1399,10 @@ public: uint index() const { return _inode_top->indx; } + uint index_at(uint i) const { + assert(_inodes + i <= _inode_top, "in range"); + return _inodes[i].indx; + } void set_node(Node *n) { _inode_top->node = n; } diff --git a/hotspot/src/share/vm/opto/type.cpp b/hotspot/src/share/vm/opto/type.cpp index bb6c959388f..3a77c9da4f0 100644 --- a/hotspot/src/share/vm/opto/type.cpp +++ b/hotspot/src/share/vm/opto/type.cpp @@ -2218,7 +2218,7 @@ const Type *TypeOopPtr::cast_to_ptr_type(PTR ptr) const { return make(ptr, _offset); } -//-----------------------------cast_to_instance------------------------------- +//-----------------------------cast_to_instance_id---------------------------- const TypeOopPtr *TypeOopPtr::cast_to_instance_id(int instance_id) const { // There are no instances of a general oop. // Return self unchanged. @@ -2610,8 +2610,7 @@ const TypeInstPtr *TypeInstPtr::make(PTR ptr, // Ptr is never Null assert( ptr != Null, "NULL pointers are not typed" ); - if ( instance_id > 0 ) - xk = true; // instances are always exactly typed + assert(instance_id <= 0 || xk || !UseExactTypes, "instances are always exactly typed"); if (!UseExactTypes) xk = false; if (ptr == Constant) { // Note: This case includes meta-object constants, such as methods. @@ -2650,16 +2649,10 @@ const Type *TypeInstPtr::cast_to_exactness(bool klass_is_exact) const { return make(ptr(), klass(), klass_is_exact, const_oop(), _offset, _instance_id); } -//-----------------------------cast_to_instance------------------------------- +//-----------------------------cast_to_instance_id---------------------------- const TypeOopPtr *TypeInstPtr::cast_to_instance_id(int instance_id) const { if( instance_id == _instance_id ) return this; - bool exact = _klass_is_exact; - PTR ptr_t = _ptr; - if ( instance_id > 0 ) { // instances are always exactly typed - if (UseExactTypes) exact = true; - ptr_t = NotNull; - } - return make(ptr_t, klass(), exact, const_oop(), _offset, instance_id); + return make(_ptr, klass(), _klass_is_exact, const_oop(), _offset, instance_id); } //------------------------------xmeet_unloaded--------------------------------- @@ -2899,6 +2892,7 @@ const Type *TypeInstPtr::xmeet( const Type *t ) const { xk = above_centerline(ptr) ? tinst_xk : false; // Watch out for Constant vs. AnyNull interface. if (ptr == Constant) ptr = NotNull; // forget it was a constant + instance_id = InstanceBot; } ciObject* o = NULL; // the Constant value, if any if (ptr == Constant) { @@ -2989,6 +2983,7 @@ const Type *TypeInstPtr::xmeet( const Type *t ) const { // class hierarchy - which means we have to fall to at least NotNull. if( ptr == TopPTR || ptr == AnyNull || ptr == Constant ) ptr = NotNull; + instance_id = InstanceBot; // Now we find the LCA of Java classes ciKlass* k = this_klass->least_common_ancestor(tinst_klass); @@ -3101,8 +3096,7 @@ const TypeAryPtr *TypeAryPtr::make( PTR ptr, const TypeAry *ary, ciKlass* k, boo assert(!(k == NULL && ary->_elem->isa_int()), "integral arrays must be pre-equipped with a class"); if (!xk) xk = ary->ary_must_be_exact(); - if ( instance_id > 0 ) - xk = true; // instances are always exactly typed + assert(instance_id <= 0 || xk || !UseExactTypes, "instances are always exactly typed"); if (!UseExactTypes) xk = (ptr == Constant); return (TypeAryPtr*)(new TypeAryPtr(ptr, NULL, ary, k, xk, offset, instance_id))->hashcons(); } @@ -3113,8 +3107,7 @@ const TypeAryPtr *TypeAryPtr::make( PTR ptr, ciObject* o, const TypeAry *ary, ci "integral arrays must be pre-equipped with a class"); assert( (ptr==Constant && o) || (ptr!=Constant && !o), "" ); if (!xk) xk = (o != NULL) || ary->ary_must_be_exact(); - if ( instance_id > 0 ) - xk = true; // instances are always exactly typed + assert(instance_id <= 0 || xk || !UseExactTypes, "instances are always exactly typed"); if (!UseExactTypes) xk = (ptr == Constant); return (TypeAryPtr*)(new TypeAryPtr(ptr, o, ary, k, xk, offset, instance_id))->hashcons(); } @@ -3134,16 +3127,10 @@ const Type *TypeAryPtr::cast_to_exactness(bool klass_is_exact) const { return make(ptr(), const_oop(), _ary, klass(), klass_is_exact, _offset, _instance_id); } -//-----------------------------cast_to_instance------------------------------- +//-----------------------------cast_to_instance_id---------------------------- const TypeOopPtr *TypeAryPtr::cast_to_instance_id(int instance_id) const { if( instance_id == _instance_id ) return this; - bool exact = _klass_is_exact; - PTR ptr_t = _ptr; - if ( instance_id > 0 ) { // instances are always exactly typed - if (UseExactTypes) exact = true; - ptr_t = NotNull; - } - return make(ptr_t, const_oop(), _ary, klass(), exact, _offset, instance_id); + return make(_ptr, const_oop(), _ary, klass(), _klass_is_exact, _offset, instance_id); } //-----------------------------narrow_size_type------------------------------- @@ -3300,6 +3287,7 @@ const Type *TypeAryPtr::xmeet( const Type *t ) const { } else { // Something like byte[int+] meets char[int+]. // This must fall to bottom, not (int[-128..65535])[int+]. + instance_id = InstanceBot; tary = TypeAry::make(Type::BOTTOM, tary->_size); } } @@ -3316,6 +3304,7 @@ const Type *TypeAryPtr::xmeet( const Type *t ) const { if( tap->const_oop() != NULL && !o->equals(tap->const_oop()) ) { ptr = NotNull; o = NULL; + instance_id = InstanceBot; } } else if( above_centerline(_ptr) ) { o = tap->const_oop(); diff --git a/hotspot/test/compiler/6724218/Test.java b/hotspot/test/compiler/6724218/Test.java new file mode 100644 index 00000000000..c2835168567 --- /dev/null +++ b/hotspot/test/compiler/6724218/Test.java @@ -0,0 +1,98 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6724218 + * @summary Fix raise_LCA_above_marks() early termination + * @run main/othervm -Xbatch -XX:CompileCommand=exclude,Test.update Test + */ + +public class Test { + Test next = null; + Object value = null; + + static boolean _closed = false; + static int size = 0; + static Test list = null; + static int cache_size = 0; + static Test cache = null; + + Object get(int i) { + Test t = list; + list = t.next; + size -= 1; + Object o = t.value; + if (i > 0) { + t.next = cache; + t.value = null; + cache = t; + cache_size = +1; + } + return o; + } + + void update() { + // Exclude compilation of this one. + if (size == 0) { + Test t; + if (cache_size > 0) { + t = cache; + cache = t.next; + cache_size = -1; + } else { + t = new Test(); + } + t.value = new Object(); + t.next = list; + list = t; + size += 1; + } + } + + synchronized Object test(int i) { + while (true) { + if (_closed) { + return null; + } else if (size > 0) { + return get(i); + } + update(); + } + } + + public static void main(String argv[]) throws Exception { + Test t = new Test(); + int lim = 500000; + Object o; + for (int j = 0; j < lim; j++) { + o = t.test(j&1); + if (o == null) { + throw new Exception("*** Failed on iteration " + j); + } + if ((j&1) == 0) { + t.update(); + } + } + } +} From 1193f0f9dbe9e365e86f1865d828a86bccbc39ce Mon Sep 17 00:00:00 2001 From: Igor Veresov Date: Thu, 17 Jul 2008 10:26:33 -0700 Subject: [PATCH 09/52] 6723228: NUMA allocator: assert(lgrp_id != -1, "No lgrp_id set") 6723229: NUMA allocator: assert(lgrp_num > 0, "There should be at least one locality group") The fix takes care of the assertion triggered during TLAB resizing after reconfiguration. Also it now handles a defect in the topology graph, in which a single leaf node doesn't have memory. Reviewed-by: jmasa --- hotspot/src/os/solaris/vm/os_solaris.cpp | 6 ++++ .../vm/gc_implementation/shared/gcUtil.hpp | 12 +++++++ .../shared/mutableNUMASpace.cpp | 32 +++++++++++++++++-- .../shared/mutableNUMASpace.hpp | 1 + 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp index 99005264c7b..6a8d173691d 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.cpp +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp @@ -2658,6 +2658,12 @@ size_t os::numa_get_leaf_groups(int *ids, size_t size) { top += r; cur++; } + if (bottom == 0) { + // Handle a situation, when the OS reports no memory available. + // Assume UMA architecture. + ids[0] = 0; + return 1; + } return bottom; } diff --git a/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp b/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp index 83fdf871de7..a6596e7e99f 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp @@ -58,6 +58,12 @@ class AdaptiveWeightedAverage : public CHeapObj { _average(0.0), _sample_count(0), _weight(weight), _last_sample(0.0) { } + void clear() { + _average = 0; + _sample_count = 0; + _last_sample = 0; + } + // Accessors float average() const { return _average; } unsigned weight() const { return _weight; } @@ -115,6 +121,12 @@ class AdaptivePaddedAverage : public AdaptiveWeightedAverage { float deviation() const { return _deviation; } unsigned padding() const { return _padding; } + void clear() { + AdaptiveWeightedAverage::clear(); + _padded_avg = 0; + _deviation = 0; + } + // Override void sample(float new_sample); }; diff --git a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp index 20ca6d3e31f..50cfe16c887 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp @@ -141,7 +141,20 @@ size_t MutableNUMASpace::free_in_words() const { size_t MutableNUMASpace::tlab_capacity(Thread *thr) const { guarantee(thr != NULL, "No thread"); int lgrp_id = thr->lgrp_id(); - assert(lgrp_id != -1, "No lgrp_id set"); + if (lgrp_id == -1) { + // This case can occur after the topology of the system has + // changed. Thread can change their location, the new home + // group will be determined during the first allocation + // attempt. For now we can safely assume that all spaces + // have equal size because the whole space will be reinitialized. + if (lgrp_spaces()->length() > 0) { + return capacity_in_bytes() / lgrp_spaces()->length(); + } else { + assert(false, "There should be at least one locality group"); + return 0; + } + } + // That's the normal case, where we know the locality group of the thread. int i = lgrp_spaces()->find(&lgrp_id, LGRPSpace::equals); if (i == -1) { return 0; @@ -150,9 +163,17 @@ size_t MutableNUMASpace::tlab_capacity(Thread *thr) const { } size_t MutableNUMASpace::unsafe_max_tlab_alloc(Thread *thr) const { + // Please see the comments for tlab_capacity(). guarantee(thr != NULL, "No thread"); int lgrp_id = thr->lgrp_id(); - assert(lgrp_id != -1, "No lgrp_id set"); + if (lgrp_id == -1) { + if (lgrp_spaces()->length() > 0) { + return free_in_bytes() / lgrp_spaces()->length(); + } else { + assert(false, "There should be at least one locality group"); + return 0; + } + } int i = lgrp_spaces()->find(&lgrp_id, LGRPSpace::equals); if (i == -1) { return 0; @@ -250,10 +271,15 @@ void MutableNUMASpace::free_region(MemRegion mr) { void MutableNUMASpace::update() { if (update_layout(false)) { // If the topology has changed, make all chunks zero-sized. + // And clear the alloc-rate statistics. + // In future we may want to handle this more gracefully in order + // to avoid the reallocation of the pages as much as possible. for (int i = 0; i < lgrp_spaces()->length(); i++) { - MutableSpace *s = lgrp_spaces()->at(i)->space(); + LGRPSpace *ls = lgrp_spaces()->at(i); + MutableSpace *s = ls->space(); s->set_end(s->bottom()); s->set_top(s->bottom()); + ls->clear_alloc_rate(); } // A NUMA space is never mangled initialize(region(), diff --git a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp index 54a01299beb..61ee6d2bcc1 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp @@ -112,6 +112,7 @@ class MutableNUMASpace : public MutableSpace { int lgrp_id() const { return _lgrp_id; } MutableSpace* space() const { return _space; } AdaptiveWeightedAverage* alloc_rate() const { return _alloc_rate; } + void clear_alloc_rate() { _alloc_rate->clear(); } SpaceStats* space_stats() { return &_space_stats; } void clear_space_stats() { _space_stats = SpaceStats(); } From fcbf2d124562828671e68f0d2275334bda16d2a7 Mon Sep 17 00:00:00 2001 From: Chuck Rasbold Date: Mon, 21 Jul 2008 13:37:05 -0700 Subject: [PATCH 10/52] 6726504: handle do_ifxxx calls in parser more uniformly Make do_ifnull() handling similar to do_if() Reviewed-by: jrose, kvn --- hotspot/src/share/vm/opto/parse.hpp | 2 +- hotspot/src/share/vm/opto/parse2.cpp | 36 +++++++++++----------------- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/hotspot/src/share/vm/opto/parse.hpp b/hotspot/src/share/vm/opto/parse.hpp index 10b3fe2ca14..bf344cb6f5f 100644 --- a/hotspot/src/share/vm/opto/parse.hpp +++ b/hotspot/src/share/vm/opto/parse.hpp @@ -479,7 +479,7 @@ class Parse : public GraphKit { float branch_prediction(float &cnt, BoolTest::mask btest, int target_bci); bool seems_never_taken(float prob); - void do_ifnull(BoolTest::mask btest); + void do_ifnull(BoolTest::mask btest, Node* c); void do_if(BoolTest::mask btest, Node* c); void repush_if_args(); void adjust_map_after_if(BoolTest::mask btest, Node* c, float prob, diff --git a/hotspot/src/share/vm/opto/parse2.cpp b/hotspot/src/share/vm/opto/parse2.cpp index e244d6a098e..a71c7726a2b 100644 --- a/hotspot/src/share/vm/opto/parse2.cpp +++ b/hotspot/src/share/vm/opto/parse2.cpp @@ -894,7 +894,7 @@ inline void Parse::repush_if_args() { } //----------------------------------do_ifnull---------------------------------- -void Parse::do_ifnull(BoolTest::mask btest) { +void Parse::do_ifnull(BoolTest::mask btest, Node *c) { int target_bci = iter().get_dest(); Block* branch_block = successor_for_bci(target_bci); @@ -906,8 +906,9 @@ void Parse::do_ifnull(BoolTest::mask btest) { // (An earlier version of do_ifnull omitted this trap for OSR methods.) #ifndef PRODUCT if (PrintOpto && Verbose) - tty->print_cr("Never-taken backedge stops compilation at bci %d",bci()); + tty->print_cr("Never-taken edge stops compilation at bci %d",bci()); #endif + repush_if_args(); // to gather stats on loop // We need to mark this branch as taken so that if we recompile we will // see that it is possible. In the tiered system the interpreter doesn't // do profiling and by the time we get to the lower tier from the interpreter @@ -928,14 +929,6 @@ void Parse::do_ifnull(BoolTest::mask btest) { maybe_add_safepoint(target_bci); explicit_null_checks_inserted++; - Node* a = null(); - Node* b = pop(); - Node* c = _gvn.transform( new (C, 3) CmpPNode(b, a) ); - - // Make a cast-away-nullness that is control dependent on the test - const Type *t = _gvn.type(b); - const Type *t_not_null = t->join(TypePtr::NOTNULL); - Node *cast = new (C, 2) CastPPNode(b,t_not_null); // Generate real control flow Node *tst = _gvn.transform( new (C, 2) BoolNode( c, btest ) ); @@ -997,7 +990,7 @@ void Parse::do_if(BoolTest::mask btest, Node* c) { if (prob == PROB_UNKNOWN) { #ifndef PRODUCT if (PrintOpto && Verbose) - tty->print_cr("Never-taken backedge stops compilation at bci %d",bci()); + tty->print_cr("Never-taken edge stops compilation at bci %d",bci()); #endif repush_if_args(); // to gather stats on loop // We need to mark this branch as taken so that if we recompile we will @@ -1016,6 +1009,9 @@ void Parse::do_if(BoolTest::mask btest, Node* c) { return; } + // If this is a backwards branch in the bytecodes, add Safepoint + maybe_add_safepoint(target_bci); + // Sanity check the probability value assert(0.0f < prob && prob < 1.0f,"Bad probability in Parser"); @@ -2101,18 +2097,18 @@ void Parse::do_one_bytecode() { break; } - case Bytecodes::_ifnull: - do_ifnull(BoolTest::eq); - break; - case Bytecodes::_ifnonnull: - do_ifnull(BoolTest::ne); + case Bytecodes::_ifnull: btest = BoolTest::eq; goto handle_if_null; + case Bytecodes::_ifnonnull: btest = BoolTest::ne; goto handle_if_null; + handle_if_null: + a = null(); + b = pop(); + c = _gvn.transform( new (C, 3) CmpPNode(b, a) ); + do_ifnull(btest, c); break; case Bytecodes::_if_acmpeq: btest = BoolTest::eq; goto handle_if_acmp; case Bytecodes::_if_acmpne: btest = BoolTest::ne; goto handle_if_acmp; handle_if_acmp: - // If this is a backwards branch in the bytecodes, add Safepoint - maybe_add_safepoint(iter().get_dest()); a = pop(); b = pop(); c = _gvn.transform( new (C, 3) CmpPNode(b, a) ); @@ -2126,8 +2122,6 @@ void Parse::do_one_bytecode() { case Bytecodes::_ifgt: btest = BoolTest::gt; goto handle_ifxx; case Bytecodes::_ifge: btest = BoolTest::ge; goto handle_ifxx; handle_ifxx: - // If this is a backwards branch in the bytecodes, add Safepoint - maybe_add_safepoint(iter().get_dest()); a = _gvn.intcon(0); b = pop(); c = _gvn.transform( new (C, 3) CmpINode(b, a) ); @@ -2141,8 +2135,6 @@ void Parse::do_one_bytecode() { case Bytecodes::_if_icmpgt: btest = BoolTest::gt; goto handle_if_icmp; case Bytecodes::_if_icmpge: btest = BoolTest::ge; goto handle_if_icmp; handle_if_icmp: - // If this is a backwards branch in the bytecodes, add Safepoint - maybe_add_safepoint(iter().get_dest()); a = pop(); b = pop(); c = _gvn.transform( new (C, 3) CmpINode( b, a ) ); From 97c80b8c8476d3499583fdeb1d2dd69fc1d15f81 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Fri, 25 Jul 2008 09:07:29 -0700 Subject: [PATCH 11/52] 6717457: Internal Error (src/share/vm/code/relocInfo.hpp:1089) Reviewed-by: kvn --- hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp | 6 +++--- hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp | 10 +++++++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp index 9d17fce5ff3..058c230282f 100644 --- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp @@ -779,9 +779,9 @@ class StubGenerator: public StubCodeGenerator { __ shrl(end, CardTableModRefBS::card_shift); __ subl(end, start); // end --> count __ BIND(L_loop); - ExternalAddress base((address)ct->byte_map_base); - Address index(start, count, Address::times_1, 0); - __ movbyte(ArrayAddress(base, index), 0); + intptr_t disp = (intptr_t) ct->byte_map_base; + Address cardtable(start, count, Address::times_1, disp); + __ movb(cardtable, 0); __ decrement(count); __ jcc(Assembler::greaterEqual, L_loop); } diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp index 68188361b50..c3b61d5bf76 100644 --- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp @@ -1222,8 +1222,16 @@ class StubGenerator: public StubCodeGenerator { __ shrq(end, CardTableModRefBS::card_shift); __ subq(end, start); // number of bytes to copy + intptr_t disp = (intptr_t) ct->byte_map_base; + if (__ is_simm32(disp)) { + Address cardtable(noreg, noreg, Address::no_scale, disp); + __ lea(scratch, cardtable); + } else { + ExternalAddress cardtable((address)disp); + __ lea(scratch, cardtable); + } + const Register count = end; // 'end' register contains bytes count now - __ lea(scratch, ExternalAddress((address)ct->byte_map_base)); __ addq(start, scratch); __ BIND(L_loop); __ movb(Address(start, count, Address::times_1), 0); From 7b4a7f7bdc40568b99edf9ea7341d8e29d8a9d87 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Fri, 25 Jul 2008 11:32:56 -0700 Subject: [PATCH 12/52] 6712835: Server compiler fails with assertion (loop_count < K,"infinite loop in PhaseIterGVN::transform") Reviewed-by: kvn --- hotspot/src/share/vm/ci/ciMethodBlocks.cpp | 2 +- .../src/share/vm/opto/idealGraphPrinter.cpp | 2 + hotspot/src/share/vm/opto/ifnode.cpp | 6 + .../test/compiler/6712835/Test6712835.java | 1578 +++++++++++++++++ 4 files changed, 1587 insertions(+), 1 deletion(-) create mode 100644 hotspot/test/compiler/6712835/Test6712835.java diff --git a/hotspot/src/share/vm/ci/ciMethodBlocks.cpp b/hotspot/src/share/vm/ci/ciMethodBlocks.cpp index 9bfba219b88..2810523f4fc 100644 --- a/hotspot/src/share/vm/ci/ciMethodBlocks.cpp +++ b/hotspot/src/share/vm/ci/ciMethodBlocks.cpp @@ -351,7 +351,7 @@ void ciBlock::set_exception_range(int start_bci, int limit_bci) { } #ifndef PRODUCT -static char *flagnames[] = { +static const char *flagnames[] = { "Processed", "Handler", "MayThrow", diff --git a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp index 114a7ea17c7..de961127e68 100644 --- a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp +++ b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp @@ -473,10 +473,12 @@ void IdealGraphPrinter::visit_node(Node *n, void *param) { print_prop("is_dontcare", "false"); } +#ifdef ASSERT Node* old = C->matcher()->find_old_node(node); if (old != NULL) { print_prop("old_node_idx", old->_idx); } +#endif } if (node->is_Proj()) { diff --git a/hotspot/src/share/vm/opto/ifnode.cpp b/hotspot/src/share/vm/opto/ifnode.cpp index 073d4202f68..c6a76a853e1 100644 --- a/hotspot/src/share/vm/opto/ifnode.cpp +++ b/hotspot/src/share/vm/opto/ifnode.cpp @@ -725,6 +725,11 @@ static Node *remove_useless_bool(IfNode *iff, PhaseGVN *phase) { int true_path = phi->is_diamond_phi(); if( true_path == 0 ) return NULL; + // Make sure that iff and the control of the phi are different. This + // should really only happen for dead control flow since it requires + // an illegal cycle. + if (phi->in(0)->in(1)->in(0) == iff) return NULL; + // phi->region->if_proj->ifnode->bool->cmp BoolNode *bol2 = phi->in(0)->in(1)->in(0)->in(1)->as_Bool(); @@ -751,6 +756,7 @@ static Node *remove_useless_bool(IfNode *iff, PhaseGVN *phase) { } Node* new_bol = (flip ? phase->transform( bol2->negate(phase) ) : bol2); + assert(new_bol != iff->in(1), "must make progress"); iff->set_req(1, new_bol); // Intervening diamond probably goes dead phase->C->set_major_progress(); diff --git a/hotspot/test/compiler/6712835/Test6712835.java b/hotspot/test/compiler/6712835/Test6712835.java new file mode 100644 index 00000000000..2f1dbda198c --- /dev/null +++ b/hotspot/test/compiler/6712835/Test6712835.java @@ -0,0 +1,1578 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6712835 + * @summary Server compiler fails with assertion (loop_count < K,"infinite loop in PhaseIterGVN::transform") + * @run main/othervm -Xcomp Test6712835 + */ + +/* Complexity upper bound: 349851 ops */ + +abstract class Tester_Class_0 { + boolean var_1 = true; + static double var_2; + float var_3 = 1.8301116E38F; + final String var_4 = "wck"; + final static short var_5 = 25624; + + + public Tester_Class_0() + { + var_2 = (byte)1.7374809293839066E308; + { + double var_18 = false ? 8027040614338917376L * var_3 + - (var_2 = var_5) : (var_3 += (char)4.491494085158084E307); + var_3 *= ~ ((byte)702579792) / 6600332715431236608L; + long var_19 = 0L; + var_18 -= 1759091496; + do + { + final long var_20 = (new long[(byte)(var_3 += + +1.6695243696502334E308)][(byte)((byte)1110410742 | ~var_19)])[var_1 & var_1 ? (byte)1047514041090199552L : (byte)var_5][(byte)(var_1 ? 123309551 : - ((byte)5932930312361050112L))]; + var_19++; + final short var_21 = var_5; + } while (var_19 < 1 && var_1 ^ var_3 == + ((byte)var_5)); + { + int var_22; + } + { + var_4.endsWith("o"); + } + int var_23 = 0; + var_1 &= (var_1 = true); + for (byte var_24 = 26; (var_1 = !var_1) && var_23 < 1; var_18 += var_1 ^ (var_1 |= false) ^ true ? var_24 : (byte)1504077779675035648L) + { + var_18 *= var_23; + var_23++; + float var_25; + (((new Tester_Class_0[var_24][var_24][var_24])[var_24])[var_24 >>= var_19][var_24 &= 6702582681202665472L]).var_3 *= var_5; + } + var_1 = (var_3 -= var_5) > (byte)func_2(1317089759, var_5, (byte)var_19) % (false & true ? 475183200 : 8947159119888251904L); + var_18 /= ~var_19 ^ ((byte)(var_18 %= (int)var_5) >= 6773554922270913536L ? (byte)var_5 : (byte)'u'); + var_3 = ~ ((byte)var_19); + } + double var_26 = 0; + var_1 &= (var_1 |= ! (var_1 |= true)); + while (var_26 < 1) + { + var_2 = 'e'; + var_26++; + var_1 ^= !true | 'j' * ((var_2 = 93384362) + var_5) <= var_5; + var_2 = true ? 2056852215 : var_5; + } + switch ((new char[(byte)var_3])[(byte)(short)var_4.charAt(438929928)] / (new byte[(byte)1779353916050551808L][(byte)+ ~8903539475459755008L])[(byte)836413337621087232L][(byte)784406244]) + { + case 101: + var_3 -= var_5; + break; + + case 'L': + + case 20: + final int var_27 = 2146473580; + break; + + case 18: + + default: + "mwh".substring((byte)(float)'A' % var_5, ']' | var_5 ^ ~ ((byte)'E')); + break; + + case 'H': + + } + var_3 = var_5; + long var_28; + var_28 = (var_1 = 'u' != (var_3 = var_1 ? 1384770002488557568L : ~ ~6691557565676772352L)) ? - ((byte)938410603) : var_5; + ((new Tester_Class_0[(byte)var_26])[(byte)'w']).var_3 = (byte)(short)'I'; + var_2 = (var_1 ^= "sfltwylm".startsWith("ytmeds")) ? 1837260339 * 434565574 : (new double[(byte)var_26])[(byte)var_3]; + } + + + + public boolean equals(Object obj) + { + var_2 = 785819716 / 'i'; + switch ((! (var_1 ^= var_1) ^ (! ((false | (var_1 |= var_1)) ^ !false) ? false : (var_1 |= !false)) ? var_1 : ! !var_1 ^ var_1) ? 1426689390 : var_5 * var_5) + { + case '`': + + case 89: + + case 13: + char var_9 = 'W'; + break; + + case 31: + + case 15: + + case 'm': + var_1 &= var_1; + break; + + case 'Z': + + case 34: + String[] var_10 = (new String[(byte)5534253842608756736L][(byte)'M'])[(byte)8717534666212195328L]; + break; + + case 124: + + } + var_3 += var_5; + var_1 |= (var_1 |= (var_1 = (var_1 |= var_5 >= (var_2 = (byte)var_3)))); + var_1 ^= (var_1 = var_4.endsWith(new String())); + var_2 = (var_3 %= 664966429); + { + var_4.lastIndexOf((int)('i' * (! !true & (true & !var_1) ? (byte)2.2562587635371023E307 : (byte)(var_3 %= var_3)) / var_3), 'P' % (false ? (byte)'N' : (byte)943393108)); + } + var_3 /= false | ! !var_1 ? (char)1.3721055E38F : '\\'; + if (var_1) + { + var_4.compareTo("uaqmqwg"); + } + else + { + var_1 ^= var_1 & (var_1 &= (var_1 ^= (var_1 ^= var_1))); + } + var_3 *= (new int[(byte)1980200282][(byte)'i'])[(byte)(var_2 = (byte)'O')][false ? (byte)2.4739911E38F : (byte)- ((byte)1.6045903096088714E308)]; + var_1 = var_5 != (byte)var_5 & (1.5002759009669559E308 < (byte)5110733568033040384L ^ (var_1 ? (var_1 ^= true) : var_1)); + long var_11; + return (var_2 = (byte)'B') < 550125954; + } + + + public static char func_0(final int arg_0, long[] arg_1, final boolean arg_2) + { + var_2 = (short)(false ? (byte)1.2577737E38F : (byte)'t'); + "xdf".codePointBefore((!arg_2 ? (byte)1426638765 : (byte)541094055) * ((byte)var_5 / var_5)); + ((new Tester_Class_0[(byte)(short)(var_2 = 'A')])[(byte)arg_0]).var_3 = 7823141134226481152L; + ((new Tester_Class_0[(byte)- ~1368497135389664256L])[!false || true ? (byte)2.5393905E38F : (byte)2.4415902E38F]).var_3 -= (int)(false ? (byte)var_5 : (byte)"musnlk".charAt(785792957)); + ((new Tester_Class_0[(byte)357672172])[(byte)7.709380171237795E307]).var_3 = arg_0; + ((new Tester_Class_0[(byte)var_5])[(byte)('Z' / + + -2.6037312E38F)]).var_3 %= arg_2 ? + - - + - + +4.6761156E37F : (byte)- (var_2 = - - ~3113191255384341504L); + (("exseqpham" + "uigdxg").equalsIgnoreCase("oeutvibnv") ? "l" : "qra").replace(false ^ true ? 't' : "jwpf".charAt(+ ((byte)arg_0)), 6.624090730243228E307 > 2.7771497E38F ? 't' : "tcfesyg".charAt(arg_0)); + ((new Tester_Class_0[(byte)arg_0][(byte)6943189372481268736L])[(byte)2.6713643513095145E307][(byte)var_5]).var_1 &= !"ipgqq".endsWith("aecnyvpmf"); + ((new Tester_Class_0[(byte)(+ +2158971337956592640L ^ var_5)])[false ? (byte)8594725249859841024L : (byte)var_5]).var_3 = (byte)"jd".charAt((byte)1.6298661301128909E307 << (byte)'B'); + var_2 = (float)1014982842 * (byte)var_5 * ((new Tester_Class_0[(byte)2.7842814E38F])[(byte)"n".charAt('e' ^ (byte)arg_0)]).var_3; + if (false) + { + ((new Tester_Class_0[(byte)8.702990410251979E307][(byte)8.865924E37F])[(byte)var_5][(byte)+ ((long)var_5)]).var_1 ^= arg_2; + } + else + { + ((new Tester_Class_0[(byte)('I' | var_5)])[(byte)('L' + (+ - - (var_2 = 'N') + 1.324025E38F))]).var_3 = var_5 % '[' + (byte)var_5; + } + ((new Tester_Class_0[(byte)7.41761E37F][(byte)(var_2 = var_5)])[(byte)var_5][(byte)'o']).var_1 &= false; + ((new Tester_Class_0[(byte)+ ((byte)7.9065203E37F)])[(byte)var_5]).var_1 ^= 630582880 > - (var_2 = var_5); + return 'K'; + } + + protected float func_1(int arg_0, final Object arg_1, Object arg_2) + { + var_1 ^= (var_1 ^= true) & !var_1; + { + var_3 -= var_3; + var_2 = var_1 && (var_1 &= ! !true) | + ~3353396000385141760L < 7949306917320622080L ? (byte)306954754 : (byte)var_5; + final long var_12 = 1048994076885686272L; + } + short var_13 = 8706; + byte var_14 = (new byte[(byte)6.697464316212731E307])[(byte)var_4.indexOf("clbr", (byte)var_5 + 'F')]; + ((new Tester_Class_0[var_14][var_14 &= 'b'])[var_14][var_14]).var_1 |= var_14 >= var_3; + (((new String[var_14][var_14])[var_14])[var_14]).codePointAt(585064460); + var_14 -= 2121015302; + var_2 = 1.241922E38F; + { + (((new Tester_Class_0[var_14][var_14 ^= 'y'])[var_14])[var_14 |= var_14]).var_3 *= 5756647686007829504L; + } + { + var_13--; + } + double var_15; + var_1 = (var_1 = true) ? false : true; + arg_0--; + return var_3; + } + + public final static short func_2(int arg_0, final short arg_1, byte arg_2) + { + arg_0 %= (((new Tester_Class_0[arg_2][arg_2])[arg_2++][--arg_2]).var_1 |= true) ? 'e' : var_5 >>> arg_2; + float var_16 = ((false ? ~3951083684045828096L >>> - -3880809660598466560L : arg_0) ^ arg_1) - 1.1257035E37F; + var_2 = var_5 + 3.3679594E38F; + arg_2 += true & (((new Tester_Class_0[arg_2])[arg_2 *= 4301185995603340288L]).var_1 = arg_1 != arg_1) ? (var_2 = arg_0) : 988311987505040384L + ']' >>> --arg_2; + arg_2 = arg_2; + var_16 /= (arg_2 += (arg_0 += (var_16 %= arg_2)) + (var_16 -= arg_2)); + var_16 += 7416220016668043264L; + ((new Tester_Class_0[arg_2])[arg_2]).var_1 &= false; + ((new Tester_Class_0[--arg_2])[--arg_2]).var_1 = true | (true & true ? true : false); + arg_2 -= (var_2 = 7997355759027275776L); + ((new Tester_Class_0[arg_2])[arg_2 %= 8660960251961819136L]).var_3 *= 4180634858198604800L; + arg_0 /= -1.3063173E38F; + var_2 = arg_2; + var_2 = (6266377813429248L ^ 'j') / (!false & (1.1423139843154216E308 >= (var_2 = arg_2) || (((new Tester_Class_0[arg_2])[arg_2]).var_1 ^= true)) ? (short)('e' * arg_0) : var_5); + --arg_0; + var_2 = (+ - ~8598445599816821760L << arg_1) % 1890075208 & (!true & !true ^ false & false ? 'w' : 'm') % (5614521287604667392L / arg_2) & ~193105176465084416L; + arg_2 &= (arg_2 |= arg_0) ^ ((((new Tester_Class_0[arg_2][arg_2])[arg_2])[arg_2]).var_1 ? arg_2 : (new long[arg_2])[arg_2]); + ((new Tester_Class_0[arg_2 &= 'V'][arg_2])[arg_2 /= 5486057194586717184L][arg_2 %= var_16]).var_1 |= (new boolean[((new Tester_Class_0[arg_2])[arg_2]).var_1 ? arg_2 : arg_2])[arg_2]; + return ((((new Tester_Class_0[arg_2][arg_2][arg_2])[--arg_2])[arg_2 |= arg_2][arg_2 %= 6782653882738869248L]).var_1 ? false : !true | "hopq".equalsIgnoreCase("wvm") | "qmhtjvm".endsWith("gewqas")) && ! !false & false ? arg_1 : arg_1; + } + + protected final static char func_3(byte arg_0, final int arg_1, final short arg_2, long[] arg_3) + { + ((new Tester_Class_0[arg_0 ^= 1902924521091955712L])[arg_0]).var_1 &= ((((new Tester_Class_0[arg_0][arg_0])[--arg_0])[arg_0 *= - -1.0959788E38F]).var_1 = false); + { + var_2 = (new float[arg_0][(byte)1082004329])[arg_0][arg_0 <<= 'T']; + } + ((new Tester_Class_0[arg_0 >>= arg_1][arg_0])[arg_0][arg_0]).var_1 |= ((new Tester_Class_0[arg_0])[--arg_0]).var_4.startsWith(((new Tester_Class_0[arg_0])[arg_0]).var_4); + ((new Tester_Class_0[(byte)var_5])[arg_0]).var_4.substring(273513722, 'f' * 'n').substring((new short[arg_0][arg_0])[arg_0][arg_0] % 'C' >> (arg_3[arg_0] - 's') % ("".charAt(arg_1) & var_5)); + var_2 = 'Q' + (char)arg_0; + { + ((new Tester_Class_0[++arg_0])[arg_0]).var_1 ^= !true || !true ? !false ^ false : ! (1.7030813E38F != ~arg_0); + } + { + "jbdu".indexOf(((new Tester_Class_0[arg_0 *= 2628674024589069312L])[arg_0 -= arg_1]).var_4, "gqglwwbab".charAt(~arg_0) >>> 'M'); + } + { + --arg_0; + } + ((new Tester_Class_0[arg_0])[arg_0]).var_1 = 'n' == ('t' | (+9156142987836739584L | 's')) - 2915339344736463872L; + int var_17; + var_17 = 'k'; + var_17 = (((new Tester_Class_0[arg_0])[arg_0]).var_1 &= false) ? (short)'q' : arg_2; + return '`'; + } + + public String toString() + { + String result = "[\n"; + result += "Tester_Class_0.var_5 = "; result += Test6712835.Printer.print(var_5); + result += "\n"; + result += "Tester_Class_0.var_4 = "; result += Test6712835.Printer.print(var_4); + result += "\n"; + result += "Tester_Class_0.var_1 = "; result += Test6712835.Printer.print(var_1); + result += "\n"; + result += "Tester_Class_0.var_2 = "; result += Test6712835.Printer.print(var_2); + result += "\n"; + result += "Tester_Class_0.var_3 = "; result += Test6712835.Printer.print(var_3); + result += ""; + result += "\n]"; + return result; + } +} + + +final class Tester_Class_1 extends Tester_Class_0 { + final boolean var_29 = false; + static short var_30; + Tester_Class_0 var_31; + + + public Tester_Class_1() + { + new String(); + byte var_43 = (var_1 ? var_29 : var_1) ? (byte)(~ ~ ~6520122970162626560L | ~6642750731731981312L) : (byte)(var_30 = var_5); + { + var_2 = Tester_Class_0.var_5; + } + ((Tester_Class_0)(new Object[var_43])[var_43]).var_1 = var_29; + var_43 += 512311665; + } + + + + + final int func_0() + { + Tester_Class_0.var_2 = var_29 ? (var_29 ? (byte)'D' : (byte)Tester_Class_0.var_5) : (!var_1 ^ var_1 | (var_1 ^= var_1) ? (byte)'J' : (byte)51510881); + new String(); + new String(); + new String(); + return 1731501229; + } + + private final static void func_1(final String arg_0, final Object arg_1) + { + long var_32 = ((new Tester_Class_1[(byte)37719380])['I' == Tester_Class_0.var_5 + Tester_Class_0.var_5 ? (byte)(var_30 = (byte)1.3043569561522328E308) : (byte)1.1111420042091164E308]).var_1 ? ~2569063513521638400L - Tester_Class_0.var_5 ^ 'm' : 660383226; + ((Tester_Class_0)arg_1).var_3 += (char)8417109805993570304L; + var_30 = var_5; + var_2 = (new byte[(byte)2102078692])[(byte)7.942050823719592E307]; + if (((new Tester_Class_1[(byte)224717297])[(byte)2889830453578512384L]).var_1) + { + Tester_Class_0.var_2 = (new byte[(byte)'C'])[(byte)Tester_Class_0.var_5]; + } + else + { + var_32 <<= 'u'; + } + Tester_Class_0.var_2 = Tester_Class_0.var_5; + final Object var_33 = arg_1; + final byte var_34 = 40; + ++var_32; + (((new Tester_Class_1[var_34][var_34])[var_34][var_34]).var_31 = ((new Tester_Class_0[var_34][var_34])[var_34])[var_34]).var_1 ^= (((new Tester_Class_1[var_34][var_34])[var_34][var_34]).var_31 = (Tester_Class_0)var_33).var_1; + ((new Tester_Class_1[var_34])[var_34]).var_31 = (((new Tester_Class_1[var_34])[((new Tester_Class_1[var_34][var_34])[var_34][var_34]).var_1 ? var_34 : var_34]).var_31 = (((new Tester_Class_1[(byte)2.4941036E38F])[var_34]).var_31 = (Tester_Class_0)arg_1)); + } + + public static int[][] func_2(long arg_0, final float arg_1, short arg_2, final double arg_3) + { + long var_35; + { + arg_0++; + var_2 = true ? (byte)9.691601510156328E307 : (byte)"a".charAt(~ ((byte)arg_1)); + if (((new Tester_Class_1[(byte)'\\'][(byte)arg_2])[(byte)arg_2][(byte)arg_0]).var_29) + { + arg_2++; + } + else + { + Tester_Class_0.var_2 = arg_2; + var_30 = arg_2; + Tester_Class_0.var_2 = arg_0; + } + arg_2 /= 157487965; + arg_2 -= func_2(~ ((byte)arg_0), (short)arg_3, (byte)+2.2503214E38F); + } + arg_0--; + double var_36; + arg_0 <<= (arg_0 >>= (arg_0 = 'O')); + { + arg_0++; + --arg_0; + } + --arg_2; + ++arg_2; + "gbcrkn".length(); + var_30 = (short)7.14672E37F; + { + arg_0 %= (arg_0 >>= (arg_2 *= (byte)1.5835087622116814E308)) % arg_3; + var_36 = 'n'; + int[][] var_37 = new int[(byte)(double)arg_0][(byte)(arg_2 >>= 'o')]; + if ((byte)1390907656194158592L <= arg_2) + { + "uuoeps".indexOf("", 899321600); + } + else + { + var_36 = - ~ -arg_0; + } + short var_38 = var_5; + var_36 = ~arg_0 + (6482428938632186880L + 6995927649252739072L); + } + if (((new Tester_Class_1[(byte)arg_1][(byte)arg_2])[(new byte[(byte)arg_0])[(byte)var_5]][(byte)'s']).var_1 = false) + { + ++arg_0; + } + else + { + ((new Tester_Class_1[(byte)2.7176027E38F])[(byte)((arg_2 -= 2.595396436487417E307) % 'p')]).var_1 ^= ((new Tester_Class_1[(byte)4.393706E36F])[false ? (byte)4826960994531808256L : (byte)arg_0]).var_29; + } + int var_39 = 0; + arg_2 <<= 'Y'; + while (var_39 < 1 && false) + { + arg_0++; + var_39++; + Object var_40; + ((Tester_Class_0)(var_40 = new long[(byte)3.285531E38F])).var_3 += var_39; + } + Object var_41; + "w".substring(1359453539); + return new int[(byte)((arg_2 /= 4.143015135482291E307) - 3.2659622E38F)][(byte)++arg_2]; + } + + public String toString() + { + String result = "[\n"; + result += "Tester_Class_1.var_5 = "; result += Test6712835.Printer.print(var_5); + result += "\n"; + result += "Tester_Class_1.var_30 = "; result += Test6712835.Printer.print(var_30); + result += "\n"; + result += "Tester_Class_1.var_4 = "; result += Test6712835.Printer.print(var_4); + result += "\n"; + result += "Tester_Class_1.var_1 = "; result += Test6712835.Printer.print(var_1); + result += "\n"; + result += "Tester_Class_1.var_29 = "; result += Test6712835.Printer.print(var_29); + result += "\n"; + result += "Tester_Class_1.var_2 = "; result += Test6712835.Printer.print(var_2); + result += "\n"; + result += "Tester_Class_1.var_3 = "; result += Test6712835.Printer.print(var_3); + result += "\n"; + result += "Tester_Class_1.var_31 = "; result += Test6712835.Printer.print(var_31); + result += ""; + result += "\n]"; + return result; + } +} + + +final class Tester_Class_2 extends Tester_Class_0 { + static float var_44 = 2.7867988E38F; + static byte var_45; + static long var_46 = 4319798868443575296L; + + + public Tester_Class_2() + { + Tester_Class_1.var_30 = (byte)3.1718026E38F; + var_45 = (new byte[(byte)'o'])[var_45 = (byte)Tester_Class_0.var_5]; + Tester_Class_1.var_30 = (Tester_Class_1.var_30 = Tester_Class_0.var_5); + if (true) + { + ++var_46; + boolean var_51 = false ? (var_1 &= !var_1) : true; + --var_46; + if (false) + { + var_3 *= 6.882788442363403E307; + } + else + { + Tester_Class_0.var_2 = '`'; + } + final float var_52 = (var_1 ^= var_1 || (var_1 &= false)) | (var_51 |= (var_51 &= false)) ? (byte)4.751813848964725E307 : (var_3 *= var_5); + (false ? var_4 : var_4).startsWith("j" + var_4); + var_46++; + var_3 %= Tester_Class_1.var_5; + } + else + { + Tester_Class_1.var_30 = (var_45 = (var_45 = (var_45 = (byte)Tester_Class_1.var_5))); + Tester_Class_1.var_2 = (var_3 -= ~ ((byte)var_46) - 2018787280); + Tester_Class_1.var_30 = (Tester_Class_1.var_30 = (Tester_Class_1.var_30 = (Tester_Class_1.var_30 = var_5))); + } + char var_53; + ++var_46; + short var_54 = 138; + ++var_46; + var_2 = 1435782089; + Tester_Class_0.var_2 = var_46; + } + + + + + protected final boolean func_0(final boolean arg_0, final boolean arg_1) + { + var_2 = 2.6153986361247174E307; + var_45 = (var_45 = (var_45 = (var_45 = (var_45 = (byte)(var_44 += var_46))))); + var_46++; + long var_47 = 0L; + var_3 -= + ((byte)(~var_46 * ~var_46 ^ var_46 % 1910419567)); + do + { + ++var_46; + var_47++; + char var_48 = 'b'; + } while (var_47 < 2); + new Tester_Class_1().var_31 = ((new Tester_Class_1[var_45 = (byte)3.0853839E38F])[(new byte[var_45 = (byte)1.4974966426791287E308])[var_45 = (byte)Tester_Class_0.var_5]]).var_1 ? new Tester_Class_1() : new Tester_Class_1(); + var_45 = (var_45 = (byte)var_44); + double var_49 = 0; + var_45 = (byte)(Tester_Class_1.var_30 = Tester_Class_0.var_5); + while (((false ^ (var_1 &= var_1) | (var_1 |= arg_0) ? new Tester_Class_1() : new Tester_Class_1()).var_29 ? var_1 : false && (var_1 ^= arg_0)) && (var_49 < 3 && (true ? new Tester_Class_1() : new Tester_Class_1()).var_1)) + { + var_45 = (var_45 = (var_45 = (var_45 = (var_45 = (byte)1.933612E38F)))); + var_49++; + var_45 = (var_45 = (var_45 = (var_45 = (byte)685709636))); + long var_50; + } + var_45 = (var_45 = (var_45 = (byte)var_5)); + var_46--; + return true; + } + + public String toString() + { + String result = "[\n"; + result += "Tester_Class_2.var_46 = "; result += Test6712835.Printer.print(var_46); + result += "\n"; + result += "Tester_Class_2.var_2 = "; result += Test6712835.Printer.print(var_2); + result += "\n"; + result += "Tester_Class_2.var_3 = "; result += Test6712835.Printer.print(var_3); + result += "\n"; + result += "Tester_Class_2.var_44 = "; result += Test6712835.Printer.print(var_44); + result += "\n"; + result += "Tester_Class_2.var_5 = "; result += Test6712835.Printer.print(var_5); + result += "\n"; + result += "Tester_Class_2.var_45 = "; result += Test6712835.Printer.print(var_45); + result += "\n"; + result += "Tester_Class_2.var_4 = "; result += Test6712835.Printer.print(var_4); + result += "\n"; + result += "Tester_Class_2.var_1 = "; result += Test6712835.Printer.print(var_1); + result += ""; + result += "\n]"; + return result; + } +} + + +class Tester_Class_3 extends Tester_Class_0 { + static boolean var_55 = true; + short var_56; + char var_57 = (char)723612093; + final static byte var_58 = 118; + static float var_59 = true ? -2818156175448416256L : - - (Tester_Class_2.var_44 += var_58); + static Tester_Class_1 var_60; + byte var_61 = 112; + Tester_Class_2[] var_62; + static short var_63 = 19813; + static double var_64 = (var_55 = true) ? (Tester_Class_1.var_2 = 'M') : Tester_Class_2.var_46; + + + public Tester_Class_3() + { + var_56 = var_58; + Tester_Class_1 var_65 = var_60 = (var_60 = (var_60 = (new Tester_Class_1[var_61 |= '\\'])[(var_1 = true) || var_55 ? var_58 : var_61])); + var_64 /= 1253632965 * '`'; + Tester_Class_2.var_46 >>>= var_58; + (((var_61 = var_58) * (var_55 ? 1641980027 : var_63) >= 1490788063 ? var_65 : var_65).var_29 ? var_65 : var_65).var_31 = (new Tester_Class_2[var_58])[var_58]; + ++var_63; + new String(); + var_64 += var_55 ? (var_61 >>>= 'Q') : (var_63 <<= var_57); + ((new Tester_Class_2().var_3 >= Tester_Class_2.var_46 ? !var_55 : var_4.startsWith(var_4, 586086925)) ? "gjsdhuop" : "juqrt").substring(("pm" + ((new Tester_Class_2[var_61][var_58])[var_58][var_58]).var_4).codePointBefore((~var_61 << 3032688286897486848L) - Tester_Class_1.var_5), (var_61 += 4.0796373033184064E306) >> (Tester_Class_2.var_46 >>> var_58)); + var_63 -= (var_63 ^= var_57); + var_64 = var_5 - (Tester_Class_2.var_46 *= var_57); + Tester_Class_2.var_46 &= 7544159045139005440L; + var_55 |= false; + Tester_Class_2.var_46 = var_61; + } + + + + + public String toString() + { + String result = "[\n"; + result += "Tester_Class_3.var_57 = "; result += Test6712835.Printer.print(var_57); + result += "\n"; + result += "Tester_Class_3.var_62 = "; result += Test6712835.Printer.print(var_62); + result += "\n"; + result += "Tester_Class_3.var_2 = "; result += Test6712835.Printer.print(var_2); + result += "\n"; + result += "Tester_Class_3.var_64 = "; result += Test6712835.Printer.print(var_64); + result += "\n"; + result += "Tester_Class_3.var_3 = "; result += Test6712835.Printer.print(var_3); + result += "\n"; + result += "Tester_Class_3.var_59 = "; result += Test6712835.Printer.print(var_59); + result += "\n"; + result += "Tester_Class_3.var_5 = "; result += Test6712835.Printer.print(var_5); + result += "\n"; + result += "Tester_Class_3.var_56 = "; result += Test6712835.Printer.print(var_56); + result += "\n"; + result += "Tester_Class_3.var_63 = "; result += Test6712835.Printer.print(var_63); + result += "\n"; + result += "Tester_Class_3.var_58 = "; result += Test6712835.Printer.print(var_58); + result += "\n"; + result += "Tester_Class_3.var_61 = "; result += Test6712835.Printer.print(var_61); + result += "\n"; + result += "Tester_Class_3.var_4 = "; result += Test6712835.Printer.print(var_4); + result += "\n"; + result += "Tester_Class_3.var_1 = "; result += Test6712835.Printer.print(var_1); + result += "\n"; + result += "Tester_Class_3.var_55 = "; result += Test6712835.Printer.print(var_55); + result += "\n"; + result += "Tester_Class_3.var_60 = "; result += Test6712835.Printer.print(var_60); + result += ""; + result += "\n]"; + return result; + } +} + + +final class Tester_Class_4 { + static long var_66; + final long var_67 = 7113579489152300032L * 985636454; + int[] var_68; + Tester_Class_3 var_69; + final long var_70 = Tester_Class_2.var_46 <<= Tester_Class_1.var_5; + byte var_71 = Tester_Class_3.var_58; + + + public Tester_Class_4() + { + Tester_Class_2.var_46++; + (var_69 = new Tester_Class_3()).var_61 += (!true | (Tester_Class_3.var_55 ^= Tester_Class_3.var_55) ? new Tester_Class_3() : new Tester_Class_3()).var_61; + final String[][] var_79 = new String[var_71 >>= (Tester_Class_3.var_63 ^= 'm')][((Tester_Class_3)(new Tester_Class_1().var_31 = new Tester_Class_2())).var_61 >>= (var_71 >>>= (Tester_Class_2.var_46 += 465205188010511360L))]; + ++(var_69 = (var_69 = (var_69 = (Tester_Class_3)(new Object[Tester_Class_3.var_58][var_71])[Tester_Class_3.var_58][var_71]))).var_61; + (((new Tester_Class_2[var_71][Tester_Class_3.var_58])[Tester_Class_2.var_45 = var_71])[var_71]).var_3 += (Tester_Class_2.var_46 <<= (Tester_Class_2.var_46 /= 9.03047405760868E307) >> (new Tester_Class_2().var_1 ? 2099696051 : Tester_Class_3.var_63)); + Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = new Tester_Class_1()))); + char var_80; + Tester_Class_3.var_64 += 355712574; + ++Tester_Class_2.var_46; + } + + + + + private final static Tester_Class_1 func_0(boolean arg_0, double arg_1) + { + Tester_Class_3.var_60 = (Tester_Class_3.var_60 = new Tester_Class_1()); + byte var_72 = (byte)Tester_Class_2.var_46; + Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = new Tester_Class_1())))); + float var_73 = 0F; + "flfix".offsetByCodePoints((Tester_Class_3.var_63 ^= 3286104714651747328L) + ((Tester_Class_3)(new Tester_Class_0[var_72])[var_72]).var_61, Tester_Class_0.var_5 + Tester_Class_3.var_58); + while (var_73 < 2 && (false ? (Tester_Class_3.var_60 = new Tester_Class_1()) : (Tester_Class_1)(new Tester_Class_0[var_72])[var_72]).var_29) + { + ((Tester_Class_3)(Tester_Class_0)(new Object[var_72])[Tester_Class_3.var_58]).var_61 >>= ((new Tester_Class_4[var_72])[var_72]).var_67; + var_73++; + new String("blod"); + --var_72; + } + ((new Tester_Class_4[Tester_Class_3.var_58][var_72])[new Tester_Class_3().var_61][Tester_Class_3.var_58]).var_69 = new Tester_Class_3(); + float var_74 = (! ("dkcx".lastIndexOf(Tester_Class_1.var_5 >> - (var_72 >>>= 1433506903139345408L)) == Tester_Class_2.var_46) ? 'O' : 'e' - new Tester_Class_2().var_3) * ~ (var_72 ^= var_72); + Tester_Class_3.var_60 = !true ? new Tester_Class_1() : (new Tester_Class_1[Tester_Class_3.var_58])[var_72]; + ((arg_0 &= Tester_Class_3.var_55 | (Tester_Class_3.var_60 = new Tester_Class_1()).var_29) ? (Tester_Class_3.var_60 = (Tester_Class_1)(new Tester_Class_1().var_31 = new Tester_Class_2())) : (Tester_Class_3.var_60 = (new Tester_Class_1[var_72])[Tester_Class_3.var_58])).var_31 = (new Tester_Class_3[var_72 |= 546982927])[Tester_Class_3.var_58]; + long var_75 = 0L; + final double var_76 = +arg_1; + while (var_75 < 1) + { + short var_77; + var_75++; + new Tester_Class_3().var_57 = (false & true ? new Tester_Class_3() : new Tester_Class_3()).var_57; + (Tester_Class_3.var_60 = (new Tester_Class_1[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_31 = (new Tester_Class_2[Tester_Class_3.var_58][var_72])[var_72][var_72]; + } + Tester_Class_3.var_64 *= (arg_0 ? (Tester_Class_3.var_55 ^= (arg_0 ^= arg_0)) & ! (Tester_Class_3.var_55 = arg_0) : arg_0) ^ new Tester_Class_1().var_29 ? ++((new Tester_Class_3[var_72][var_72])[(new byte[Tester_Class_3.var_58])[Tester_Class_3.var_58]][(((new Tester_Class_4[var_72][Tester_Class_3.var_58])[Tester_Class_3.var_58][Tester_Class_3.var_58]).var_69 = (new Tester_Class_3[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_61]).var_57 : 'C'; + long var_78; + var_74 %= (Tester_Class_3.var_55 |= (arg_0 = (arg_0 ^= (arg_0 &= !arg_0)))) ? new Tester_Class_3().var_61 : (Tester_Class_3.var_63 ^= var_72); + arg_1 /= (Tester_Class_2.var_46 &= 'W'); + --(((new Tester_Class_4[var_72])[var_72]).var_69 = (((new Tester_Class_4[var_72])[var_72]).var_69 = new Tester_Class_3())).var_61; + return (new Tester_Class_1[var_72][Tester_Class_3.var_58])[var_72][new Tester_Class_3().var_61]; + } + + public String toString() + { + String result = "[\n"; + result += "Tester_Class_4.var_68 = "; result += Test6712835.Printer.print(var_68); + result += "\n"; + result += "Tester_Class_4.var_66 = "; result += Test6712835.Printer.print(var_66); + result += "\n"; + result += "Tester_Class_4.var_67 = "; result += Test6712835.Printer.print(var_67); + result += "\n"; + result += "Tester_Class_4.var_70 = "; result += Test6712835.Printer.print(var_70); + result += "\n"; + result += "Tester_Class_4.var_71 = "; result += Test6712835.Printer.print(var_71); + result += "\n"; + result += "Tester_Class_4.var_69 = "; result += Test6712835.Printer.print(var_69); + result += ""; + result += "\n]"; + return result; + } +} + + +final class Tester_Class_5 extends Tester_Class_0 { + static boolean var_81; + final int var_82 = 174395841; + int var_83; + byte var_84; + boolean var_85 = Tester_Class_3.var_55; + static boolean var_86 = Tester_Class_3.var_55; + + + public Tester_Class_5() + { + { + short var_87 = (new short[Tester_Class_3.var_58][var_84 = Tester_Class_3.var_58])[(((new Tester_Class_4[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_69 = (Tester_Class_3)(Tester_Class_0)(new Object[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_61][Tester_Class_3.var_58]; + Tester_Class_4 var_88 = var_85 ^ (var_81 = false) ? (new Tester_Class_4[Tester_Class_3.var_58])[Tester_Class_3.var_58] : (new Tester_Class_4[Tester_Class_3.var_58])[Tester_Class_3.var_58]; + { + ++var_87; + } + short var_89; + (var_88.var_69 = (new Tester_Class_3[var_88.var_71][var_88.var_71])[var_88.var_71][var_88.var_71]).var_61 += (((Tester_Class_2)(new Tester_Class_1().var_31 = new Tester_Class_2())).var_3 = Tester_Class_3.var_58); + var_88 = var_88; + } + { + ++Tester_Class_2.var_46; + --Tester_Class_2.var_46; + } + { + Tester_Class_2.var_46++; + Tester_Class_3.var_64 /= Tester_Class_3.var_59; + ((Tester_Class_4)(new Object[Tester_Class_2.var_45 = Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_71 %= (var_3 /= 3637233239489444864L); + ++Tester_Class_2.var_46; + } + new Tester_Class_3().var_57++; + var_85 &= (Tester_Class_3.var_55 |= false); + Tester_Class_3.var_60 = new Tester_Class_1(); + Tester_Class_2.var_46++; + ((Tester_Class_3)(true ? (new Tester_Class_2[Tester_Class_3.var_58])[Tester_Class_3.var_58] : (new Tester_Class_0[Tester_Class_3.var_58])[Tester_Class_2.var_45 = Tester_Class_3.var_58])).var_57 *= ((new Tester_Class_3[Tester_Class_3.var_58])[(byte)'`']).var_57; + var_3 += (int)Tester_Class_3.var_59 ^ (Tester_Class_2.var_46 -= Tester_Class_2.var_46) % ~((new Tester_Class_4[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_71; + ++Tester_Class_2.var_46; + --Tester_Class_2.var_46; + var_83 = Tester_Class_3.var_58; + } + + + + + public String toString() + { + String result = "[\n"; + result += "Tester_Class_5.var_82 = "; result += Test6712835.Printer.print(var_82); + result += "\n"; + result += "Tester_Class_5.var_83 = "; result += Test6712835.Printer.print(var_83); + result += "\n"; + result += "Tester_Class_5.var_2 = "; result += Test6712835.Printer.print(var_2); + result += "\n"; + result += "Tester_Class_5.var_3 = "; result += Test6712835.Printer.print(var_3); + result += "\n"; + result += "Tester_Class_5.var_5 = "; result += Test6712835.Printer.print(var_5); + result += "\n"; + result += "Tester_Class_5.var_84 = "; result += Test6712835.Printer.print(var_84); + result += "\n"; + result += "Tester_Class_5.var_4 = "; result += Test6712835.Printer.print(var_4); + result += "\n"; + result += "Tester_Class_5.var_1 = "; result += Test6712835.Printer.print(var_1); + result += "\n"; + result += "Tester_Class_5.var_81 = "; result += Test6712835.Printer.print(var_81); + result += "\n"; + result += "Tester_Class_5.var_85 = "; result += Test6712835.Printer.print(var_85); + result += "\n"; + result += "Tester_Class_5.var_86 = "; result += Test6712835.Printer.print(var_86); + result += ""; + result += "\n]"; + return result; + } +} + + +class Tester_Class_6 extends Tester_Class_0 { + long var_90 = 8467263472031702016L; + final static int var_91 = 1648594448 * ']'; + char var_92 = 'x'; + short var_93 = Tester_Class_3.var_63; + Tester_Class_4 var_94; + String[] var_95; + static short var_96 = Tester_Class_3.var_63 -= 83376045 << 40225606; + final static double var_97 = 5.387227213380301E307; + final static short var_98 = Tester_Class_3.var_63 &= var_91; + byte var_99 = 44; + + + public Tester_Class_6() + { + (Tester_Class_3.var_60 = (Tester_Class_1)(new Object[Tester_Class_3.var_58][var_99])[Tester_Class_3.var_58][var_99]).var_31 = true | true ? (Tester_Class_5)(new Object[var_99])[Tester_Class_3.var_58] : (Tester_Class_5)(new Object[Tester_Class_3.var_58])[var_99]; + var_92 &= 'p'; + Tester_Class_5.var_81 = (((new Tester_Class_1[var_99][Tester_Class_3.var_58])[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_29; + { + { + ++Tester_Class_2.var_46; + Tester_Class_3.var_2 = var_98; + var_93 -= var_96; + } + Tester_Class_2.var_46--; + { + (var_5 == (((Tester_Class_3)(new Tester_Class_0[var_99])[Tester_Class_3.var_58]).var_61 /= var_5) ? "fsajxeuao".replace('s', 'K') : var_4).substring('e' >>> var_5).toLowerCase(); + } + var_93 %= ((new Tester_Class_6[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_90; + var_93 /= var_93; + if (Tester_Class_5.var_86) + { + (var_94 = (new Tester_Class_4[var_99])[var_99]).var_69 = (new Tester_Class_3[var_99])[var_99 %= -var_90]; + } + else + { + --var_96; + } + var_93 *= 'O'; + final long var_103 = 7573900518735055872L; + --Tester_Class_3.var_63; + } + Tester_Class_3.var_64 /= var_93; + if (true) + { + --Tester_Class_2.var_46; + Tester_Class_5 var_104; + final double var_105 = Tester_Class_3.var_64 += Tester_Class_5.var_86 & (new Tester_Class_2().var_1 & ((Tester_Class_3.var_55 = (var_1 ^= Tester_Class_5.var_86) & false) & (Tester_Class_5.var_81 = Tester_Class_5.var_86))) ? (byte)'g' : var_99; + Tester_Class_3.var_64 *= var_99; + } + else + { + char var_106 = var_92 -= Tester_Class_3.var_58; + } + double[] var_107 = ((new double[Tester_Class_3.var_58][var_99][var_99])[var_99])[false ? Tester_Class_3.var_58 : Tester_Class_3.var_58]; + var_99 <<= (Tester_Class_3.var_63 >>= Tester_Class_3.var_58); + ++var_99; + } + + + + + final static byte func_0(final byte arg_0, final char arg_1, final Tester_Class_5[] arg_2) + { + ((Tester_Class_4)(new Object[Tester_Class_3.var_58][Tester_Class_3.var_58])[Tester_Class_3.var_58][arg_0]).var_69 = (Tester_Class_3)(new Tester_Class_0[Tester_Class_3.var_58])[Tester_Class_2.var_45 = Tester_Class_3.var_58]; + long var_100 = 0L; + Tester_Class_3.var_64 /= (Tester_Class_5.var_86 = true) || 'o' > (Tester_Class_3.var_63 -= (float)arg_0) ? var_98 : 1.7875238E38F; + do + { + Tester_Class_3.var_64 %= var_5; + var_100++; + Tester_Class_3.var_64 += var_96 + 'r'; + } while (true && (var_100 < 1 && (new Tester_Class_1().var_29 ? new Tester_Class_1() : (new Tester_Class_1[arg_0][Tester_Class_3.var_58])[arg_0][Tester_Class_3.var_58]).var_29)); + (Tester_Class_3.var_55 ^ (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = new Tester_Class_1()))).var_29 ? new Tester_Class_3() : new Tester_Class_3()).var_57 = ((((new Tester_Class_6[Tester_Class_3.var_58][Tester_Class_3.var_58])[Tester_Class_3.var_58][Tester_Class_3.var_58]).var_94 = (((new Tester_Class_6[Tester_Class_3.var_58][Tester_Class_3.var_58])[Tester_Class_3.var_58][arg_0]).var_94 = (new Tester_Class_4[Tester_Class_3.var_58][arg_0])[Tester_Class_3.var_58][Tester_Class_3.var_58])).var_69 = new Tester_Class_3()).var_57; + final double var_101 = 1.6798216578519203E308; + Tester_Class_3.var_60 = (Tester_Class_3.var_60 = false ? new Tester_Class_1() : (Tester_Class_3.var_60 = new Tester_Class_1())); + Tester_Class_2 var_102 = new Tester_Class_2(); + return Tester_Class_3.var_58; + } + + public String toString() + { + String result = "[\n"; + result += "Tester_Class_6.var_92 = "; result += Test6712835.Printer.print(var_92); + result += "\n"; + result += "Tester_Class_6.var_91 = "; result += Test6712835.Printer.print(var_91); + result += "\n"; + result += "Tester_Class_6.var_95 = "; result += Test6712835.Printer.print(var_95); + result += "\n"; + result += "Tester_Class_6.var_90 = "; result += Test6712835.Printer.print(var_90); + result += "\n"; + result += "Tester_Class_6.var_2 = "; result += Test6712835.Printer.print(var_2); + result += "\n"; + result += "Tester_Class_6.var_97 = "; result += Test6712835.Printer.print(var_97); + result += "\n"; + result += "Tester_Class_6.var_3 = "; result += Test6712835.Printer.print(var_3); + result += "\n"; + result += "Tester_Class_6.var_5 = "; result += Test6712835.Printer.print(var_5); + result += "\n"; + result += "Tester_Class_6.var_93 = "; result += Test6712835.Printer.print(var_93); + result += "\n"; + result += "Tester_Class_6.var_96 = "; result += Test6712835.Printer.print(var_96); + result += "\n"; + result += "Tester_Class_6.var_98 = "; result += Test6712835.Printer.print(var_98); + result += "\n"; + result += "Tester_Class_6.var_99 = "; result += Test6712835.Printer.print(var_99); + result += "\n"; + result += "Tester_Class_6.var_4 = "; result += Test6712835.Printer.print(var_4); + result += "\n"; + result += "Tester_Class_6.var_1 = "; result += Test6712835.Printer.print(var_1); + result += "\n"; + result += "Tester_Class_6.var_94 = "; result += Test6712835.Printer.print(var_94); + result += ""; + result += "\n]"; + return result; + } +} + + +abstract class Tester_Class_7 { + final static char var_108 = '_'; + static Tester_Class_3 var_109; + final short var_110 = 4360; + short var_111; + Object var_112; + Tester_Class_4 var_113; + static Tester_Class_5 var_114; + final short var_115 = Tester_Class_6.var_96; + final static float var_116 = Tester_Class_3.var_59; + + + public Tester_Class_7() + { + --Tester_Class_2.var_46; + --Tester_Class_6.var_96; + var_113 = (new Tester_Class_4[new Tester_Class_6().var_99])[Tester_Class_3.var_58]; + --Tester_Class_2.var_46; + Tester_Class_6.var_96--; + Tester_Class_3.var_63 -= 'i'; + if (!Tester_Class_5.var_86) + { + Tester_Class_3.var_64 %= var_116; + if ((Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)(Tester_Class_0)(var_112 = "yosyghjm"))).var_29) + { + Tester_Class_2.var_46++; + } + else + { + (var_114 = (var_114 = (Tester_Class_5)(Tester_Class_0)(var_112 = "bxt"))).var_83 = (Tester_Class_2.var_45 = (Tester_Class_2.var_45 = Tester_Class_3.var_58)); + } + var_114 = (var_114 = (var_114 = (var_114 = (var_114 = (var_114 = (Tester_Class_5)(var_112 = "blrobgg")))))); + var_113 = (((Tester_Class_6)(var_112 = "popebwfp")).var_94 = (new Tester_Class_4[Tester_Class_3.var_58])[Tester_Class_3.var_58]); + } + else + { + Tester_Class_3.var_60 = new Tester_Class_1(); + } + final Tester_Class_6 var_122 = new Tester_Class_6(); + var_122.var_92 &= (var_122.var_92 |= var_108); + ((new Tester_Class_5[var_122.var_99])[((new Tester_Class_3[Tester_Class_3.var_58])[var_122.var_99--]).var_61]).var_83 = 1708230145; + } + + + + public boolean equals(Object obj) + { + (((Tester_Class_5.var_81 = (Tester_Class_5.var_81 = false)) ? (Tester_Class_3.var_55 &= false) : !Tester_Class_3.var_55 & ((Tester_Class_1)obj).var_29) ? (new Tester_Class_2[Tester_Class_3.var_58])[Tester_Class_3.var_58] : (Tester_Class_2)obj).equals((Tester_Class_5.var_86 |= Tester_Class_3.var_55) | (Tester_Class_3.var_55 = Tester_Class_3.var_55) ? obj : (Tester_Class_6)(Tester_Class_0)obj); + Tester_Class_3.var_64 *= 2.8258473339654136E307; + { + final int var_118 = 1248523063; + short var_119 = 30906; + Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)obj); + ((Tester_Class_6)(((Tester_Class_1)obj).var_31 = ((var_113 = (Tester_Class_4)obj).var_69 = (Tester_Class_3)obj))).var_94 = (var_113 = (Tester_Class_4)(var_112 = (Tester_Class_1)obj)); + } + final Tester_Class_1 var_120 = false ^ (((Tester_Class_1)obj).var_1 = !true) ^ (((Tester_Class_6)(Tester_Class_0)obj).var_92 *= (((Tester_Class_3)obj).var_57 |= (Tester_Class_2.var_46 >>= 6986775136305733632L))) < (byte)Tester_Class_6.var_97 ? (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)obj)) : (true ? (Tester_Class_1)obj : (Tester_Class_1)obj); + (var_114 = (var_114 = (Tester_Class_5)obj)).var_83 = (((new Tester_Class_6[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_92 &= ((Tester_Class_4)obj).var_70 << (Tester_Class_2.var_45 = Tester_Class_3.var_58)); + var_114 = (Tester_Class_5)obj; + obj = ((Tester_Class_3.var_60 = var_120).var_29 ? false : false) ? (new Tester_Class_6[Tester_Class_3.var_58])[Tester_Class_3.var_58] : obj; + (var_120.var_29 ? (Tester_Class_6)(obj = (Tester_Class_3.var_60 = var_120)) : (new Tester_Class_6[Tester_Class_3.var_58])[((Tester_Class_3)obj).var_61 ^= Tester_Class_6.var_91]).var_90 ^= 2127530040436251648L; + Object var_121; + return (new boolean[Tester_Class_3.var_58])[((var_113 = (Tester_Class_4)obj).var_69 = (var_109 = (new Tester_Class_3[Tester_Class_3.var_58][Tester_Class_3.var_58])[Tester_Class_3.var_58][Tester_Class_3.var_58])).var_61]; + } + + + public String toString() + { + String result = "[\n"; + result += "Tester_Class_7.var_108 = "; result += Test6712835.Printer.print(var_108); + result += "\n"; + result += "Tester_Class_7.var_116 = "; result += Test6712835.Printer.print(var_116); + result += "\n"; + result += "Tester_Class_7.var_110 = "; result += Test6712835.Printer.print(var_110); + result += "\n"; + result += "Tester_Class_7.var_111 = "; result += Test6712835.Printer.print(var_111); + result += "\n"; + result += "Tester_Class_7.var_115 = "; result += Test6712835.Printer.print(var_115); + result += "\n"; + result += "Tester_Class_7.var_114 = "; result += Test6712835.Printer.print(var_114); + result += "\n"; + result += "Tester_Class_7.var_113 = "; result += Test6712835.Printer.print(var_113); + result += "\n"; + result += "Tester_Class_7.var_109 = "; result += Test6712835.Printer.print(var_109); + result += "\n"; + result += "Tester_Class_7.var_112 = "; result += Test6712835.Printer.print(var_112); + result += ""; + result += "\n]"; + return result; + } +} + + +class Tester_Class_8 extends Tester_Class_7 { + static char var_123; + Tester_Class_4 var_124; + static short var_125; + + + public Tester_Class_8() + { + { + Tester_Class_3.var_64 -= (Tester_Class_2.var_46 *= Tester_Class_3.var_64); + { + Tester_Class_2.var_46--; + } + ++Tester_Class_3.var_63; + Tester_Class_5.var_86 |= true; + Tester_Class_6.var_96--; + } + "w".indexOf(312689020); + if (false) + { + (Tester_Class_7.var_114 = (new Tester_Class_5[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_83 = 'I'; + } + else + { + --Tester_Class_6.var_96; + } + switch (Tester_Class_5.var_86 ? Tester_Class_3.var_58 : Tester_Class_3.var_58) + { + case 95: + + case 35: + + } + Tester_Class_6.var_96--; + Tester_Class_3.var_64 *= 4.516167673347119E307; + --Tester_Class_3.var_63; + { + int var_126; + } + Tester_Class_3.var_60 = new Tester_Class_1(); + Tester_Class_2.var_46++; + ((new Tester_Class_6[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_99 &= Tester_Class_6.var_91; + ((new Tester_Class_1[((new Tester_Class_4[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_71])[((Tester_Class_3)(var_112 = "fsmtm")).var_61]).var_31 = (Tester_Class_2)(new Tester_Class_0[Tester_Class_3.var_58])[Tester_Class_3.var_58]; + } + + + + + public String toString() + { + String result = "[\n"; + result += "Tester_Class_8.var_108 = "; result += Test6712835.Printer.print(var_108); + result += "\n"; + result += "Tester_Class_8.var_123 = "; result += Test6712835.Printer.print(var_123); + result += "\n"; + result += "Tester_Class_8.var_116 = "; result += Test6712835.Printer.print(var_116); + result += "\n"; + result += "Tester_Class_8.var_110 = "; result += Test6712835.Printer.print(var_110); + result += "\n"; + result += "Tester_Class_8.var_111 = "; result += Test6712835.Printer.print(var_111); + result += "\n"; + result += "Tester_Class_8.var_115 = "; result += Test6712835.Printer.print(var_115); + result += "\n"; + result += "Tester_Class_8.var_125 = "; result += Test6712835.Printer.print(var_125); + result += "\n"; + result += "Tester_Class_8.var_114 = "; result += Test6712835.Printer.print(var_114); + result += "\n"; + result += "Tester_Class_8.var_113 = "; result += Test6712835.Printer.print(var_113); + result += "\n"; + result += "Tester_Class_8.var_124 = "; result += Test6712835.Printer.print(var_124); + result += "\n"; + result += "Tester_Class_8.var_109 = "; result += Test6712835.Printer.print(var_109); + result += "\n"; + result += "Tester_Class_8.var_112 = "; result += Test6712835.Printer.print(var_112); + result += ""; + result += "\n]"; + return result; + } +} + + +final class Tester_Class_9 { + final static String var_127 = "pxk"; + Tester_Class_2 var_128; + final static char var_129 = '\\'; + static float var_130; + static boolean var_131; + final static float var_132 = Tester_Class_3.var_59; + static Tester_Class_0 var_133; + boolean[] var_134; + + + public Tester_Class_9() + { + Tester_Class_2.var_44 -= Tester_Class_3.var_58; + Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (new Tester_Class_1[Tester_Class_3.var_58][Tester_Class_3.var_58])[Tester_Class_3.var_58][Tester_Class_3.var_58])); + { + Tester_Class_8 var_136; + } + ++Tester_Class_2.var_46; + Tester_Class_6.var_96--; + var_128 = (var_128 = (var_128 = (Tester_Class_2)(var_133 = (new Tester_Class_1[Tester_Class_3.var_58])[Tester_Class_3.var_58]))); + ++Tester_Class_6.var_96; + ++Tester_Class_2.var_46; + Tester_Class_4 var_137; + var_128 = (var_128 = (new Tester_Class_2[Tester_Class_3.var_58])[Tester_Class_3.var_58]); + (Tester_Class_8.var_114 = (Tester_Class_8.var_114 = (new Tester_Class_5[Tester_Class_3.var_58])[Tester_Class_3.var_58])).var_83 = (((new Tester_Class_4[Tester_Class_3.var_58][Tester_Class_3.var_58])[Tester_Class_3.var_58][Tester_Class_3.var_58]).var_69 = (new Tester_Class_3[Tester_Class_3.var_58][Tester_Class_3.var_58])[Tester_Class_3.var_58][Tester_Class_3.var_58]).var_57++; + Tester_Class_2.var_46++; + } + + + + + protected static short func_1() + { + { + Tester_Class_3.var_63--; + } + Tester_Class_3.var_64 *= Tester_Class_2.var_46; + short var_135; + Tester_Class_3.var_64 -= Tester_Class_6.var_96; + return new Tester_Class_6().var_93; + } + + public String toString() + { + String result = "[\n"; + result += "Tester_Class_9.var_129 = "; result += Test6712835.Printer.print(var_129); + result += "\n"; + result += "Tester_Class_9.var_134 = "; result += Test6712835.Printer.print(var_134); + result += "\n"; + result += "Tester_Class_9.var_130 = "; result += Test6712835.Printer.print(var_130); + result += "\n"; + result += "Tester_Class_9.var_132 = "; result += Test6712835.Printer.print(var_132); + result += "\n"; + result += "Tester_Class_9.var_131 = "; result += Test6712835.Printer.print(var_131); + result += "\n"; + result += "Tester_Class_9.var_127 = "; result += Test6712835.Printer.print(var_127); + result += "\n"; + result += "Tester_Class_9.var_128 = "; result += Test6712835.Printer.print(var_128); + result += "\n"; + result += "Tester_Class_9.var_133 = "; result += Test6712835.Printer.print(var_133); + result += ""; + result += "\n]"; + return result; + } +} + + +final class Tester_Class_10 extends Tester_Class_0 { + final static byte var_138 = 78; + Object var_139; + final static boolean var_140 = true; + float var_141 = 1.2816267E38F; + Tester_Class_8 var_142; + static Tester_Class_3 var_143; + short var_144 = var_1 ? (Tester_Class_6.var_96 &= 8024552544994698240L) : Tester_Class_0.var_5; + final boolean var_145 = var_140; + long var_146; + float[] var_147; + + + public Tester_Class_10() + { + "xuc".codePointCount(new Tester_Class_6().var_99 / ((new Tester_Class_9().var_128 = new Tester_Class_2()).var_1 ? var_138 : (int)(Tester_Class_3.var_64 += Tester_Class_3.var_64)), 882345740); + Tester_Class_3.var_64 /= Tester_Class_9.var_132; + Tester_Class_9.var_127.indexOf((Tester_Class_7.var_114 = (Tester_Class_8.var_114 = (Tester_Class_5)(var_139 = "mcyagebtv"))).var_83 = var_145 ? (Tester_Class_2.var_45 = Tester_Class_3.var_58) : Tester_Class_6.var_96); + --Tester_Class_2.var_46; + final float var_148 = 3.0263434E38F; + ((Tester_Class_7.var_114 = (Tester_Class_5)(Tester_Class_9.var_133 = new Tester_Class_1())).var_85 & ((Tester_Class_1)(var_139 = new Tester_Class_6())).var_1 ? "gmxwrgik" : Tester_Class_9.var_127).compareTo(var_4); + --Tester_Class_2.var_46; + new Tester_Class_6(); + ++Tester_Class_2.var_46; + Tester_Class_3.var_60 = Tester_Class_5.var_86 ? new Tester_Class_1() : new Tester_Class_1(); + { + --Tester_Class_6.var_96; + ((Tester_Class_7)(var_139 = new Tester_Class_1().var_4)).var_112 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)(var_139 = "gugsy"))); + } + Tester_Class_9.var_133 = (Tester_Class_3.var_60 = new Tester_Class_1()); + if (var_140 & !var_140) + { + Tester_Class_6.var_96++; + } + else + { + Tester_Class_2.var_46++; + } + { + ++new Tester_Class_6().var_92; + } + Tester_Class_7.var_109 = (((new Tester_Class_4[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_69 = (var_143 = new Tester_Class_3())); + Tester_Class_3.var_63--; + } + + + + + public String toString() + { + String result = "[\n"; + result += "Tester_Class_10.var_147 = "; result += Test6712835.Printer.print(var_147); + result += "\n"; + result += "Tester_Class_10.var_146 = "; result += Test6712835.Printer.print(var_146); + result += "\n"; + result += "Tester_Class_10.var_3 = "; result += Test6712835.Printer.print(var_3); + result += "\n"; + result += "Tester_Class_10.var_141 = "; result += Test6712835.Printer.print(var_141); + result += "\n"; + result += "Tester_Class_10.var_5 = "; result += Test6712835.Printer.print(var_5); + result += "\n"; + result += "Tester_Class_10.var_144 = "; result += Test6712835.Printer.print(var_144); + result += "\n"; + result += "Tester_Class_10.var_138 = "; result += Test6712835.Printer.print(var_138); + result += "\n"; + result += "Tester_Class_10.var_1 = "; result += Test6712835.Printer.print(var_1); + result += "\n"; + result += "Tester_Class_10.var_140 = "; result += Test6712835.Printer.print(var_140); + result += "\n"; + result += "Tester_Class_10.var_145 = "; result += Test6712835.Printer.print(var_145); + result += "\n"; + result += "Tester_Class_10.var_139 = "; result += Test6712835.Printer.print(var_139); + result += "\n"; + result += "Tester_Class_10.var_142 = "; result += Test6712835.Printer.print(var_142); + result += "\n"; + result += "Tester_Class_10.var_2 = "; result += Test6712835.Printer.print(var_2); + result += "\n"; + result += "Tester_Class_10.var_4 = "; result += Test6712835.Printer.print(var_4); + result += "\n"; + result += "Tester_Class_10.var_143 = "; result += Test6712835.Printer.print(var_143); + result += ""; + result += "\n]"; + return result; + } +} + + +interface Tester_Interface_11 { + public Tester_Class_4 func_0(final int arg_0, final byte arg_1); + public Tester_Class_2 func_1(Tester_Class_5 arg_0, final Tester_Class_0 arg_1, final int arg_2); +} + +public class Test6712835 { + final boolean var_149 = false; + Tester_Class_8 var_150; + final long var_151 = 8058077687473630208L; + + + protected final Tester_Class_1 func_0(final Object arg_0, Tester_Class_3 arg_1, final Tester_Class_4 arg_2, int arg_3) + { + Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)arg_0)); + --Tester_Class_3.var_63; + (var_150 = (((new Tester_Class_10[arg_2.var_71])[(((Tester_Class_6)arg_0).var_94 = arg_2).var_71 &= Tester_Class_3.var_63 << ~arg_2.var_71]).var_142 = (var_150 = (((Tester_Class_10)arg_0).var_142 = (Tester_Class_8)arg_0)))).var_113 = arg_2; + Tester_Class_7.var_114 = (Tester_Class_7.var_114 = false ? (Tester_Class_5)arg_0 : (Tester_Class_5)arg_0); + ((((arg_1 = arg_1).var_1 |= "lgcrda".equalsIgnoreCase("ontlkst")) ? (Tester_Class_1)arg_0 : (Tester_Class_3.var_60 = (Tester_Class_1)arg_0)).var_29 ? (arg_1 = (Tester_Class_3)(((Tester_Class_7)arg_0).var_112 = (Tester_Class_9)arg_0)) : arg_1).var_57 >>>= ']'; + Tester_Class_8.var_114 = (Tester_Class_5)arg_0; + ((Tester_Class_3.var_55 &= (arg_1.var_1 = true)) ? (Tester_Class_6)(new Tester_Class_0[Tester_Class_3.var_58][Tester_Class_10.var_138])[Tester_Class_10.var_138][Tester_Class_10.var_138] : (Tester_Class_6)arg_0).var_94 = arg_2; + { + Tester_Class_3.var_55 &= ((Tester_Class_3.var_60 = new Tester_Class_1()).var_1 &= false); + Tester_Class_2.var_44 -= (arg_3 |= + ~6610561718704644096L); + ((Tester_Class_8)arg_0).var_113 = ((((Tester_Class_10)(Tester_Class_0)arg_0).var_142 = (var_150 = (Tester_Class_8)arg_0)).var_124 = arg_2); + (! (false | Tester_Class_5.var_86) ? (Tester_Class_10)arg_0 : (new Tester_Class_10[arg_1.var_61][arg_1.var_61])[Tester_Class_10.var_138][Tester_Class_10.var_138]).var_139 = ((Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)arg_0)).var_31 = (((Tester_Class_9)arg_0).var_128 = (((Tester_Class_9)arg_0).var_128 = (Tester_Class_2)arg_0))); + } + final Tester_Interface_11 var_152 = !((Tester_Class_1)arg_0).var_29 ^ Tester_Class_5.var_86 ? (new Tester_Interface_11[arg_2.var_71][arg_1.var_61])[arg_1.var_61][arg_1.var_61] : (new Tester_Interface_11[arg_2.var_71][arg_2.var_71])[Tester_Class_10.var_138][Tester_Class_3.var_58]; + Tester_Class_3.var_64 /= (arg_3 >>= ++((Tester_Class_6)(Tester_Class_0)arg_0).var_92) * Tester_Class_9.var_132; + Tester_Class_0 var_153 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)arg_0))))).var_31 = (((new Tester_Class_9[arg_1.var_61])[arg_1.var_61 *= 634692606]).var_128 = !false ? (Tester_Class_2)arg_0 : (Tester_Class_2)arg_0); + (Tester_Class_10.var_140 ? (Tester_Class_7)arg_0 : (var_150 = (Tester_Class_8)(Tester_Class_7)arg_0)).var_112 = Tester_Class_3.var_64 != ((((Tester_Class_10)(var_153 = (Tester_Class_8.var_114 = (Tester_Class_5)arg_0))).var_1 |= arg_1.var_1) ? (Tester_Class_6)var_153 : (Tester_Class_6)var_153).var_99-- ? (Tester_Class_7)((var_150 = (Tester_Class_8)arg_0).var_112 = (Tester_Class_10)var_153) : (Tester_Class_7)arg_0; + (((new Tester_Class_7[Tester_Class_10.var_138][arg_2.var_71])[Tester_Class_3.var_58])[arg_2.var_71]).var_112 = arg_0; + if (!false) + { + arg_3 <<= (Tester_Class_2.var_46 /= - ((byte)((Tester_Class_10)arg_0).var_144)) - ((Tester_Class_6)arg_0).var_99; + } + else + { + ((Tester_Class_7)(((Tester_Class_8)arg_0).var_112 = var_153)).var_113 = arg_2; + ((Tester_Class_9)arg_0).var_128 = (((Tester_Class_9)(((Tester_Class_7)arg_0).var_112 = (Tester_Class_7)arg_0)).var_128 = (((Tester_Class_9)arg_0).var_128 = (Tester_Class_2)arg_0)); + } + (((Tester_Class_10)arg_0).var_142 = (Tester_Class_8)arg_0).var_124 = (((Tester_Class_6)var_153).var_94 = arg_2); + final char var_154 = arg_1.var_57 %= ((Tester_Class_6)var_153).var_93--; + (true ? arg_1 : (arg_1 = arg_1)).equals(arg_0); + (Tester_Class_10.var_140 ? (new Tester_Class_6[Tester_Class_10.var_138])[arg_2.var_71] : (new Tester_Class_6[(Tester_Class_10.var_143 = arg_1).var_61])[arg_1.var_61]).var_94 = ((((new Tester_Class_7[arg_2.var_71][arg_1.var_61][Tester_Class_10.var_138])[Tester_Class_10.var_138])[arg_2.var_71 = arg_2.var_71][Tester_Class_10.var_138]).var_113 = (((Tester_Class_7)arg_0).var_113 = arg_2)); + Tester_Class_3.var_60 = ((Tester_Class_10)(((Tester_Class_7)arg_0).var_112 = (Tester_Class_7)(((Tester_Class_10)var_153).var_139 = new Tester_Class_6[Tester_Class_10.var_138][Tester_Class_10.var_138]))).var_1 ? (Tester_Class_3.var_60 = (Tester_Class_1)var_153) : (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)(Tester_Class_9.var_133 = (Tester_Class_10)arg_0))); + ((Tester_Class_7)(((Tester_Class_10)arg_0).var_139 = new Tester_Class_10[Tester_Class_3.var_58][--arg_2.var_71])).var_112 = new byte[(((Tester_Class_8)(Tester_Class_7)((var_150 = (var_150 = (Tester_Class_8)arg_0)).var_112 = arg_2)).var_113 = (((Tester_Class_7)arg_0).var_113 = arg_2)).var_71]; + Tester_Class_8 var_155; + (Tester_Class_3.var_55 & arg_2.equals(arg_0) ? (Tester_Class_10)var_153 : (Tester_Class_10)var_153).var_3 %= Tester_Class_6.var_91; + return ((Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)var_153)))).var_29 ? ! !true : Tester_Class_10.var_140 | Tester_Class_3.var_55) || Tester_Class_3.var_55 ? (Tester_Class_3.var_60 = (Tester_Class_1)(((Tester_Class_10)var_153).var_139 = (Tester_Class_6)var_153)) : new Tester_Class_1(); + } + + protected Tester_Class_5 func_1(Tester_Class_0 arg_0, final float arg_1) + { + (!Tester_Class_10.var_140 ? (Tester_Class_6)arg_0 : (Tester_Class_6)arg_0).var_90 /= ((Tester_Class_8.var_109 = (new boolean[Tester_Class_10.var_138][Tester_Class_3.var_58])[((Tester_Class_6)arg_0).var_99][Tester_Class_10.var_138] ? (Tester_Class_3)((Tester_Class_3.var_60 = (Tester_Class_1)arg_0).var_31 = (Tester_Class_6)arg_0) : (Tester_Class_3)arg_0).var_61 *= Tester_Class_3.var_58); + { + "".toLowerCase(); + } + ((Tester_Class_10)arg_0).var_139 = new Tester_Class_8(); + arg_0 = (new Tester_Class_6[((Tester_Class_6)arg_0).var_99])[Tester_Class_3.var_58]; + if (((Tester_Class_10)(arg_0 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)arg_0)))).var_145) + { + Tester_Class_3.var_63++; + } + else + { + ++Tester_Class_2.var_46; + } + (((Tester_Class_3.var_55 ^= Tester_Class_3.var_55 ^ true) ? (Tester_Class_10)arg_0 : (Tester_Class_10)arg_0).var_145 || true ? (Tester_Class_6)arg_0 : (Tester_Class_6)(((Tester_Class_7)(((Tester_Class_10)arg_0).var_139 = (Tester_Class_10)arg_0)).var_112 = "jlixai")).var_99--; + Tester_Class_5.var_81 = Tester_Class_3.var_55 && ! (arg_0.var_1 = arg_0.var_1); + { + ((new Tester_Class_6[Tester_Class_3.var_58])[(true ? (Tester_Class_6)(Tester_Class_9.var_133 = (Tester_Class_10)arg_0) : (Tester_Class_6)(((Tester_Class_1)arg_0).var_31 = (Tester_Class_10)arg_0)).var_99]).var_90 *= (Tester_Class_3.var_64 %= Tester_Class_3.var_63); + } + ++Tester_Class_2.var_46; + Tester_Class_0 var_156; + Tester_Class_2.var_46++; + Tester_Class_8.var_114 = (Tester_Class_7.var_114 = (Tester_Class_8.var_114 = (Tester_Class_5)arg_0)); + Tester_Class_6.func_2((Tester_Class_7.var_114 = (Tester_Class_7.var_114 = (Tester_Class_7.var_114 = (Tester_Class_5)arg_0))).var_83 = (byte)(((Tester_Class_10)arg_0).var_142 = (new Tester_Class_8[Tester_Class_3.var_58][Tester_Class_3.var_58])[Tester_Class_3.var_58][Tester_Class_10.var_138]).var_110, Tester_Class_6.var_96, (new byte[Tester_Class_3.var_58])[Tester_Class_10.var_138]); + Tester_Class_7.var_114 = (new Tester_Class_5[Tester_Class_10.var_138])[((Tester_Class_3)arg_0).var_61]; + boolean var_157 = Tester_Class_10.var_140; + (Tester_Class_3.var_60 = (Tester_Class_1)arg_0).var_1 ^= Tester_Class_10.var_140; + return Tester_Class_8.var_114 = (Tester_Class_7.var_114 = (Tester_Class_8.var_114 = (Tester_Class_5)arg_0)); + } + + final static int func_2(Tester_Class_6 arg_0) + { + new Tester_Class_9(); + { + ++Tester_Class_3.var_63; + } + new Tester_Class_3().var_57--; + Tester_Class_1 var_158; + String var_159; + --Tester_Class_6.var_96; + { + new String(); + } + var_159 = (var_159 = arg_0.var_4); + { + --Tester_Class_2.var_46; + } + final double var_160 = (Tester_Class_7.var_114 = (Tester_Class_8.var_114 = (Tester_Class_8.var_114 = (Tester_Class_5)(new Tester_Class_0[arg_0.var_99][arg_0.var_99])[Tester_Class_3.var_58][Tester_Class_3.var_58]))).var_1 ? Tester_Class_9.var_132 : Tester_Class_6.var_97; + Tester_Class_8 var_161; + char var_162 = 'O'; + Tester_Class_2.var_46++; + Tester_Class_6.var_96++; + { + new String(); + } + ++Tester_Class_6.var_96; + var_162 >>= ((new Tester_Class_4[arg_0.var_99])[arg_0.var_99++]).var_70 >> Tester_Class_6.var_91; + (Tester_Class_7.var_114 = (Tester_Class_7.var_114 = (new Tester_Class_5[Tester_Class_3.var_58])[++arg_0.var_99])).var_83 = (arg_0.var_93 <<= Tester_Class_7.var_108); + --Tester_Class_6.var_96; + { + new Tester_Class_9().var_128 = new Tester_Class_2(); + } + arg_0 = arg_0; + { + Tester_Class_9 var_163; + } + ((Tester_Class_5)(Tester_Class_9.var_133 = arg_0)).var_83 = (arg_0.var_99 >>= Tester_Class_5.var_5); + arg_0.var_99 = Tester_Class_10.var_138; + Tester_Class_3.var_60 = (var_158 = (Tester_Class_3.var_60 = (Tester_Class_1)(Tester_Class_9.var_133 = arg_0))); + return Tester_Class_6.var_91; + } + + protected final Tester_Class_9 func_3() + { + Tester_Class_2.var_44 = 3210658399310388224L; + ++Tester_Class_6.var_96; + short var_164 = 15978; + var_164++; + Tester_Class_5.var_81 = true; + return Tester_Class_3.var_55 ? new Tester_Class_9() : new Tester_Class_9(); + } + + final static Tester_Class_10 func_4(Tester_Class_3 arg_0, String arg_1, final byte[] arg_2, final Object arg_3) + { + Tester_Class_1 var_165; + Tester_Class_3.var_63 += new Tester_Class_6().var_92 >= 3821095133162842112L ? (arg_0.var_61 |= Tester_Class_6.var_91) : Tester_Class_10.var_138; + return false ? ((var_165 = (Tester_Class_1)arg_3).var_29 ? (Tester_Class_10)arg_3 : (Tester_Class_10)arg_3) : (Tester_Class_10)(Tester_Class_0)arg_3; + } + + private static Object func_7(final short arg_0, String arg_1, final Tester_Class_3 arg_2) + { + Tester_Class_3.var_60 = (new Tester_Class_1[arg_2.var_61])[Tester_Class_10.var_138]; + return ((new Tester_Class_7[arg_2.var_61 |= Tester_Class_3.var_63])[arg_2.var_61 *= Tester_Class_6.var_98]).var_112 = new Tester_Class_8(); + } + + public static String execute() + { + try { + Test6712835 t = new Test6712835(); + try { t.test(); } + catch(Throwable e) { } + try { return t.toString(); } + catch (Throwable e) { return "Error during result conversion to String"; } + } catch (Throwable e) { return "Error during test execution"; } + } + + public static void main(String[] args) + { + try { + Test6712835 t = new Test6712835(); + try { t.test(); } + catch(Throwable e) { } + try { System.out.println(t); } + catch(Throwable e) { } + } catch (Throwable e) { } + } + + private void test() + { + Tester_Class_3.var_60 = true ? (Tester_Class_3.var_60 = new Tester_Class_1()) : new Tester_Class_1(); + double var_170 = 0; + Tester_Class_9.var_133 = (new Tester_Class_4().var_69 = new Tester_Class_3()); + new Tester_Class_6(); + String var_171; + new Tester_Class_9(); + do + { + new String(); + var_170++; + Tester_Class_3.var_64 = 1.0240330514364089E307; + new String(); + var_171 = (var_171 = Tester_Class_9.var_127); + Tester_Class_3.var_63--; + } while (var_170 < 525); + ((new Tester_Class_10[Tester_Class_10.var_138])[Tester_Class_2.var_45 = Tester_Class_3.var_58]).var_142 = (Tester_Class_8)(Tester_Class_7)(new Tester_Class_10().var_139 = new Tester_Class_2()); + long var_172 = 0L; + Tester_Class_3.var_64 /= (((new Tester_Class_6[Tester_Class_3.var_58])[Tester_Class_10.var_138]).var_99 ^= ((new Tester_Class_6[Tester_Class_3.var_58])[Tester_Class_10.var_138]).var_90) > 9.462466046830147E307 ? new Tester_Class_6().var_99 : Tester_Class_3.var_58; + short var_173; + (true ? new Tester_Class_2() : (func_3().var_128 = new Tester_Class_2())).var_3 *= (var_150 = new Tester_Class_8()).var_115; + (Tester_Class_3.var_60 = new Tester_Class_1()).var_31 = (((new Tester_Class_9[Tester_Class_3.var_58])[Tester_Class_10.var_138]).var_128 = (func_3().var_128 = (func_3().var_128 = (new Tester_Class_9().var_128 = new Tester_Class_2())))); + for (((new Tester_Class_10[new Tester_Class_6().var_99])[new Tester_Class_6().var_99++]).var_142 = (new Tester_Class_8[Tester_Class_10.var_138])[Tester_Class_3.var_58]; var_172 < 203 && (Tester_Class_3.var_55 &= (new boolean[Tester_Class_2.var_45 = Tester_Class_3.var_58])[Tester_Class_10.var_138]); Tester_Class_9.var_133 = (Tester_Class_7.var_114 = (new Tester_Class_5[Tester_Class_2.var_45 = Tester_Class_10.var_138][Tester_Class_10.var_138])[Tester_Class_3.var_58][Tester_Class_2.var_45 = Tester_Class_3.var_58])) + { + var_171 = Tester_Class_9.var_127; + var_172++; + Tester_Class_3.var_63++; + Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)(new Object[Tester_Class_3.var_58][Tester_Class_10.var_138])[Tester_Class_3.var_58][Tester_Class_3.var_58]))); + ++Tester_Class_2.var_46; + Tester_Class_2.var_46--; + Tester_Class_3.var_64 -= Tester_Class_3.var_58; + } + (Tester_Class_3.var_60 = new Tester_Class_1()).var_31 = ((new Tester_Class_8().var_124 = new Tester_Class_4()).var_69 = new Tester_Class_3()); + int var_174 = 0; + ((new Tester_Class_6[Tester_Class_10.var_138][Tester_Class_10.var_138])[Tester_Class_2.var_45 = Tester_Class_10.var_138][Tester_Class_2.var_45 = Tester_Class_3.var_58]).var_92 = 'Z'; + while ((Tester_Class_9.var_131 = Tester_Class_3.var_55) && (var_174 < 24 && !true)) + { + new Tester_Class_10(); + var_174++; + Tester_Class_3.var_64 %= (((new Tester_Class_6[Tester_Class_3.var_58])[Tester_Class_2.var_45 = Tester_Class_3.var_58]).var_93 ^= (byte)Tester_Class_3.var_59); + ((Tester_Class_10)(Tester_Class_9.var_133 = (new Tester_Class_5[((Tester_Class_6)(new Tester_Class_0[Tester_Class_10.var_138])[(byte)(Tester_Class_2.var_46 >>>= Tester_Class_7.var_108)]).var_99])[Tester_Class_10.var_138])).var_139 = (new Tester_Class_10[new Tester_Class_6().var_99][new Tester_Class_4().var_71])[new Tester_Class_4().var_71]; + } + int var_175 = 0; + (Tester_Class_10.var_140 ? (Tester_Class_2)(Tester_Class_9.var_133 = (Tester_Class_7.var_114 = (new Tester_Class_5[Tester_Class_10.var_138])[Tester_Class_10.var_138])) : new Tester_Class_2()).var_1 &= Tester_Class_3.var_55; + do + { + Tester_Class_10.var_143 = new Tester_Class_3(); + var_175++; + ++Tester_Class_2.var_46; + } while ((false ? true : var_149) | !Tester_Class_10.var_140 && var_175 < 97); + Tester_Class_9.var_131 = true; + (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = new Tester_Class_1())))).var_1 &= (((new Tester_Class_10().var_1 = !true) ? new Tester_Class_10() : new Tester_Class_10()).var_145 ? new Tester_Class_3() : new Tester_Class_3()).var_1; + (true ? func_3() : func_3()).var_128 = ((((Tester_Class_5.var_86 = (Tester_Class_3.var_55 &= !var_149)) ? new Tester_Class_10() : new Tester_Class_10()).var_145 ? new Tester_Class_9() : func_3()).var_128 = var_149 ? new Tester_Class_2() : new Tester_Class_2()); + Tester_Class_3.var_59 -= (Tester_Class_5.var_81 = new Tester_Class_1().var_29) ^ !true ? 7920143378515332096L : new Tester_Class_6().var_92; + ((Tester_Class_3.var_60 = new Tester_Class_1()).var_1 ? (new Tester_Class_5[Tester_Class_10.var_138][Tester_Class_3.var_58])[Tester_Class_3.var_58][Tester_Class_3.var_58] : (Tester_Class_8.var_114 = new Tester_Class_5())).var_83 = Tester_Class_10.var_140 ? (Tester_Class_3.var_63 -= 2.0167496E38F) : ++Tester_Class_3.var_63; + double var_176 = 9.327780852480363E307; + } + public String toString() + { + String result = "[\n"; + result += "Test6712835.var_151 = "; result += Printer.print(var_151); + result += "\n"; + result += "Test6712835.var_149 = "; result += Printer.print(var_149); + result += "\n"; + result += "Test6712835.var_150 = "; result += Printer.print(var_150); + result += ""; + result += "\n]"; + return result; + } + static class Printer + { + public static String print(boolean arg) { return String.valueOf(arg); } + public static String print(byte arg) { return String.valueOf(arg); } + public static String print(short arg) { return String.valueOf(arg); } + public static String print(char arg) { return String.valueOf((int)arg); } + public static String print(int arg) { return String.valueOf(arg); } + public static String print(long arg) { return String.valueOf(arg); } + public static String print(float arg) { return String.valueOf(arg); } + public static String print(double arg) { return String.valueOf(arg); } + + + public static String print(Object arg) + { + return print_r(new java.util.Stack(), arg); + } + + private static String print_r(java.util.Stack visitedObjects, Object arg) + { + String result = ""; + if (arg == null) + result += "null"; + else + if (arg.getClass().isArray()) + { + for (int i = 0; i < visitedObjects.size(); i++) + if (visitedObjects.elementAt(i) == arg) return ""; + + visitedObjects.push(arg); + + final String delimiter = ", "; + result += "["; + + if (arg instanceof Object[]) + { + Object[] array = (Object[]) arg; + for (int i = 0; i < array.length; i++) + { + result += print_r(visitedObjects, array[i]); + if (i < array.length - 1) result += delimiter; + } + } + else + if (arg instanceof boolean[]) + { + boolean[] array = (boolean[]) arg; + for (int i = 0; i < array.length; i++) + { + result += print(array[i]); + if (i < array.length - 1) result += delimiter; + } + } + else + if (arg instanceof byte[]) + { + byte[] array = (byte[]) arg; + for (int i = 0; i < array.length; i++) + { + result += print(array[i]); + if (i < array.length - 1) result += delimiter; + } + } + else + if (arg instanceof short[]) + { + short[] array = (short[]) arg; + for (int i = 0; i < array.length; i++) + { + result += print(array[i]); + if (i < array.length - 1) result += delimiter; + } + } + else + if (arg instanceof char[]) + { + char[] array = (char[]) arg; + for (int i = 0; i < array.length; i++) + { + result += print(array[i]); + if (i < array.length - 1) result += delimiter; + } + } + else + if (arg instanceof int[]) + { + int[] array = (int[]) arg; + for (int i = 0; i < array.length; i++) + { + result += print(array[i]); + if (i < array.length - 1) result += delimiter; + } + } + else + if (arg instanceof long[]) + { + long[] array = (long[]) arg; + for (int i = 0; i < array.length; i++) + { + result += print(array[i]); + if (i < array.length - 1) result += delimiter; + } + } + else + if (arg instanceof float[]) + { + float[] array = (float[]) arg; + for (int i = 0; i < array.length; i++) + { + result += print(array[i]); + if (i < array.length - 1) result += delimiter; + } + } + else + if (arg instanceof double[]) + { + double[] array = (double[]) arg; + for (int i = 0; i < array.length; i++) + { + result += print(array[i]); + if (i < array.length - 1) result += delimiter; + } + } + + result += "]"; + visitedObjects.pop(); + + } else + { + result += arg.toString(); + } + + return result; + } + } +} From 20de63f383e1417b4e39b9b5197db870a8c56df8 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Fri, 25 Jul 2008 15:54:23 -0700 Subject: [PATCH 13/52] 6700047: C2 failed in idom_no_update Partial peeling shouldn't place clones into loop Reviewed-by: kvn --- hotspot/src/share/vm/opto/loopopts.cpp | 17 +++--- .../test/compiler/6700047/Test6700047.java | 60 +++++++++++++++++++ 2 files changed, 69 insertions(+), 8 deletions(-) create mode 100644 hotspot/test/compiler/6700047/Test6700047.java diff --git a/hotspot/src/share/vm/opto/loopopts.cpp b/hotspot/src/share/vm/opto/loopopts.cpp index f7fa3f21b2c..4353219f41c 100644 --- a/hotspot/src/share/vm/opto/loopopts.cpp +++ b/hotspot/src/share/vm/opto/loopopts.cpp @@ -1891,18 +1891,19 @@ void PhaseIdealLoop::clone_for_use_outside_loop( IdealLoopTree *loop, Node* n, N _igvn.hash_delete(use); use->set_req(j, n_clone); _igvn._worklist.push(use); + Node* use_c; if (!use->is_Phi()) { - Node* use_c = has_ctrl(use) ? get_ctrl(use) : use->in(0); - set_ctrl(n_clone, use_c); - assert(!loop->is_member(get_loop(use_c)), "should be outside loop"); - get_loop(use_c)->_body.push(n_clone); + use_c = has_ctrl(use) ? get_ctrl(use) : use->in(0); } else { // Use in a phi is considered a use in the associated predecessor block - Node *prevbb = use->in(0)->in(j); - set_ctrl(n_clone, prevbb); - assert(!loop->is_member(get_loop(prevbb)), "should be outside loop"); - get_loop(prevbb)->_body.push(n_clone); + use_c = use->in(0)->in(j); } + if (use_c->is_CountedLoop()) { + use_c = use_c->in(LoopNode::EntryControl); + } + set_ctrl(n_clone, use_c); + assert(!loop->is_member(get_loop(use_c)), "should be outside loop"); + get_loop(use_c)->_body.push(n_clone); _igvn.register_new_node_with_optimizer(n_clone); #if !defined(PRODUCT) if (TracePartialPeeling) { diff --git a/hotspot/test/compiler/6700047/Test6700047.java b/hotspot/test/compiler/6700047/Test6700047.java new file mode 100644 index 00000000000..55921d59465 --- /dev/null +++ b/hotspot/test/compiler/6700047/Test6700047.java @@ -0,0 +1,60 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6700047 + * @summary C2 failed in idom_no_update + * @run main Test6700047 + */ + +public class Test6700047 { + public static void main(String[] args) { + for (int i = 0; i < 100000; i++) { + intToLeftPaddedAsciiBytes(); + } + } + + public static int intToLeftPaddedAsciiBytes() { + int offset = 40; + int q; + int r; + int i = 100; + int result = 1; + while (offset > 0) { + q = (i * 52429); + r = i; + offset--; + i = q; + if (i == 0) { + break; + } + } + if (offset > 0) { + for(int j = 0; j < offset; j++) { + result++; + } + } + return result; + } +} From 2d1fcda0d7fc039b1d2be6fd72fab6acb01c9804 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Fri, 25 Jul 2008 16:03:40 -0700 Subject: [PATCH 14/52] 6729552: jvm98 crashes with SS12 built jdk on Solaris X64 fastdebug version SS12 C++ tripped over new templates usage in instanceKlass.cpp. Reviewed-by: never --- hotspot/make/solaris/makefiles/fastdebug.make | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hotspot/make/solaris/makefiles/fastdebug.make b/hotspot/make/solaris/makefiles/fastdebug.make index 62eaeb8f968..3ac2ae212b1 100644 --- a/hotspot/make/solaris/makefiles/fastdebug.make +++ b/hotspot/make/solaris/makefiles/fastdebug.make @@ -38,6 +38,8 @@ OPT_CFLAGS/SLOWER = -xO2 # Problem with SS12 compiler, dtrace doesn't like the .o files (bug 6693876) ifeq ($(COMPILER_REV), 5.9) + # To avoid jvm98 crash + OPT_CFLAGS/instanceKlass.o = $(OPT_CFLAGS/SLOWER) # Not clear this workaround could be skipped in some cases. OPT_CFLAGS/vmGCOperations.o = $(OPT_CFLAGS/SLOWER) OPT_CFLAGS/java.o = $(OPT_CFLAGS/SLOWER) From 74faacc94506d50ed1c827d0f26baf10f5348d19 Mon Sep 17 00:00:00 2001 From: Keith McGuigan Date: Mon, 28 Jul 2008 14:07:44 -0400 Subject: [PATCH 15/52] 6721093: -XX:AppendRatio=N not supported Add mechanism to ignore unsupported flags for a set period of time Reviewed-by: acorn, never, coleenp --- hotspot/src/os/linux/vm/os_linux.cpp | 34 ++- hotspot/src/os/solaris/vm/os_solaris.cpp | 21 ++ hotspot/src/os/windows/vm/os_windows.cpp | 26 +++ .../src/share/vm/classfile/javaClasses.cpp | 4 +- hotspot/src/share/vm/includeDB_core | 1 + hotspot/src/share/vm/memory/universe.cpp | 21 +- hotspot/src/share/vm/runtime/arguments.cpp | 85 ++++--- hotspot/src/share/vm/runtime/arguments.hpp | 8 +- hotspot/src/share/vm/runtime/init.cpp | 2 - hotspot/src/share/vm/runtime/java.cpp | 104 +++++++-- hotspot/src/share/vm/runtime/java.hpp | 211 ++++++++++++------ hotspot/src/share/vm/runtime/os.cpp | 43 ++-- hotspot/src/share/vm/runtime/os.hpp | 7 + hotspot/src/share/vm/runtime/thread.cpp | 8 +- .../share/vm/runtime/threadLocalStorage.cpp | 7 +- .../share/vm/runtime/threadLocalStorage.hpp | 1 + hotspot/src/share/vm/runtime/vmStructs.cpp | 5 +- .../src/share/vm/services/threadService.cpp | 2 +- 18 files changed, 432 insertions(+), 158 deletions(-) diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index bc5d9ebc69e..c80f526306f 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -94,6 +94,9 @@ static pid_t _initial_pid = 0; static int SR_signum = SIGUSR2; sigset_t SR_sigset; +/* Used to protect dlsym() calls */ +static pthread_mutex_t dl_mutex; + //////////////////////////////////////////////////////////////////////////////// // utility functions @@ -1493,6 +1496,24 @@ const char* os::dll_file_extension() { return ".so"; } const char* os::get_temp_directory() { return "/tmp/"; } +void os::dll_build_name( + char* buffer, size_t buflen, const char* pname, const char* fname) { + // copied from libhpi + const size_t pnamelen = pname ? strlen(pname) : 0; + + /* Quietly truncate on buffer overflow. Should be an error. */ + if (pnamelen + strlen(fname) + 10 > (size_t) buflen) { + *buffer = '\0'; + return; + } + + if (pnamelen == 0) { + sprintf(buffer, "lib%s.so", fname); + } else { + sprintf(buffer, "%s/lib%s.so", pname, fname); + } +} + const char* os::get_current_directory(char *buf, int buflen) { return getcwd(buf, buflen); } @@ -1742,7 +1763,17 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) return NULL; } - +/* + * glibc-2.0 libdl is not MT safe. If you are building with any glibc, + * chances are you might want to run the generated bits against glibc-2.0 + * libdl.so, so always use locking for any version of glibc. + */ +void* os::dll_lookup(void* handle, const char* name) { + pthread_mutex_lock(&dl_mutex); + void* res = dlsym(handle, name); + pthread_mutex_unlock(&dl_mutex); + return res; +} bool _print_ascii_file(const char* filename, outputStream* st) { @@ -3581,6 +3612,7 @@ void os::init(void) { Linux::clock_init(); initial_time_count = os::elapsed_counter(); + pthread_mutex_init(&dl_mutex, NULL); } // To install functions for atexit system call diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp index b6ca2a6db90..c17ae11e81c 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.cpp +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp @@ -1783,6 +1783,24 @@ const char* os::dll_file_extension() { return ".so"; } const char* os::get_temp_directory() { return "/tmp/"; } +void os::dll_build_name( + char* buffer, size_t buflen, const char* pname, const char* fname) { + // copied from libhpi + const size_t pnamelen = pname ? strlen(pname) : 0; + + /* Quietly truncate on buffer overflow. Should be an error. */ + if (pnamelen + strlen(fname) + 10 > (size_t) buflen) { + *buffer = '\0'; + return; + } + + if (pnamelen == 0) { + sprintf(buffer, "lib%s.so", fname); + } else { + sprintf(buffer, "%s/lib%s.so", pname, fname); + } +} + const char* os::get_current_directory(char *buf, int buflen) { return getcwd(buf, buflen); } @@ -2034,6 +2052,9 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) return NULL; } +void* os::dll_lookup(void* handle, const char* name) { + return dlsym(handle, name); +} bool _print_ascii_file(const char* filename, outputStream* st) { diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index 14b3141d27e..c77f50b77f5 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -985,6 +985,28 @@ const char * os::get_temp_directory() } } +void os::dll_build_name(char *holder, size_t holderlen, + const char* pname, const char* fname) +{ + // copied from libhpi + const size_t pnamelen = pname ? strlen(pname) : 0; + const char c = (pnamelen > 0) ? pname[pnamelen-1] : 0; + + /* Quietly truncates on buffer overflow. Should be an error. */ + if (pnamelen + strlen(fname) + 10 > holderlen) { + *holder = '\0'; + return; + } + + if (pnamelen == 0) { + sprintf(holder, "%s.dll", fname); + } else if (c == ':' || c == '\\') { + sprintf(holder, "%s%s.dll", pname, fname); + } else { + sprintf(holder, "%s\\%s.dll", pname, fname); + } +} + // Needs to be in os specific directory because windows requires another // header file const char* os::get_current_directory(char *buf, int buflen) { @@ -1248,6 +1270,10 @@ bool os::dll_address_to_function_name(address addr, char *buf, return false; } +void* os::dll_lookup(void* handle, const char* name) { + return GetProcAddress((HMODULE)handle, name); +} + // save the start and end address of jvm.dll into param[0] and param[1] static int _locate_jvm_dll(int pid, char* mod_fname, address base_addr, unsigned size, void * param) { diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp index 65a07231a72..ea68a366740 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.cpp +++ b/hotspot/src/share/vm/classfile/javaClasses.cpp @@ -649,8 +649,8 @@ jlong java_lang_Thread::thread_id(oop java_thread) { } oop java_lang_Thread::park_blocker(oop java_thread) { - assert(JDK_Version::supports_thread_park_blocker() && _park_blocker_offset != 0, - "Must support parkBlocker field"); + assert(JDK_Version::current().supports_thread_park_blocker() && + _park_blocker_offset != 0, "Must support parkBlocker field"); if (_park_blocker_offset > 0) { return java_thread->obj_field(_park_blocker_offset); diff --git a/hotspot/src/share/vm/includeDB_core b/hotspot/src/share/vm/includeDB_core index 0c53185fd0e..6354076017c 100644 --- a/hotspot/src/share/vm/includeDB_core +++ b/hotspot/src/share/vm/includeDB_core @@ -178,6 +178,7 @@ arguments.cpp os_.inline.hpp arguments.cpp universe.inline.hpp arguments.cpp vm_version_.hpp +arguments.hpp java.hpp arguments.hpp perfData.hpp arguments.hpp top.hpp diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp index bfa85393d49..c943f5749a7 100644 --- a/hotspot/src/share/vm/memory/universe.cpp +++ b/hotspot/src/share/vm/memory/universe.cpp @@ -367,26 +367,31 @@ void Universe::genesis(TRAPS) { // Only 1.3 or later has the java.lang.Shutdown class. // Only 1.4 or later has the java.lang.CharSequence interface. // Only 1.5 or later has the java.lang.management.MemoryUsage class. - if (JDK_Version::is_pre_jdk16_version()) { - klassOop k = SystemDictionary::resolve_or_null(vmSymbolHandles::java_lang_management_MemoryUsage(), THREAD); + if (JDK_Version::is_partially_initialized()) { + uint8_t jdk_version; + klassOop k = SystemDictionary::resolve_or_null( + vmSymbolHandles::java_lang_management_MemoryUsage(), THREAD); CLEAR_PENDING_EXCEPTION; // ignore exceptions if (k == NULL) { - k = SystemDictionary::resolve_or_null(vmSymbolHandles::java_lang_CharSequence(), THREAD); + k = SystemDictionary::resolve_or_null( + vmSymbolHandles::java_lang_CharSequence(), THREAD); CLEAR_PENDING_EXCEPTION; // ignore exceptions if (k == NULL) { - k = SystemDictionary::resolve_or_null(vmSymbolHandles::java_lang_Shutdown(), THREAD); + k = SystemDictionary::resolve_or_null( + vmSymbolHandles::java_lang_Shutdown(), THREAD); CLEAR_PENDING_EXCEPTION; // ignore exceptions if (k == NULL) { - JDK_Version::set_jdk12x_version(); + jdk_version = 2; } else { - JDK_Version::set_jdk13x_version(); + jdk_version = 3; } } else { - JDK_Version::set_jdk14x_version(); + jdk_version = 4; } } else { - JDK_Version::set_jdk15x_version(); + jdk_version = 5; } + JDK_Version::fully_initialize(jdk_version); } #ifdef ASSERT diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index b5d35226c0d..5d114ec7714 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -153,37 +153,56 @@ void Arguments::init_system_properties() { os::init_system_properties_values(); } -// String containing commands that will be ignored and cause a -// warning to be issued. These commands should be accepted -// for 1.6 but not 1.7. The string should be cleared at the -// beginning of 1.7. -static const char* obsolete_jvm_flags_1_5_0[] = { - "UseTrainGC", - "UseSpecialLargeObjectHandling", - "UseOversizedCarHandling", - "TraceCarAllocation", - "PrintTrainGCProcessingStats", - "LogOfCarSpaceSize", - "OversizedCarThreshold", - "MinTickInterval", - "DefaultTickInterval", - "MaxTickInterval", - "DelayTickAdjustment", - "ProcessingToTenuringRatio", - "MinTrainLength", - 0}; +/** + * Provide a slightly more user-friendly way of eliminating -XX flags. + * When a flag is eliminated, it can be added to this list in order to + * continue accepting this flag on the command-line, while issuing a warning + * and ignoring the value. Once the JDK version reaches the 'accept_until' + * limit, we flatly refuse to admit the existence of the flag. This allows + * a flag to die correctly over JDK releases using HSX. + */ +typedef struct { + const char* name; + JDK_Version obsoleted_in; // when the flag went away + JDK_Version accept_until; // which version to start denying the existence +} ObsoleteFlag; -bool Arguments::made_obsolete_in_1_5_0(const char *s) { +static ObsoleteFlag obsolete_jvm_flags[] = { + { "UseTrainGC", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "UseSpecialLargeObjectHandling", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "UseOversizedCarHandling", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "TraceCarAllocation", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "PrintTrainGCProcessingStats", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "LogOfCarSpaceSize", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "OversizedCarThreshold", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "MinTickInterval", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "DefaultTickInterval", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "MaxTickInterval", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "DelayTickAdjustment", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "ProcessingToTenuringRatio", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "MinTrainLength", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "AppendRatio", JDK_Version::jdk_update(6,10), JDK_Version::jdk(7) }, + { NULL, JDK_Version(0), JDK_Version(0) } +}; + +// Returns true if the flag is obsolete and fits into the range specified +// for being ignored. In the case that the flag is ignored, the 'version' +// value is filled in with the version number when the flag became +// obsolete so that that value can be displayed to the user. +bool Arguments::is_newly_obsolete(const char *s, JDK_Version* version) { int i = 0; - while (obsolete_jvm_flags_1_5_0[i] != NULL) { + assert(version != NULL, "Must provide a version buffer"); + while (obsolete_jvm_flags[i].name != NULL) { + const ObsoleteFlag& flag_status = obsolete_jvm_flags[i]; // =xxx form // [-|+] form - if ((strncmp(obsolete_jvm_flags_1_5_0[i], s, - strlen(obsolete_jvm_flags_1_5_0[i])) == 0) || + if ((strncmp(flag_status.name, s, strlen(flag_status.name)) == 0) || ((s[0] == '+' || s[0] == '-') && - (strncmp(obsolete_jvm_flags_1_5_0[i], &s[1], - strlen(obsolete_jvm_flags_1_5_0[i])) == 0))) { - return true; + (strncmp(flag_status.name, &s[1], strlen(flag_status.name)) == 0))) { + if (JDK_Version::current().compare(flag_status.accept_until) == -1) { + *version = flag_status.obsoleted_in; + return true; + } } i++; } @@ -705,14 +724,20 @@ void Arguments::print_jvm_args_on(outputStream* st) { } } -bool Arguments::process_argument(const char* arg, jboolean ignore_unrecognized, FlagValueOrigin origin) { +bool Arguments::process_argument(const char* arg, + jboolean ignore_unrecognized, FlagValueOrigin origin) { + + JDK_Version since = JDK_Version(); if (parse_argument(arg, origin)) { // do nothing - } else if (made_obsolete_in_1_5_0(arg)) { + } else if (is_newly_obsolete(arg, &since)) { + enum { bufsize = 256 }; + char buffer[bufsize]; + since.to_string(buffer, bufsize); jio_fprintf(defaultStream::error_stream(), - "Warning: The flag %s has been EOL'd as of 1.5.0 and will" - " be ignored\n", arg); + "Warning: The flag %s has been EOL'd as of %s and will" + " be ignored\n", arg, buffer); } else { if (!ignore_unrecognized) { jio_fprintf(defaultStream::error_stream(), diff --git a/hotspot/src/share/vm/runtime/arguments.hpp b/hotspot/src/share/vm/runtime/arguments.hpp index bbc91c89c95..1a7e3849fe4 100644 --- a/hotspot/src/share/vm/runtime/arguments.hpp +++ b/hotspot/src/share/vm/runtime/arguments.hpp @@ -357,9 +357,11 @@ class Arguments : AllStatic { short* methodsNum, short* methodsMax, char*** methods, bool** allClasses ); - // Returns true if the string s is in the list of - // flags made obsolete in 1.5.0. - static bool made_obsolete_in_1_5_0(const char* s); + // Returns true if the string s is in the list of flags that have recently + // been made obsolete. If we detect one of these flags on the command + // line, instead of failing we print a warning message and ignore the + // flag. This gives the user a release or so to stop using the flag. + static bool is_newly_obsolete(const char* s, JDK_Version* buffer); static short CompileOnlyClassesNum; static short CompileOnlyClassesMax; diff --git a/hotspot/src/share/vm/runtime/init.cpp b/hotspot/src/share/vm/runtime/init.cpp index 4851d19a15a..3f470e3ed9a 100644 --- a/hotspot/src/share/vm/runtime/init.cpp +++ b/hotspot/src/share/vm/runtime/init.cpp @@ -39,7 +39,6 @@ void bytecodes_init(); void classLoader_init(); void codeCache_init(); void VM_Version_init(); -void JDK_Version_init(); void stubRoutines_init1(); jint universe_init(); // dependent on codeCache_init and stubRoutines_init void interpreter_init(); // before any methods loaded @@ -88,7 +87,6 @@ jint init_globals() { classLoader_init(); codeCache_init(); VM_Version_init(); - JDK_Version_init(); stubRoutines_init1(); jint status = universe_init(); // dependent on codeCache_init and stubRoutines_init if (status != JNI_OK) diff --git a/hotspot/src/share/vm/runtime/java.cpp b/hotspot/src/share/vm/runtime/java.cpp index 4e0ba39e629..ad992664a97 100644 --- a/hotspot/src/share/vm/runtime/java.cpp +++ b/hotspot/src/share/vm/runtime/java.cpp @@ -563,32 +563,104 @@ void vm_shutdown_during_initialization(const char* error, const char* message) { vm_shutdown(); } -jdk_version_info JDK_Version::_version_info = {0}; -bool JDK_Version::_pre_jdk16_version = false; -int JDK_Version::_jdk_version = 0; +JDK_Version JDK_Version::_current; void JDK_Version::initialize() { + jdk_version_info info; + assert(!_current.is_valid(), "Don't initialize twice"); + void *lib_handle = os::native_java_library(); - jdk_version_info_fn_t func = - CAST_TO_FN_PTR(jdk_version_info_fn_t, hpi::dll_lookup(lib_handle, "JDK_GetVersionInfo0")); + jdk_version_info_fn_t func = CAST_TO_FN_PTR(jdk_version_info_fn_t, + os::dll_lookup(lib_handle, "JDK_GetVersionInfo0")); if (func == NULL) { // JDK older than 1.6 - _pre_jdk16_version = true; - return; - } - - if (func != NULL) { - (*func)(&_version_info, sizeof(_version_info)); - } - if (jdk_major_version() == 1) { - _jdk_version = jdk_minor_version(); + _current._partially_initialized = true; } else { - // If the release version string is changed to n.x.x (e.g. 7.0.0) in a future release - _jdk_version = jdk_major_version(); + (*func)(&info, sizeof(info)); + + int major = JDK_VERSION_MAJOR(info.jdk_version); + int minor = JDK_VERSION_MINOR(info.jdk_version); + int micro = JDK_VERSION_MICRO(info.jdk_version); + int build = JDK_VERSION_BUILD(info.jdk_version); + if (major == 1 && minor > 4) { + // We represent "1.5.0" as "5.0", but 1.4.2 as itself. + major = minor; + minor = micro; + micro = 0; + } + _current = JDK_Version(major, minor, micro, info.update_version, + info.special_update_version, build, + info.thread_park_blocker == 1); } } +void JDK_Version::fully_initialize( + uint8_t major, uint8_t minor, uint8_t micro, uint8_t update) { + // This is only called when current is less than 1.6 and we've gotten + // far enough in the initialization to determine the exact version. + assert(major < 6, "not needed for JDK version >= 6"); + assert(is_partially_initialized(), "must not initialize"); + if (major < 5) { + // JDK verison sequence: 1.2.x, 1.3.x, 1.4.x, 5.0.x, 6.0.x, etc. + micro = minor; + minor = major; + major = 1; + } + _current = JDK_Version(major, minor, micro, update); +} + void JDK_Version_init() { JDK_Version::initialize(); } + +static int64_t encode_jdk_version(const JDK_Version& v) { + return + ((int64_t)v.major_version() << (BitsPerByte * 5)) | + ((int64_t)v.minor_version() << (BitsPerByte * 4)) | + ((int64_t)v.micro_version() << (BitsPerByte * 3)) | + ((int64_t)v.update_version() << (BitsPerByte * 2)) | + ((int64_t)v.special_update_version() << (BitsPerByte * 1)) | + ((int64_t)v.build_number() << (BitsPerByte * 0)); +} + +int JDK_Version::compare(const JDK_Version& other) const { + assert(is_valid() && other.is_valid(), "Invalid version (uninitialized?)"); + if (!is_partially_initialized() && other.is_partially_initialized()) { + return -(other.compare(*this)); // flip the comparators + } + assert(!other.is_partially_initialized(), "Not initialized yet"); + if (is_partially_initialized()) { + assert(other.major_version() >= 6, + "Invalid JDK version comparison during initialization"); + return -1; + } else { + uint64_t e = encode_jdk_version(*this); + uint64_t o = encode_jdk_version(other); + return (e > o) ? 1 : ((e == o) ? 0 : -1); + } +} + +void JDK_Version::to_string(char* buffer, size_t buflen) const { + size_t index = 0; + if (!is_valid()) { + jio_snprintf(buffer, buflen, "%s", "(uninitialized)"); + } else if (is_partially_initialized()) { + jio_snprintf(buffer, buflen, "%s", "(uninitialized) pre-1.6.0"); + } else { + index += jio_snprintf( + &buffer[index], buflen - index, "%d.%d", _major, _minor); + if (_micro > 0) { + index += jio_snprintf(&buffer[index], buflen - index, ".%d", _micro); + } + if (_update > 0) { + index += jio_snprintf(&buffer[index], buflen - index, "_%02d", _update); + } + if (_special > 0) { + index += jio_snprintf(&buffer[index], buflen - index, "%c", _special); + } + if (_build > 0) { + index += jio_snprintf(&buffer[index], buflen - index, "-b%02d", _build); + } + } +} diff --git a/hotspot/src/share/vm/runtime/java.hpp b/hotspot/src/share/vm/runtime/java.hpp index 160c62bb26a..0a557751619 100644 --- a/hotspot/src/share/vm/runtime/java.hpp +++ b/hotspot/src/share/vm/runtime/java.hpp @@ -48,100 +48,163 @@ extern void vm_exit_during_initialization(symbolHandle exception_name, const cha extern void vm_exit_during_initialization(const char* error, const char* message = NULL); extern void vm_shutdown_during_initialization(const char* error, const char* message = NULL); -class JDK_Version : AllStatic { +/** + * Discovering the JDK_Version during initialization is tricky when the + * running JDK is less than JDK6. For JDK6 and greater, a "GetVersion" + * function exists in libjava.so and we simply call it during the + * 'initialize()' call to find the version. For JDKs with version < 6, no + * such call exists and we have to probe the JDK in order to determine + * the exact version. This probing cannot happen during late in + * the VM initialization process so there's a period of time during + * initialization when we don't know anything about the JDK version other than + * that it less than version 6. This is the "partially initialized" time, + * when we can answer only certain version queries (such as, is the JDK + * version greater than 5? Answer: no). Once the JDK probing occurs, we + * know the version and are considered fully initialized. + */ +class JDK_Version VALUE_OBJ_CLASS_SPEC { friend class VMStructs; + friend class Universe; + friend void JDK_Version_init(); private: - static jdk_version_info _version_info; - static bool _pre_jdk16_version; - static int _jdk_version; // JDK version number representing the release - // i.e. n in 1.n.x (= jdk_minor_version()) + + static JDK_Version _current; + + // In this class, we promote the minor version of release to be the + // major version for releases >= 5 in anticipation of the JDK doing the + // same thing. For example, we represent "1.5.0" as major version 5 (we + // drop the leading 1 and use 5 as the 'major'). + + uint8_t _major; + uint8_t _minor; + uint8_t _micro; + uint8_t _update; + uint8_t _special; + uint8_t _build; + + // If partially initialized, the above fields are invalid and we know + // that we're less than major version 6. + bool _partially_initialized; + + bool _thread_park_blocker; + + bool is_valid() const { + return (_major != 0 || _partially_initialized); + } + + // initializes or partially initializes the _current static field + static void initialize(); + + // Completes initialization for a pre-JDK6 version. + static void fully_initialize(uint8_t major, uint8_t minor = 0, + uint8_t micro = 0, uint8_t update = 0); public: - static void initialize(); - static int jdk_major_version() { return JDK_VERSION_MAJOR(_version_info.jdk_version); } - static int jdk_minor_version() { return JDK_VERSION_MINOR(_version_info.jdk_version); } - static int jdk_micro_version() { return JDK_VERSION_MICRO(_version_info.jdk_version); } - static int jdk_build_number() { return JDK_VERSION_BUILD(_version_info.jdk_version); } - static bool is_pre_jdk16_version() { return _pre_jdk16_version; } - static bool is_jdk12x_version() { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 2; } - static bool is_jdk13x_version() { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 3; } - static bool is_jdk14x_version() { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 4; } - static bool is_jdk15x_version() { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 5; } + // Returns true if the the current version has only been partially initialized + static bool is_partially_initialized() { + return _current._partially_initialized; + } + + JDK_Version() : _major(0), _minor(0), _micro(0), _update(0), + _special(0), _build(0), _partially_initialized(false), + _thread_park_blocker(false) {} + + JDK_Version(uint8_t major, uint8_t minor = 0, uint8_t micro = 0, + uint8_t update = 0, uint8_t special = 0, uint8_t build = 0, + bool thread_park_blocker = false) : + _major(major), _minor(minor), _micro(micro), _update(update), + _special(special), _build(build), _partially_initialized(false), + _thread_park_blocker(thread_park_blocker) {} + + // Returns the current running JDK version + static JDK_Version current() { return _current; } + + // Factory methods for convenience + static JDK_Version jdk(uint8_t m) { + return JDK_Version(m); + } + + static JDK_Version jdk_update(uint8_t major, uint8_t update_number) { + return JDK_Version(major, 0, 0, update_number); + } + + uint8_t major_version() const { return _major; } + uint8_t minor_version() const { return _minor; } + uint8_t micro_version() const { return _micro; } + uint8_t update_version() const { return _update; } + uint8_t special_update_version() const { return _special; } + uint8_t build_number() const { return _build; } + + bool supports_thread_park_blocker() const { + return _thread_park_blocker; + } + + // Performs a full ordering comparison using all fields (update, build, etc.) + int compare(const JDK_Version& other) const; + + /** + * Performs comparison using only the major version, returning negative + * if the major version of 'this' is less than the parameter, 0 if it is + * equal, and a positive value if it is greater. + */ + int compare_major(int version) const { + if (_partially_initialized) { + if (version >= 6) { + return -1; + } else { + assert(false, "Can't make this comparison during init time"); + return -1; // conservative + } + } else { + return major_version() - version; + } + } + + void to_string(char* buffer, size_t buflen) const; + + // Convenience methods for queries on the current major/minor version + static bool is_jdk12x_version() { + return current().compare_major(2) == 0; + } + + static bool is_jdk13x_version() { + return current().compare_major(3) == 0; + } + + static bool is_jdk14x_version() { + return current().compare_major(4) == 0; + } + + static bool is_jdk15x_version() { + return current().compare_major(5) == 0; + } static bool is_jdk16x_version() { - if (is_jdk_version_initialized()) { - return _jdk_version == 6; - } else { - assert(is_pre_jdk16_version(), "must have been initialized"); - return false; - } + return current().compare_major(6) == 0; } static bool is_jdk17x_version() { - if (is_jdk_version_initialized()) { - return _jdk_version == 7; - } else { - assert(is_pre_jdk16_version(), "must have been initialized"); - return false; - } + return current().compare_major(7) == 0; } - static bool supports_thread_park_blocker() { return _version_info.thread_park_blocker; } + static bool is_gte_jdk13x_version() { + return current().compare_major(3) >= 0; + } static bool is_gte_jdk14x_version() { - // Keep the semantics of this that the version number is >= 1.4 - assert(is_jdk_version_initialized(), "Not initialized"); - return _jdk_version >= 4; + return current().compare_major(4) >= 0; } + static bool is_gte_jdk15x_version() { - // Keep the semantics of this that the version number is >= 1.5 - assert(is_jdk_version_initialized(), "Not initialized"); - return _jdk_version >= 5; + return current().compare_major(5) >= 0; } + static bool is_gte_jdk16x_version() { - // Keep the semantics of this that the version number is >= 1.6 - if (is_jdk_version_initialized()) { - return _jdk_version >= 6; - } else { - assert(is_pre_jdk16_version(), "Not initialized"); - return false; - } + return current().compare_major(6) >= 0; } static bool is_gte_jdk17x_version() { - // Keep the semantics of this that the version number is >= 1.7 - if (is_jdk_version_initialized()) { - return _jdk_version >= 7; - } else { - assert(is_pre_jdk16_version(), "Not initialized"); - return false; - } - } - - static bool is_jdk_version_initialized() { - return _jdk_version > 0; - } - - // These methods are defined to deal with pre JDK 1.6 versions - static void set_jdk12x_version() { - assert(_pre_jdk16_version && !is_jdk_version_initialized(), "must not initialize"); - _jdk_version = 2; - _version_info.jdk_version = (1 << 24) | (2 << 16); - } - static void set_jdk13x_version() { - assert(_pre_jdk16_version && !is_jdk_version_initialized(), "must not initialize"); - _jdk_version = 3; - _version_info.jdk_version = (1 << 24) | (3 << 16); - } - static void set_jdk14x_version() { - assert(_pre_jdk16_version && !is_jdk_version_initialized(), "must not initialize"); - _jdk_version = 4; - _version_info.jdk_version = (1 << 24) | (4 << 16); - } - static void set_jdk15x_version() { - assert(_pre_jdk16_version && !is_jdk_version_initialized(), "must not initialize"); - _jdk_version = 5; - _version_info.jdk_version = (1 << 24) | (5 << 16); + return current().compare_major(7) >= 0; } }; diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp index f276e7e7250..088a07ff45e 100644 --- a/hotspot/src/share/vm/runtime/os.cpp +++ b/hotspot/src/share/vm/runtime/os.cpp @@ -336,29 +336,38 @@ void* os::native_java_library() { char buffer[JVM_MAXPATHLEN]; char ebuf[1024]; - // Try to load verify dll first. In 1.3 java dll depends on it and is not always - // able to find it when the loading executable is outside the JDK. + // Try to load verify dll first. In 1.3 java dll depends on it and is not + // always able to find it when the loading executable is outside the JDK. // In order to keep working with 1.2 we ignore any loading errors. - hpi::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "verify"); - hpi::dll_load(buffer, ebuf, sizeof(ebuf)); + dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "verify"); + dll_load(buffer, ebuf, sizeof(ebuf)); // Load java dll - hpi::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "java"); - _native_java_library = hpi::dll_load(buffer, ebuf, sizeof(ebuf)); + dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "java"); + _native_java_library = dll_load(buffer, ebuf, sizeof(ebuf)); if (_native_java_library == NULL) { vm_exit_during_initialization("Unable to load native library", ebuf); } - // The JNI_OnLoad handling is normally done by method load in java.lang.ClassLoader$NativeLibrary, - // but the VM loads the base library explicitly so we have to check for JNI_OnLoad as well - const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS; - JNI_OnLoad_t JNI_OnLoad = CAST_TO_FN_PTR(JNI_OnLoad_t, hpi::dll_lookup(_native_java_library, onLoadSymbols[0])); - if (JNI_OnLoad != NULL) { - JavaThread* thread = JavaThread::current(); - ThreadToNativeFromVM ttn(thread); - HandleMark hm(thread); - jint ver = (*JNI_OnLoad)(&main_vm, NULL); - if (!Threads::is_supported_jni_version_including_1_1(ver)) { - vm_exit_during_initialization("Unsupported JNI version"); + } + static jboolean onLoaded = JNI_FALSE; + if (onLoaded) { + // We may have to wait to fire OnLoad until TLS is initialized. + if (ThreadLocalStorage::is_initialized()) { + // The JNI_OnLoad handling is normally done by method load in + // java.lang.ClassLoader$NativeLibrary, but the VM loads the base library + // explicitly so we have to check for JNI_OnLoad as well + const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS; + JNI_OnLoad_t JNI_OnLoad = CAST_TO_FN_PTR( + JNI_OnLoad_t, dll_lookup(_native_java_library, onLoadSymbols[0])); + if (JNI_OnLoad != NULL) { + JavaThread* thread = JavaThread::current(); + ThreadToNativeFromVM ttn(thread); + HandleMark hm(thread); + jint ver = (*JNI_OnLoad)(&main_vm, NULL); + onLoaded = JNI_TRUE; + if (!Threads::is_supported_jni_version_including_1_1(ver)) { + vm_exit_during_initialization("Unsupported JNI version"); + } } } } diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp index 0b8cea57884..8111d3937e4 100644 --- a/hotspot/src/share/vm/runtime/os.hpp +++ b/hotspot/src/share/vm/runtime/os.hpp @@ -390,6 +390,10 @@ class os: AllStatic { static const char* get_temp_directory(); static const char* get_current_directory(char *buf, int buflen); + // Builds a platform-specific full library path given a ld path and lib name + static void dll_build_name(char* buffer, size_t size, + const char* pathname, const char* fname); + // Symbol lookup, find nearest function name; basically it implements // dladdr() for all platforms. Name of the nearest function is copied // to buf. Distance from its base address is returned as offset. @@ -413,6 +417,9 @@ class os: AllStatic { // same architecture as Hotspot is running on static void* dll_load(const char *name, char *ebuf, int ebuflen); + // lookup symbol in a shared library + static void* dll_lookup(void* handle, const char* name); + // Print out system information; they are called by fatal error handler. // Output format may be different on different platforms. static void print_os_info(outputStream* st); diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index c488b3f2c52..85919814bee 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -2578,7 +2578,8 @@ void JavaThread::prepare(jobject jni_thread, ThreadPriority prio) { oop JavaThread::current_park_blocker() { // Support for JSR-166 locks oop thread_oop = threadObj(); - if (thread_oop != NULL && JDK_Version::supports_thread_park_blocker()) { + if (thread_oop != NULL && + JDK_Version::current().supports_thread_park_blocker()) { return java_lang_Thread::park_blocker(thread_oop); } return NULL; @@ -2761,6 +2762,8 @@ void Threads::threads_do(ThreadClosure* tc) { jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { + extern void JDK_Version_init(); + // Check version if (!is_supported_jni_version(args->version)) return JNI_EVERSION; @@ -2776,6 +2779,9 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { // Initialize system properties. Arguments::init_system_properties(); + // So that JDK version can be used as a discrimintor when parsing arguments + JDK_Version_init(); + // Parse arguments jint parse_result = Arguments::parse(args); if (parse_result != JNI_OK) return parse_result; diff --git a/hotspot/src/share/vm/runtime/threadLocalStorage.cpp b/hotspot/src/share/vm/runtime/threadLocalStorage.cpp index e00c7fe257b..2b2b8766f68 100644 --- a/hotspot/src/share/vm/runtime/threadLocalStorage.cpp +++ b/hotspot/src/share/vm/runtime/threadLocalStorage.cpp @@ -42,8 +42,13 @@ void ThreadLocalStorage::set_thread(Thread* thread) { } void ThreadLocalStorage::init() { - assert(ThreadLocalStorage::thread_index() == -1, "More than one attempt to initialize threadLocalStorage"); + assert(!is_initialized(), + "More than one attempt to initialize threadLocalStorage"); pd_init(); set_thread_index(os::allocate_thread_local_storage()); generate_code_for_get_thread(); } + +bool ThreadLocalStorage::is_initialized() { + return (thread_index() != -1); +} diff --git a/hotspot/src/share/vm/runtime/threadLocalStorage.hpp b/hotspot/src/share/vm/runtime/threadLocalStorage.hpp index e522d2791ab..e345baa27f7 100644 --- a/hotspot/src/share/vm/runtime/threadLocalStorage.hpp +++ b/hotspot/src/share/vm/runtime/threadLocalStorage.hpp @@ -47,6 +47,7 @@ class ThreadLocalStorage : AllStatic { // Initialization // Called explicitly from VMThread::activate_system instead of init_globals. static void init(); + static bool is_initialized(); private: static int _thread_index; diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index eeda67501aa..cb38e15d017 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -761,8 +761,9 @@ static inline uint64_t cast_uint64_t(size_t x) static_field(Abstract_VM_Version, _vm_minor_version, int) \ static_field(Abstract_VM_Version, _vm_build_number, int) \ \ - static_field(JDK_Version, _pre_jdk16_version, bool) \ - static_field(JDK_Version, _jdk_version, int) \ + static_field(JDK_Version, _current, JDK_Version) \ + nonstatic_field(JDK_Version, _partially_initialized, bool) \ + nonstatic_field(JDK_Version, _major, unsigned char) \ \ \ \ diff --git a/hotspot/src/share/vm/services/threadService.cpp b/hotspot/src/share/vm/services/threadService.cpp index 5084dbf0b4e..ee56b62f70a 100644 --- a/hotspot/src/share/vm/services/threadService.cpp +++ b/hotspot/src/share/vm/services/threadService.cpp @@ -744,7 +744,7 @@ ThreadSnapshot::ThreadSnapshot(JavaThread* thread) { } // Support for JSR-166 locks - if (JDK_Version::supports_thread_park_blocker() && + if (JDK_Version::current().supports_thread_park_blocker() && (_thread_status == java_lang_Thread::PARKED || _thread_status == java_lang_Thread::PARKED_TIMED)) { From 50c4a23cac0735e837d8779c3a0802c7b3d816d4 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Mon, 28 Jul 2008 17:12:52 -0700 Subject: [PATCH 16/52] 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.") Escape Analysis fixes. Reviewed-by: never, rasbold --- hotspot/src/share/vm/opto/c2_globals.hpp | 3 + hotspot/src/share/vm/opto/compile.cpp | 10 + hotspot/src/share/vm/opto/escape.cpp | 200 ++- hotspot/src/share/vm/opto/escape.hpp | 4 +- hotspot/src/share/vm/opto/lcm.cpp | 16 +- hotspot/src/share/vm/opto/loopopts.cpp | 3 +- hotspot/src/share/vm/opto/macro.cpp | 26 +- hotspot/src/share/vm/opto/memnode.cpp | 9 +- hotspot/src/share/vm/opto/memnode.hpp | 1 + hotspot/src/share/vm/opto/superword.cpp | 6 +- hotspot/src/share/vm/runtime/arguments.cpp | 3 + hotspot/test/compiler/6646019/Test.java | 31 +- hotspot/test/compiler/6689060/Test.java | 32 +- hotspot/test/compiler/6695810/Test.java | 32 +- hotspot/test/compiler/6726999/Test.java | 1419 ++++++++++++++++++++ 15 files changed, 1680 insertions(+), 115 deletions(-) create mode 100644 hotspot/test/compiler/6726999/Test.java diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp index 089a8847b53..0f09eaf837c 100644 --- a/hotspot/src/share/vm/opto/c2_globals.hpp +++ b/hotspot/src/share/vm/opto/c2_globals.hpp @@ -388,6 +388,9 @@ product(intx, EliminateAllocationArraySizeLimit, 64, \ "Array size (number of elements) limit for scalar replacement") \ \ + product(intx, ValueSearchLimit, 1000, \ + "Recursion limit in PhaseMacroExpand::value_from_mem_phi") \ + \ product(intx, MaxLabelRootDepth, 1100, \ "Maximum times call Label_Root to prevent stack overflow") \ \ diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp index c57a460d45d..ec28d079955 100644 --- a/hotspot/src/share/vm/opto/compile.cpp +++ b/hotspot/src/share/vm/opto/compile.cpp @@ -585,6 +585,10 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr // Perform escape analysis if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) { TracePhase t2("escapeAnalysis", &_t_escapeAnalysis, true); + // Add ConP#NULL and ConN#NULL nodes before ConnectionGraph construction. + PhaseGVN* igvn = initial_gvn(); + Node* oop_null = igvn->zerocon(T_OBJECT); + Node* noop_null = igvn->zerocon(T_NARROWOOP); _congraph = new(comp_arena()) ConnectionGraph(this); bool has_non_escaping_obj = _congraph->compute_escape(); @@ -594,6 +598,12 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr _congraph->dump(); } #endif + // Cleanup. + if (oop_null->outcnt() == 0) + igvn->hash_delete(oop_null); + if (noop_null->outcnt() == 0) + igvn->hash_delete(noop_null); + if (!has_non_escaping_obj) { _congraph = NULL; } diff --git a/hotspot/src/share/vm/opto/escape.cpp b/hotspot/src/share/vm/opto/escape.cpp index 8a779f59431..fece33098fb 100644 --- a/hotspot/src/share/vm/opto/escape.cpp +++ b/hotspot/src/share/vm/opto/escape.cpp @@ -62,10 +62,14 @@ static const char *edge_type_suffix[] = { "F" // FieldEdge }; -void PointsToNode::dump() const { +void PointsToNode::dump(bool print_state) const { NodeType nt = node_type(); - EscapeState es = escape_state(); - tty->print("%s %s %s [[", node_type_names[(int) nt], esc_names[(int) es], _scalar_replaceable ? "" : "NSR"); + tty->print("%s ", node_type_names[(int) nt]); + if (print_state) { + EscapeState es = escape_state(); + tty->print("%s %s ", esc_names[(int) es], _scalar_replaceable ? "":"NSR"); + } + tty->print("[["); for (uint i = 0; i < edge_count(); i++) { tty->print(" %d%s", edge_target(i), edge_type_suffix[(int) edge_type(i)]); } @@ -84,11 +88,22 @@ ConnectionGraph::ConnectionGraph(Compile * C) : _compile(C), _node_map(C->comp_arena()) { - _phantom_object = C->top()->_idx; - PointsToNode *phn = ptnode_adr(_phantom_object); - phn->_node = C->top(); - phn->set_node_type(PointsToNode::JavaObject); - phn->set_escape_state(PointsToNode::GlobalEscape); + _phantom_object = C->top()->_idx, + add_node(C->top(), PointsToNode::JavaObject, PointsToNode::GlobalEscape,true); + + // Add ConP(#NULL) and ConN(#NULL) nodes. + PhaseGVN* igvn = C->initial_gvn(); + Node* oop_null = igvn->zerocon(T_OBJECT); + _oop_null = oop_null->_idx; + assert(_oop_null < C->unique(), "should be created already"); + add_node(oop_null, PointsToNode::JavaObject, PointsToNode::NoEscape, true); + + if (UseCompressedOops) { + Node* noop_null = igvn->zerocon(T_NARROWOOP); + _noop_null = noop_null->_idx; + assert(_noop_null < C->unique(), "should be created already"); + add_node(noop_null, PointsToNode::JavaObject, PointsToNode::NoEscape, true); + } } void ConnectionGraph::add_pointsto_edge(uint from_i, uint to_i) { @@ -500,29 +515,30 @@ void ConnectionGraph::split_AddP(Node *addp, Node *base, PhaseGVN *igvn) { igvn->set_type(addp, tinst); // record the allocation in the node map set_map(addp->_idx, get_map(base->_idx)); - // if the Address input is not the appropriate instance type - // (due to intervening casts,) insert a cast - Node *adr = addp->in(AddPNode::Address); - const TypeOopPtr *atype = igvn->type(adr)->isa_oopptr(); - if (atype != NULL && atype->instance_id() != inst_id) { - assert(!atype->is_known_instance(), "no conflicting instances"); - const TypeOopPtr *new_atype = base_t->add_offset(atype->offset())->isa_oopptr(); - Node *acast = new (_compile, 2) CastPPNode(adr, new_atype); - acast->set_req(0, adr->in(0)); - igvn->set_type(acast, new_atype); - record_for_optimizer(acast); - Node *bcast = acast; - Node *abase = addp->in(AddPNode::Base); - if (abase != adr) { - bcast = new (_compile, 2) CastPPNode(abase, base_t); - bcast->set_req(0, abase->in(0)); - igvn->set_type(bcast, base_t); - record_for_optimizer(bcast); + + // Set addp's Base and Address to 'base'. + Node *abase = addp->in(AddPNode::Base); + Node *adr = addp->in(AddPNode::Address); + if (adr->is_Proj() && adr->in(0)->is_Allocate() && + adr->in(0)->_idx == (uint)inst_id) { + // Skip AddP cases #3 and #5. + } else { + assert(!abase->is_top(), "sanity"); // AddP case #3 + if (abase != base) { + igvn->hash_delete(addp); + addp->set_req(AddPNode::Base, base); + if (abase == adr) { + addp->set_req(AddPNode::Address, base); + } else { + // AddP case #4 (adr is array's element offset AddP node) +#ifdef ASSERT + const TypeOopPtr *atype = igvn->type(adr)->isa_oopptr(); + assert(adr->is_AddP() && atype != NULL && + atype->instance_id() == inst_id, "array's element offset should be processed first"); +#endif + } + igvn->hash_insert(addp); } - igvn->hash_delete(addp); - addp->set_req(AddPNode::Base, bcast); - addp->set_req(AddPNode::Address, acast); - igvn->hash_insert(addp); } // Put on IGVN worklist since at least addp's type was changed above. record_for_optimizer(addp); @@ -660,27 +676,31 @@ Node* ConnectionGraph::find_inst_mem(Node *orig_mem, int alias_idx, GrowableArra Compile* C = phase->C; const TypeOopPtr *tinst = C->get_adr_type(alias_idx)->isa_oopptr(); bool is_instance = (tinst != NULL) && tinst->is_known_instance(); + Node *start_mem = C->start()->proj_out(TypeFunc::Memory); Node *prev = NULL; Node *result = orig_mem; while (prev != result) { prev = result; + if (result == start_mem) + break; // hit one of our sentinals if (result->is_Mem()) { - MemNode *mem = result->as_Mem(); - const Type *at = phase->type(mem->in(MemNode::Address)); + const Type *at = phase->type(result->in(MemNode::Address)); if (at != Type::TOP) { assert (at->isa_ptr() != NULL, "pointer type required."); int idx = C->get_alias_index(at->is_ptr()); if (idx == alias_idx) break; } - result = mem->in(MemNode::Memory); + result = result->in(MemNode::Memory); } if (!is_instance) continue; // don't search further for non-instance types // skip over a call which does not affect this memory slice if (result->is_Proj() && result->as_Proj()->_con == TypeFunc::Memory) { Node *proj_in = result->in(0); - if (proj_in->is_Call()) { + if (proj_in->is_Allocate() && proj_in->_idx == (uint)tinst->instance_id()) { + break; // hit one of our sentinals + } else if (proj_in->is_Call()) { CallNode *call = proj_in->as_Call(); if (!call->may_modify(tinst, phase)) { result = call->in(TypeFunc::Memory); @@ -1006,12 +1026,12 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) memnode_worklist.append_if_missing(use); } else if (use->is_MergeMem()) { mergemem_worklist.append_if_missing(use); - } else if (use->is_Call() && tinst != NULL) { + } else if (use->is_SafePoint() && tinst != NULL) { // Look for MergeMem nodes for calls which reference unique allocation // (through CheckCastPP nodes) even for debug info. Node* m = use->in(TypeFunc::Memory); uint iid = tinst->instance_id(); - while (m->is_Proj() && m->in(0)->is_Call() && + while (m->is_Proj() && m->in(0)->is_SafePoint() && m->in(0) != use && !m->in(0)->_idx != iid) { m = m->in(0)->in(TypeFunc::Memory); } @@ -1348,15 +1368,95 @@ bool ConnectionGraph::compute_escape() { remove_deferred(ni, &deferred_edges, &visited); Node *n = ptn->_node; if (n->is_AddP()) { - // If this AddP computes an address which may point to more that one - // object or more then one field (array's element), nothing the address - // points to can be scalar replaceable. + // Search for objects which are not scalar replaceable. + // Mark their escape state as ArgEscape to propagate the state + // to referenced objects. + // Note: currently there are no difference in compiler optimizations + // for ArgEscape objects and NoEscape objects which are not + // scalar replaceable. + + int offset = ptn->offset(); Node *base = get_addp_base(n); ptset.Clear(); PointsTo(ptset, base, igvn); - if (ptset.Size() > 1 || - (ptset.Size() != 0 && ptn->offset() == Type::OffsetBot)) { + int ptset_size = ptset.Size(); + + // Check if a field's initializing value is recorded and add + // a corresponding NULL field's value if it is not recorded. + // Connection Graph does not record a default initialization by NULL + // captured by Initialize node. + // + // Note: it will disable scalar replacement in some cases: + // + // Point p[] = new Point[1]; + // p[0] = new Point(); // Will be not scalar replaced + // + // but it will save us from incorrect optimizations in next cases: + // + // Point p[] = new Point[1]; + // if ( x ) p[0] = new Point(); // Will be not scalar replaced + // + // Without a control flow analysis we can't distinguish above cases. + // + if (offset != Type::OffsetBot && ptset_size == 1) { + uint elem = ptset.getelem(); // Allocation node's index + // It does not matter if it is not Allocation node since + // only non-escaping allocations are scalar replaced. + if (ptnode_adr(elem)->_node->is_Allocate() && + ptnode_adr(elem)->escape_state() == PointsToNode::NoEscape) { + AllocateNode* alloc = ptnode_adr(elem)->_node->as_Allocate(); + InitializeNode* ini = alloc->initialization(); + Node* value = NULL; + if (ini != NULL) { + BasicType ft = UseCompressedOops ? T_NARROWOOP : T_OBJECT; + Node* store = ini->find_captured_store(offset, type2aelembytes(ft), igvn); + if (store != NULL && store->is_Store()) + value = store->in(MemNode::ValueIn); + } + if (value == NULL || value != ptnode_adr(value->_idx)->_node) { + // A field's initializing value was not recorded. Add NULL. + uint null_idx = UseCompressedOops ? _noop_null : _oop_null; + add_pointsto_edge(ni, null_idx); + } + } + } + + // An object is not scalar replaceable if the field which may point + // to it has unknown offset (unknown element of an array of objects). + // + if (offset == Type::OffsetBot) { + uint e_cnt = ptn->edge_count(); + for (uint ei = 0; ei < e_cnt; ei++) { + uint npi = ptn->edge_target(ei); + set_escape_state(npi, PointsToNode::ArgEscape); + ptnode_adr(npi)->_scalar_replaceable = false; + } + } + + // Currently an object is not scalar replaceable if a LoadStore node + // access its field since the field value is unknown after it. + // + bool has_LoadStore = false; + for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { + Node *use = n->fast_out(i); + if (use->is_LoadStore()) { + has_LoadStore = true; + break; + } + } + // An object is not scalar replaceable if the address points + // to unknown field (unknown element for arrays, offset is OffsetBot). + // + // Or the address may point to more then one object. This may produce + // the false positive result (set scalar_replaceable to false) + // since the flow-insensitive escape analysis can't separate + // the case when stores overwrite the field's value from the case + // when stores happened on different control branches. + // + if (ptset_size > 1 || ptset_size != 0 && + (has_LoadStore || offset == Type::OffsetBot)) { for( VectorSetI j(&ptset); j.test(); ++j ) { + set_escape_state(j.elem, PointsToNode::ArgEscape); ptnode_adr(j.elem)->_scalar_replaceable = false; } } @@ -1855,7 +1955,7 @@ void ConnectionGraph::record_for_escape_analysis(Node *n, PhaseTransform *phase) case Op_LoadN: { const Type *t = phase->type(n); - if (!t->isa_narrowoop() && t->isa_ptr() == NULL) { + if (t->make_ptr() == NULL) { _processed.set(n->_idx); return; } @@ -1878,8 +1978,9 @@ void ConnectionGraph::record_for_escape_analysis(Node *n, PhaseTransform *phase) } case Op_Phi: { - if (n->as_Phi()->type()->isa_ptr() == NULL) { - // nothing to do if not an oop + const Type *t = n->as_Phi()->type(); + if (t->make_ptr() == NULL) { + // nothing to do if not an oop or narrow oop _processed.set(n->_idx); return; } @@ -2067,7 +2168,7 @@ void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) { { const Type *t = phase->type(n); #ifdef ASSERT - if (!t->isa_narrowoop() && t->isa_ptr() == NULL) + if (t->make_ptr() == NULL) assert(false, "Op_LoadP"); #endif @@ -2099,7 +2200,8 @@ void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) { case Op_Phi: { #ifdef ASSERT - if (n->as_Phi()->type()->isa_ptr() == NULL) + const Type *t = n->as_Phi()->type(); + if (t->make_ptr() == NULL) assert(false, "Op_Phi"); #endif for (uint i = 1; i < n->req() ; i++) { @@ -2213,16 +2315,14 @@ void ConnectionGraph::dump() { PointsToNode::NodeType ptn_loc_type = ptn_loc->node_type(); if ( ptn_loc_type == PointsToNode::LocalVar && ptn_loc->_node != NULL && ptn_loc->edge_count() == 1 && ptn_loc->edge_target(0) == ni ) { - tty->print("%6d LocalVar [[%d]]", li, ni); - ptnode_adr(li)->_node->dump(); + ptnode_adr(li)->dump(false); } } if (Verbose) { // Print all fields which reference this allocation for (uint i = 0; i < ptn->edge_count(); i++) { uint ei = ptn->edge_target(i); - tty->print("%6d Field [[%d]]", ei, ni); - ptnode_adr(ei)->_node->dump(); + ptnode_adr(ei)->dump(false); } } tty->cr(); diff --git a/hotspot/src/share/vm/opto/escape.hpp b/hotspot/src/share/vm/opto/escape.hpp index 0135aab828d..93cfd0ec89d 100644 --- a/hotspot/src/share/vm/opto/escape.hpp +++ b/hotspot/src/share/vm/opto/escape.hpp @@ -197,7 +197,7 @@ public: void remove_edge(uint targIdx, EdgeType et); #ifndef PRODUCT - void dump() const; + void dump(bool print_state=true) const; #endif }; @@ -221,6 +221,8 @@ private: // that pointer values loaded from // a field which has not been set // are assumed to point to. + uint _oop_null; // ConP(#NULL) + uint _noop_null; // ConN(#NULL) Compile * _compile; // Compile object for current compilation diff --git a/hotspot/src/share/vm/opto/lcm.cpp b/hotspot/src/share/vm/opto/lcm.cpp index 9be6e270faa..0bcb9923cb5 100644 --- a/hotspot/src/share/vm/opto/lcm.cpp +++ b/hotspot/src/share/vm/opto/lcm.cpp @@ -322,7 +322,7 @@ Node *Block::select(PhaseCFG *cfg, Node_List &worklist, int *ready_cnt, VectorSe uint choice = 0; // Bigger is most important uint latency = 0; // Bigger is scheduled first uint score = 0; // Bigger is better - uint idx; // Index in worklist + int idx = -1; // Index in worklist for( uint i=0; i= 0, "index should be set"); + Node *n = worklist[(uint)idx]; // Get the winner - worklist.map(idx,worklist.pop()); // Compress worklist + worklist.map((uint)idx, worklist.pop()); // Compress worklist return n; } @@ -599,7 +600,14 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, int *ready_cnt, Vect assert(cfg->_bbs[oop_store->_idx]->_dom_depth <= this->_dom_depth, "oop_store must dominate card-mark"); } } - if( n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_MemBarAcquire ) { + if( n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_MemBarAcquire && + n->req() > TypeFunc::Parms ) { + // MemBarAcquire could be created without Precedent edge. + // del_req() replaces the specified edge with the last input edge + // and then removes the last edge. If the specified edge > number of + // edges the last edge will be moved outside of the input edges array + // and the edge will be lost. This is why this code should be + // executed only when Precedent (== TypeFunc::Parms) edge is present. Node *x = n->in(TypeFunc::Parms); n->del_req(TypeFunc::Parms); n->add_prec(x); diff --git a/hotspot/src/share/vm/opto/loopopts.cpp b/hotspot/src/share/vm/opto/loopopts.cpp index 4353219f41c..3ac320cbfc3 100644 --- a/hotspot/src/share/vm/opto/loopopts.cpp +++ b/hotspot/src/share/vm/opto/loopopts.cpp @@ -578,7 +578,8 @@ Node *PhaseIdealLoop::split_if_with_blocks_pre( Node *n ) { Node *cmov = conditional_move( n ); if( cmov ) return cmov; } - if( n->is_CFG() || n_op == Op_StorePConditional || n_op == Op_StoreLConditional || n_op == Op_CompareAndSwapI || n_op == Op_CompareAndSwapL ||n_op == Op_CompareAndSwapP) return n; + if( n->is_CFG() || n->is_LoadStore() ) + return n; if( n_op == Op_Opaque1 || // Opaque nodes cannot be mod'd n_op == Op_Opaque2 ) { if( !C->major_progress() ) // If chance of no more loop opts... diff --git a/hotspot/src/share/vm/opto/macro.cpp b/hotspot/src/share/vm/opto/macro.cpp index 3e036249edd..c496c8fd98a 100644 --- a/hotspot/src/share/vm/opto/macro.cpp +++ b/hotspot/src/share/vm/opto/macro.cpp @@ -194,9 +194,10 @@ void PhaseMacroExpand::eliminate_card_mark(Node *p2x) { } // Search for a memory operation for the specified memory slice. -static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_mem, Node *alloc) { +static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_mem, Node *alloc, PhaseGVN *phase) { Node *orig_mem = mem; Node *alloc_mem = alloc->in(TypeFunc::Memory); + const TypeOopPtr *tinst = phase->C->get_adr_type(alias_idx)->isa_oopptr(); while (true) { if (mem == alloc_mem || mem == start_mem ) { return mem; // hit one of our sentinals @@ -208,7 +209,13 @@ static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_me // already know that the object is safe to eliminate. if (in->is_Initialize() && in->as_Initialize()->allocation() == alloc) { return in; - } else if (in->is_Call() || in->is_MemBar()) { + } else if (in->is_Call()) { + CallNode *call = in->as_Call(); + if (!call->may_modify(tinst, phase)) { + mem = call->in(TypeFunc::Memory); + } + mem = in->in(TypeFunc::Memory); + } else if (in->is_MemBar()) { mem = in->in(TypeFunc::Memory); } else { assert(false, "unexpected projection"); @@ -265,7 +272,7 @@ Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type * } if (level <= 0) { - return NULL; + return NULL; // Give up: phi tree too deep } Node *start_mem = C->start()->proj_out(TypeFunc::Memory); Node *alloc_mem = alloc->in(TypeFunc::Memory); @@ -283,7 +290,7 @@ Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type * if (in == NULL || in->is_top()) { values.at_put(j, in); } else { - Node *val = scan_mem_chain(in, alias_idx, offset, start_mem, alloc); + Node *val = scan_mem_chain(in, alias_idx, offset, start_mem, alloc, &_igvn); if (val == start_mem || val == alloc_mem) { // hit a sentinel, return appropriate 0 value values.at_put(j, _igvn.zerocon(ft)); @@ -308,7 +315,8 @@ Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type * } values.at_put(j, val); } else { - return NULL; // unknown node on this path + assert(false, "unknown node on this path"); + return NULL; // unknown node on this path } } } @@ -344,7 +352,7 @@ Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, BasicType ft, const Type if (visited.test_set(mem->_idx)) { return NULL; // found a loop, give up } - mem = scan_mem_chain(mem, alias_idx, offset, start_mem, alloc); + mem = scan_mem_chain(mem, alias_idx, offset, start_mem, alloc, &_igvn); if (mem == start_mem || mem == alloc_mem) { done = true; // hit a sentinel, return appropriate 0 value } else if (mem->is_Initialize()) { @@ -368,7 +376,7 @@ Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, BasicType ft, const Type Node *unique_input = NULL; Node *top = C->top(); for (uint i = 1; i < mem->req(); i++) { - Node *n = scan_mem_chain(mem->in(i), alias_idx, offset, start_mem, alloc); + Node *n = scan_mem_chain(mem->in(i), alias_idx, offset, start_mem, alloc, &_igvn); if (n == NULL || n == top || n == mem) { continue; } else if (unique_input == NULL) { @@ -396,7 +404,7 @@ Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, BasicType ft, const Type } else if (mem->is_Phi()) { // attempt to produce a Phi reflecting the values on the input paths of the Phi Node_Stack value_phis(a, 8); - Node * phi = value_from_mem_phi(mem, ft, ftype, adr_t, alloc, &value_phis, 8); + Node * phi = value_from_mem_phi(mem, ft, ftype, adr_t, alloc, &value_phis, ValueSearchLimit); if (phi != NULL) { return phi; } else { @@ -463,7 +471,7 @@ bool PhaseMacroExpand::can_eliminate_allocation(AllocateNode *alloc, GrowableArr Node* n = use->fast_out(k); if (!n->is_Store() && n->Opcode() != Op_CastP2X) { DEBUG_ONLY(disq_node = n;) - if (n->is_Load()) { + if (n->is_Load() || n->is_LoadStore()) { NOT_PRODUCT(fail_eliminate = "Field load";) } else { NOT_PRODUCT(fail_eliminate = "Not store field referrence";) diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp index 8388753e937..edbadc5a09b 100644 --- a/hotspot/src/share/vm/opto/memnode.cpp +++ b/hotspot/src/share/vm/opto/memnode.cpp @@ -94,14 +94,19 @@ Node *MemNode::optimize_simple_memory_chain(Node *mchain, const TypePtr *t_adr, if (tinst == NULL || !tinst->is_known_instance_field()) return mchain; // don't try to optimize non-instance types uint instance_id = tinst->instance_id(); + Node *start_mem = phase->C->start()->proj_out(TypeFunc::Memory); Node *prev = NULL; Node *result = mchain; while (prev != result) { prev = result; + if (result == start_mem) + break; // hit one of our sentinals // skip over a call which does not affect this memory slice if (result->is_Proj() && result->as_Proj()->_con == TypeFunc::Memory) { Node *proj_in = result->in(0); - if (proj_in->is_Call()) { + if (proj_in->is_Allocate() && proj_in->_idx == instance_id) { + break; // hit one of our sentinals + } else if (proj_in->is_Call()) { CallNode *call = proj_in->as_Call(); if (!call->may_modify(t_adr, phase)) { result = call->in(TypeFunc::Memory); @@ -115,6 +120,8 @@ Node *MemNode::optimize_simple_memory_chain(Node *mchain, const TypePtr *t_adr, } } else if (proj_in->is_MemBar()) { result = proj_in->in(TypeFunc::Memory); + } else { + assert(false, "unexpected projection"); } } else if (result->is_MergeMem()) { result = step_through_mergemem(phase, result->as_MergeMem(), t_adr, NULL, tty); diff --git a/hotspot/src/share/vm/opto/memnode.hpp b/hotspot/src/share/vm/opto/memnode.hpp index 891b9f64a87..dff9dad102e 100644 --- a/hotspot/src/share/vm/opto/memnode.hpp +++ b/hotspot/src/share/vm/opto/memnode.hpp @@ -607,6 +607,7 @@ public: }; //------------------------------LoadStoreNode--------------------------- +// Note: is_Mem() method returns 'true' for this class. class LoadStoreNode : public Node { public: enum { diff --git a/hotspot/src/share/vm/opto/superword.cpp b/hotspot/src/share/vm/opto/superword.cpp index 593d5dd2dd0..acc8248500d 100644 --- a/hotspot/src/share/vm/opto/superword.cpp +++ b/hotspot/src/share/vm/opto/superword.cpp @@ -1196,8 +1196,10 @@ void SuperWord::construct_bb() { Node *n = lp()->fast_out(i); if (in_bb(n) && (n->is_Phi() && n->bottom_type() == Type::MEMORY)) { Node* n_tail = n->in(LoopNode::LoopBackControl); - _mem_slice_head.push(n); - _mem_slice_tail.push(n_tail); + if (n_tail != n->in(LoopNode::EntryControl)) { + _mem_slice_head.push(n); + _mem_slice_tail.push(n_tail); + } } } diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 421eae2cf0b..e9f7abeebe0 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -2472,6 +2472,9 @@ jint Arguments::parse(const JavaVMInitArgs* args) { if (match_option(option, "-XX:+PrintVMOptions", &tail)) { PrintVMOptions = true; } + if (match_option(option, "-XX:-PrintVMOptions", &tail)) { + PrintVMOptions = false; + } } // Parse default .hotspotrc settings file diff --git a/hotspot/test/compiler/6646019/Test.java b/hotspot/test/compiler/6646019/Test.java index e724394ff57..99c07617e04 100644 --- a/hotspot/test/compiler/6646019/Test.java +++ b/hotspot/test/compiler/6646019/Test.java @@ -1,23 +1,24 @@ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * - * - * - * + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. * */ diff --git a/hotspot/test/compiler/6689060/Test.java b/hotspot/test/compiler/6689060/Test.java index f6361aee067..4d3f2003baa 100644 --- a/hotspot/test/compiler/6689060/Test.java +++ b/hotspot/test/compiler/6689060/Test.java @@ -1,24 +1,24 @@ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. * */ diff --git a/hotspot/test/compiler/6695810/Test.java b/hotspot/test/compiler/6695810/Test.java index 77297671082..f59db440083 100644 --- a/hotspot/test/compiler/6695810/Test.java +++ b/hotspot/test/compiler/6695810/Test.java @@ -1,24 +1,24 @@ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. * */ diff --git a/hotspot/test/compiler/6726999/Test.java b/hotspot/test/compiler/6726999/Test.java new file mode 100644 index 00000000000..69bd2f76cc0 --- /dev/null +++ b/hotspot/test/compiler/6726999/Test.java @@ -0,0 +1,1419 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +/* + * @test + * @bug 6726999 + * @summary nsk/stress/jck12a/jck12a010 assert(n != NULL,"Bad immediate dominator info."); + * @run main/othervm -Xbatch -XX:CompileCommand=exclude,Test.dummy -XX:+AggressiveOpts Test + */ + +import java.lang.reflect.Array; + +class Point { + int x; + int y; +} + +public class Test { + + void dummy() { + // Empty method to verify correctness of DebugInfo. + // Use -XX:CompileCommand=exclude,Test.dummy + } + + int test0_0_0(int y) { + int x = 3; + Point p = new Point(); + dummy(); + p.x = x; + p.y = 3 * x + y; + return p.x * p.y; + } + + int test0_0_1(int y) { + int x = 3; + Point p = null; + dummy(); + p = new Point(); + dummy(); + p.x = x; + p.y = 3 * x + y; + return p.x * p.y; + } + + int test0_0_2(int y) { + int x = 3; + Point p = new Point(); + dummy(); + p = new Point(); + dummy(); + p.x = x; + p.y = 3 * x + y; + return p.x * p.y; + } + + int test0_0_3(int y) { + int x = 3; + Point p[] = new Point[1]; + p[0] = new Point(); + dummy(); + p[0].x = x; + p[0].y = 3 * x + y; + return p[0].x * p[0].y; + } + + int test0_0_4(int y) { + int x = 3; + Point p[] = new Point[1]; + dummy(); + p[0] = new Point(); + dummy(); + p[0].x = x; + p[0].y = 3 * x + y; + return p[0].x * p[0].y; + } + + int test0_0_5(int y) { + int x = 3; + Point p[] = new Point[1]; + dummy(); + p[0] = null; + dummy(); + p[0] = new Point(); + dummy(); + p[0].x = x; + p[0].y = 3 * x + y; + return p[0].x * p[0].y; + } + + int test0_0_6(int y) { + int x = 3; + Point p[] = new Point[1]; + p[0] = new Point(); + dummy(); + p[0] = new Point(); + dummy(); + p[0].x = x; + p[0].y = 3 * x + y; + return p[0].x * p[0].y; + } + + int test0_1_3(int y) { + int x = 3; + Point p1 = new Point(); + dummy(); + Point p[] = new Point[1]; + p[0] = p1; + dummy(); + p[0].x = x; + p[0].y = 3 * x + y; + return p[0].x * p[0].y; + } + + int test0_1_4(int y) { + int x = 3; + Point p1 = new Point(); + dummy(); + Point p[] = new Point[1]; + dummy(); + p[0] = p1; + dummy(); + p[0].x = x; + p[0].y = 3 * x + y; + return p[0].x * p[0].y; + } + + int test0_1_5(int y) { + int x = 3; + Point p1 = new Point(); + dummy(); + Point p[] = new Point[1]; + dummy(); + p[0] = null; + dummy(); + p[0] = p1; + dummy(); + p[0].x = x; + p[0].y = 3 * x + y; + return p[0].x * p[0].y; + } + + int test0_1_6(int y) { + int x = 3; + Point p1 = new Point(); + dummy(); + Point p2 = new Point(); + dummy(); + Point p[] = new Point[1]; + p[0] = p1; + dummy(); + p[0] = p2; + dummy(); + p[0].x = x; + p[0].y = 3 * x + y; + return p[0].x * p[0].y; + } + + int test1_0_0(int y) { + Point p = new Point(); + if ( (y & 1) == 1 ) { + p = new Point(); + } + int x = 3; + p.x = x; + p.y = 3 * x + y; + dummy(); + return p.x * p.y; + } + + int test1_0_1(int y) { + Point p = null; + if ( (y & 1) == 1 ) { + p = new Point(); + } + int x = 3; + if ( p == null ) + return (3 * x + y) * x; + p.x = x; + p.y = 3 * x + y; + dummy(); + return p.x * p.y; + } + + int test1_0_2(int y) { + Point p[] = new Point[1]; + if ( (y & 1) == 1 ) { + p[0] = new Point(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_0_3(int y) { + Point p[] = new Point[1]; + p[0] = null; + if ( (y & 1) == 1 ) { + p[0] = new Point(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_0_4(int y) { + Point p[] = new Point[1]; + p[0] = new Point(); + if ( (y & 1) == 1 ) { + p[0] = new Point(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_0_5(int y) { + Point p[] = new Point[1]; + if ( (y & 1) == 1 ) { + p[0] = new Point(); + } else { + p[0] = null; + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_0_6(int y) { + Point p[] = new Point[1]; + if ( (y & 1) == 1 ) { + p[0] = new Point(); + } else { + p[0] = new Point(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_1_0(int y) { + Point p = new Point(); + if ( (y & 1) == 1 ) { + dummy(); + p = new Point(); + dummy(); + } + int x = 3; + p.x = x; + p.y = 3 * x + y; + dummy(); + return p.x * p.y; + } + + int test1_1_1(int y) { + Point p = null; + if ( (y & 1) == 1 ) { + dummy(); + p = new Point(); + dummy(); + } + int x = 3; + if ( p == null ) + return (3 * x + y) * x; + p.x = x; + p.y = 3 * x + y; + dummy(); + return p.x * p.y; + } + + int test1_1_2(int y) { + Point p[] = new Point[1]; + if ( (y & 1) == 1 ) { + dummy(); + p[0] = new Point(); + dummy(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_1_3(int y) { + Point p[] = new Point[1]; + dummy(); + p[0] = null; + if ( (y & 1) == 1 ) { + dummy(); + p[0] = new Point(); + dummy(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_1_4(int y) { + Point p[] = new Point[1]; + dummy(); + p[0] = new Point(); + if ( (y & 1) == 1 ) { + dummy(); + p[0] = new Point(); + dummy(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_1_5(int y) { + Point p[] = new Point[1]; + if ( (y & 1) == 1 ) { + dummy(); + p[0] = new Point(); + dummy(); + } else { + dummy(); + p[0] = null; + dummy(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_1_6(int y) { + Point p[] = new Point[1]; + if ( (y & 1) == 1 ) { + dummy(); + p[0] = new Point(); + dummy(); + } else { + dummy(); + p[0] = new Point(); + dummy(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_2_0(int y) { + Point p1 = new Point(); + dummy(); + Point p = new Point(); + if ( (y & 1) == 1 ) { + dummy(); + p = p1; + dummy(); + } + int x = 3; + p.x = x; + p.y = 3 * x + y; + dummy(); + return p.x * p.y; + } + + int test1_2_1(int y) { + Point p1 = new Point(); + dummy(); + Point p = null; + if ( (y & 1) == 1 ) { + dummy(); + p = p1; + dummy(); + } + int x = 3; + if ( p == null ) + return (3 * x + y) * x; + p.x = x; + p.y = 3 * x + y; + dummy(); + return p.x * p.y; + } + + int test1_2_2(int y) { + Point p1 = new Point(); + dummy(); + Point p[] = new Point[1]; + if ( (y & 1) == 1 ) { + dummy(); + p[0] = p1; + dummy(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_2_3(int y) { + Point p1 = new Point(); + dummy(); + Point p[] = new Point[1]; + dummy(); + p[0] = null; + if ( (y & 1) == 1 ) { + dummy(); + p[0] = p1; + dummy(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_2_4(int y) { + Point p1 = new Point(); + dummy(); + Point p2 = new Point(); + dummy(); + Point p[] = new Point[1]; + dummy(); + p[0] = p1; + if ( (y & 1) == 1 ) { + dummy(); + p[0] = p2; + dummy(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_2_5(int y) { + Point p1 = new Point(); + dummy(); + Point p[] = new Point[1]; + if ( (y & 1) == 1 ) { + dummy(); + p[0] = p1; + dummy(); + } else { + dummy(); + p[0] = null; + dummy(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_2_6(int y) { + Point p1 = new Point(); + dummy(); + Point p2 = new Point(); + dummy(); + Point p[] = new Point[1]; + if ( (y & 1) == 1 ) { + dummy(); + p[0] = p1; + dummy(); + } else { + dummy(); + p[0] = p2; + dummy(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test2_0_0(int y) { + Point p = new Point(); + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + p = new Point(); + } + int x = 3; + p.x = x; + p.y = 3 * x + y; + dummy(); + return p.x * p.y; + } + + int test2_0_1(int y) { + Point p = null; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + p = new Point(); + } + int x = 3; + if ( p == null ) + return (3 * x + y) * x; + p.x = x; + p.y = 3 * x + y; + dummy(); + return p.x * p.y; + } + + int test2_0_2(int y) { + Point p[] = new Point[3]; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + p[i] = new Point(); + } + int x = 3; + int j = (y & 1); + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_0_3(int y) { + Point p[] = new Point[3]; + int j = (y & 1); + p[j] = null; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + p[i] = new Point(); + } + int x = 3; + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_0_4(int y) { + Point p[] = new Point[3]; + int j = (y & 1); + p[j] = new Point(); + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + p[i] = new Point(); + } + int x = 3; + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_0_5(int y) { + Point p[] = new Point[3]; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + p[i] = new Point(); + } + for (int i = 0; i < lim; i++) { + p[i] = null; + } + int x = 3; + int j = (y & 1); + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_0_6(int y) { + Point p[] = new Point[3]; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + p[i] = new Point(); + } + for (int i = 0; i < lim; i++) { + p[i] = new Point(); + } + int x = 3; + int j = (y & 1); + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_1_0(int y) { + Point p = new Point(); + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p = new Point(); + dummy(); + } + int x = 3; + p.x = x; + p.y = 3 * x + y; + dummy(); + return p.x * p.y; + } + + int test2_1_1(int y) { + Point p = null; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p = new Point(); + dummy(); + } + int x = 3; + if ( p == null ) + return (3 * x + y) * x; + p.x = x; + p.y = 3 * x + y; + dummy(); + return p.x * p.y; + } + + int test2_1_2(int y) { + Point p[] = new Point[3]; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = new Point(); + dummy(); + } + int x = 3; + int j = (y & 1); + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_1_3(int y) { + Point p[] = new Point[3]; + dummy(); + int j = (y & 1); + p[j] = null; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = new Point(); + dummy(); + } + int x = 3; + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_1_4(int y) { + Point p[] = new Point[3]; + dummy(); + int j = (y & 1); + p[j] = new Point(); + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = new Point(); + dummy(); + } + int x = 3; + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_1_5(int y) { + Point p[] = new Point[3]; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = new Point(); + dummy(); + } + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = null; + dummy(); + } + int x = 3; + int j = (y & 1); + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_1_6(int y) { + Point p[] = new Point[3]; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = new Point(); + dummy(); + } + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = new Point(); + dummy(); + } + int x = 3; + int j = (y & 1); + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_2_0(int y) { + Point p1 = new Point(); + dummy(); + Point p = new Point(); + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p = p1; + dummy(); + } + int x = 3; + p.x = x; + p.y = 3 * x + y; + dummy(); + return p.x * p.y; + } + + int test2_2_1(int y) { + Point p1 = new Point(); + dummy(); + Point p = null; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p = p1; + dummy(); + } + int x = 3; + if ( p == null ) + return (3 * x + y) * x; + p.x = x; + p.y = 3 * x + y; + dummy(); + return p.x * p.y; + } + + int test2_2_2(int y) { + Point p1 = new Point(); + dummy(); + Point p[] = new Point[3]; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = p1; + dummy(); + } + int x = 3; + int j = (y & 1); + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_2_3(int y) { + Point p1 = new Point(); + dummy(); + Point p[] = new Point[3]; + dummy(); + int j = (y & 1); + p[j] = null; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = p1; + dummy(); + } + int x = 3; + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_2_4(int y) { + Point p1 = new Point(); + dummy(); + Point p2 = new Point(); + dummy(); + Point p[] = new Point[3]; + dummy(); + int j = (y & 1); + p[j] = p1; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = p2; + dummy(); + } + int x = 3; + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_2_5(int y) { + Point p1 = new Point(); + dummy(); + Point p[] = new Point[3]; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = p1; + dummy(); + } + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = null; + dummy(); + } + int x = 3; + int j = (y & 1); + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_2_6(int y) { + Point p1 = new Point(); + dummy(); + Point p2 = new Point(); + dummy(); + Point p[] = new Point[3]; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = p1; + dummy(); + } + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = p2; + dummy(); + } + int x = 3; + int j = (y & 1); + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + public static void main(String args[]) { + Test tsr = new Test(); + Point p = new Point(); + Point ptmp = p; + Class cls = Point.class; + int y = 0; + for (int i=0; i<10000; i++) { + y = tsr.test0_0_0(y); + y = tsr.test0_0_0(y); + y = tsr.test0_0_1(y); + y = tsr.test0_0_1(y); + y = tsr.test0_0_2(y); + y = tsr.test0_0_2(y); + y = tsr.test0_0_3(y); + y = tsr.test0_0_3(y); + y = tsr.test0_0_4(y); + y = tsr.test0_0_4(y); + y = tsr.test0_0_5(y); + y = tsr.test0_0_5(y); + y = tsr.test0_0_6(y); + y = tsr.test0_0_6(y); + + y = tsr.test0_1_3(y); + y = tsr.test0_1_3(y); + y = tsr.test0_1_4(y); + y = tsr.test0_1_4(y); + y = tsr.test0_1_5(y); + y = tsr.test0_1_5(y); + y = tsr.test0_1_6(y); + y = tsr.test0_1_6(y); + + y = tsr.test1_0_0(y&~1); + y = tsr.test1_0_1(y&~1); + y = tsr.test1_0_2(y&~1); + y = tsr.test1_0_3(y&~1); + y = tsr.test1_0_4(y&~1); + y = tsr.test1_0_5(y&~1); + y = tsr.test1_0_6(y&~1); + y = tsr.test1_0_0((y&~1)+1); + y = tsr.test1_0_1((y&~1)+1); + y = tsr.test1_0_2((y&~1)+1); + y = tsr.test1_0_3((y&~1)+1); + y = tsr.test1_0_4((y&~1)+1); + y = tsr.test1_0_5((y&~1)+1); + y = tsr.test1_0_6((y&~1)+1); + + y = tsr.test1_1_0(y&~1); + y = tsr.test1_1_1(y&~1); + y = tsr.test1_1_2(y&~1); + y = tsr.test1_1_3(y&~1); + y = tsr.test1_1_4(y&~1); + y = tsr.test1_1_5(y&~1); + y = tsr.test1_1_6(y&~1); + y = tsr.test1_1_0((y&~1)+1); + y = tsr.test1_1_1((y&~1)+1); + y = tsr.test1_1_2((y&~1)+1); + y = tsr.test1_1_3((y&~1)+1); + y = tsr.test1_1_4((y&~1)+1); + y = tsr.test1_1_5((y&~1)+1); + y = tsr.test1_1_6((y&~1)+1); + + y = tsr.test1_2_0(y&~1); + y = tsr.test1_2_1(y&~1); + y = tsr.test1_2_2(y&~1); + y = tsr.test1_2_3(y&~1); + y = tsr.test1_2_4(y&~1); + y = tsr.test1_2_5(y&~1); + y = tsr.test1_2_6(y&~1); + y = tsr.test1_2_0((y&~1)+1); + y = tsr.test1_2_1((y&~1)+1); + y = tsr.test1_2_2((y&~1)+1); + y = tsr.test1_2_3((y&~1)+1); + y = tsr.test1_2_4((y&~1)+1); + y = tsr.test1_2_5((y&~1)+1); + y = tsr.test1_2_6((y&~1)+1); + + y = tsr.test2_0_0(y&~3); + y = tsr.test2_0_1(y&~3); + y = tsr.test2_0_2(y&~3); + y = tsr.test2_0_3(y&~3); + y = tsr.test2_0_4(y&~3); + y = tsr.test2_0_5(y&~3); + y = tsr.test2_0_6(y&~3); + y = tsr.test2_0_0((y&~3)+3); + y = tsr.test2_0_1((y&~3)+3); + y = tsr.test2_0_2((y&~3)+3); + y = tsr.test2_0_3((y&~3)+3); + y = tsr.test2_0_4((y&~3)+3); + y = tsr.test2_0_5((y&~3)+3); + y = tsr.test2_0_6((y&~3)+3); + + y = tsr.test2_1_0(y&~3); + y = tsr.test2_1_1(y&~3); + y = tsr.test2_1_2(y&~3); + y = tsr.test2_1_3(y&~3); + y = tsr.test2_1_4(y&~3); + y = tsr.test2_1_5(y&~3); + y = tsr.test2_1_6(y&~3); + y = tsr.test2_1_0((y&~3)+3); + y = tsr.test2_1_1((y&~3)+3); + y = tsr.test2_1_2((y&~3)+3); + y = tsr.test2_1_3((y&~3)+3); + y = tsr.test2_1_4((y&~3)+3); + y = tsr.test2_1_5((y&~3)+3); + y = tsr.test2_1_6((y&~3)+3); + + y = tsr.test2_2_0(y&~3); + y = tsr.test2_2_1(y&~3); + y = tsr.test2_2_2(y&~3); + y = tsr.test2_2_3(y&~3); + y = tsr.test2_2_4(y&~3); + y = tsr.test2_2_5(y&~3); + y = tsr.test2_2_6(y&~3); + y = tsr.test2_2_0((y&~3)+3); + y = tsr.test2_2_1((y&~3)+3); + y = tsr.test2_2_2((y&~3)+3); + y = tsr.test2_2_3((y&~3)+3); + y = tsr.test2_2_4((y&~3)+3); + y = tsr.test2_2_5((y&~3)+3); + y = tsr.test2_2_6((y&~3)+3); + + } + for (int i=0; i<10000; i++) { + y = tsr.test0_0_0(y); + y = tsr.test0_0_0(y); + y = tsr.test0_0_1(y); + y = tsr.test0_0_1(y); + y = tsr.test0_0_2(y); + y = tsr.test0_0_2(y); + y = tsr.test0_0_3(y); + y = tsr.test0_0_3(y); + y = tsr.test0_0_4(y); + y = tsr.test0_0_4(y); + y = tsr.test0_0_5(y); + y = tsr.test0_0_5(y); + y = tsr.test0_0_6(y); + y = tsr.test0_0_6(y); + + y = tsr.test0_1_3(y); + y = tsr.test0_1_3(y); + y = tsr.test0_1_4(y); + y = tsr.test0_1_4(y); + y = tsr.test0_1_5(y); + y = tsr.test0_1_5(y); + y = tsr.test0_1_6(y); + y = tsr.test0_1_6(y); + + y = tsr.test1_0_0(y&~1); + y = tsr.test1_0_1(y&~1); + y = tsr.test1_0_2(y&~1); + y = tsr.test1_0_3(y&~1); + y = tsr.test1_0_4(y&~1); + y = tsr.test1_0_5(y&~1); + y = tsr.test1_0_6(y&~1); + y = tsr.test1_0_0((y&~1)+1); + y = tsr.test1_0_1((y&~1)+1); + y = tsr.test1_0_2((y&~1)+1); + y = tsr.test1_0_3((y&~1)+1); + y = tsr.test1_0_4((y&~1)+1); + y = tsr.test1_0_5((y&~1)+1); + y = tsr.test1_0_6((y&~1)+1); + + y = tsr.test1_1_0(y&~1); + y = tsr.test1_1_1(y&~1); + y = tsr.test1_1_2(y&~1); + y = tsr.test1_1_3(y&~1); + y = tsr.test1_1_4(y&~1); + y = tsr.test1_1_5(y&~1); + y = tsr.test1_1_6(y&~1); + y = tsr.test1_1_0((y&~1)+1); + y = tsr.test1_1_1((y&~1)+1); + y = tsr.test1_1_2((y&~1)+1); + y = tsr.test1_1_3((y&~1)+1); + y = tsr.test1_1_4((y&~1)+1); + y = tsr.test1_1_5((y&~1)+1); + y = tsr.test1_1_6((y&~1)+1); + + y = tsr.test1_2_0(y&~1); + y = tsr.test1_2_1(y&~1); + y = tsr.test1_2_2(y&~1); + y = tsr.test1_2_3(y&~1); + y = tsr.test1_2_4(y&~1); + y = tsr.test1_2_5(y&~1); + y = tsr.test1_2_6(y&~1); + y = tsr.test1_2_0((y&~1)+1); + y = tsr.test1_2_1((y&~1)+1); + y = tsr.test1_2_2((y&~1)+1); + y = tsr.test1_2_3((y&~1)+1); + y = tsr.test1_2_4((y&~1)+1); + y = tsr.test1_2_5((y&~1)+1); + y = tsr.test1_2_6((y&~1)+1); + + y = tsr.test2_0_0(y&~3); + y = tsr.test2_0_1(y&~3); + y = tsr.test2_0_2(y&~3); + y = tsr.test2_0_3(y&~3); + y = tsr.test2_0_4(y&~3); + y = tsr.test2_0_5(y&~3); + y = tsr.test2_0_6(y&~3); + y = tsr.test2_0_0((y&~3)+3); + y = tsr.test2_0_1((y&~3)+3); + y = tsr.test2_0_2((y&~3)+3); + y = tsr.test2_0_3((y&~3)+3); + y = tsr.test2_0_4((y&~3)+3); + y = tsr.test2_0_5((y&~3)+3); + y = tsr.test2_0_6((y&~3)+3); + + y = tsr.test2_1_0(y&~3); + y = tsr.test2_1_1(y&~3); + y = tsr.test2_1_2(y&~3); + y = tsr.test2_1_3(y&~3); + y = tsr.test2_1_4(y&~3); + y = tsr.test2_1_5(y&~3); + y = tsr.test2_1_6(y&~3); + y = tsr.test2_1_0((y&~3)+3); + y = tsr.test2_1_1((y&~3)+3); + y = tsr.test2_1_2((y&~3)+3); + y = tsr.test2_1_3((y&~3)+3); + y = tsr.test2_1_4((y&~3)+3); + y = tsr.test2_1_5((y&~3)+3); + y = tsr.test2_1_6((y&~3)+3); + + y = tsr.test2_2_0(y&~3); + y = tsr.test2_2_1(y&~3); + y = tsr.test2_2_2(y&~3); + y = tsr.test2_2_3(y&~3); + y = tsr.test2_2_4(y&~3); + y = tsr.test2_2_5(y&~3); + y = tsr.test2_2_6(y&~3); + y = tsr.test2_2_0((y&~3)+3); + y = tsr.test2_2_1((y&~3)+3); + y = tsr.test2_2_2((y&~3)+3); + y = tsr.test2_2_3((y&~3)+3); + y = tsr.test2_2_4((y&~3)+3); + y = tsr.test2_2_5((y&~3)+3); + y = tsr.test2_2_6((y&~3)+3); + + } + for (int i=0; i<10000; i++) { + y = tsr.test0_0_0(y); + y = tsr.test0_0_0(y); + y = tsr.test0_0_1(y); + y = tsr.test0_0_1(y); + y = tsr.test0_0_2(y); + y = tsr.test0_0_2(y); + y = tsr.test0_0_3(y); + y = tsr.test0_0_3(y); + y = tsr.test0_0_4(y); + y = tsr.test0_0_4(y); + y = tsr.test0_0_5(y); + y = tsr.test0_0_5(y); + y = tsr.test0_0_6(y); + y = tsr.test0_0_6(y); + + y = tsr.test0_1_3(y); + y = tsr.test0_1_3(y); + y = tsr.test0_1_4(y); + y = tsr.test0_1_4(y); + y = tsr.test0_1_5(y); + y = tsr.test0_1_5(y); + y = tsr.test0_1_6(y); + y = tsr.test0_1_6(y); + + y = tsr.test1_0_0(y&~1); + y = tsr.test1_0_1(y&~1); + y = tsr.test1_0_2(y&~1); + y = tsr.test1_0_3(y&~1); + y = tsr.test1_0_4(y&~1); + y = tsr.test1_0_5(y&~1); + y = tsr.test1_0_6(y&~1); + y = tsr.test1_0_0((y&~1)+1); + y = tsr.test1_0_1((y&~1)+1); + y = tsr.test1_0_2((y&~1)+1); + y = tsr.test1_0_3((y&~1)+1); + y = tsr.test1_0_4((y&~1)+1); + y = tsr.test1_0_5((y&~1)+1); + y = tsr.test1_0_6((y&~1)+1); + + y = tsr.test1_1_0(y&~1); + y = tsr.test1_1_1(y&~1); + y = tsr.test1_1_2(y&~1); + y = tsr.test1_1_3(y&~1); + y = tsr.test1_1_4(y&~1); + y = tsr.test1_1_5(y&~1); + y = tsr.test1_1_6(y&~1); + y = tsr.test1_1_0((y&~1)+1); + y = tsr.test1_1_1((y&~1)+1); + y = tsr.test1_1_2((y&~1)+1); + y = tsr.test1_1_3((y&~1)+1); + y = tsr.test1_1_4((y&~1)+1); + y = tsr.test1_1_5((y&~1)+1); + y = tsr.test1_1_6((y&~1)+1); + + y = tsr.test1_2_0(y&~1); + y = tsr.test1_2_1(y&~1); + y = tsr.test1_2_2(y&~1); + y = tsr.test1_2_3(y&~1); + y = tsr.test1_2_4(y&~1); + y = tsr.test1_2_5(y&~1); + y = tsr.test1_2_6(y&~1); + y = tsr.test1_2_0((y&~1)+1); + y = tsr.test1_2_1((y&~1)+1); + y = tsr.test1_2_2((y&~1)+1); + y = tsr.test1_2_3((y&~1)+1); + y = tsr.test1_2_4((y&~1)+1); + y = tsr.test1_2_5((y&~1)+1); + y = tsr.test1_2_6((y&~1)+1); + + y = tsr.test2_0_0(y&~3); + y = tsr.test2_0_1(y&~3); + y = tsr.test2_0_2(y&~3); + y = tsr.test2_0_3(y&~3); + y = tsr.test2_0_4(y&~3); + y = tsr.test2_0_5(y&~3); + y = tsr.test2_0_6(y&~3); + y = tsr.test2_0_0((y&~3)+3); + y = tsr.test2_0_1((y&~3)+3); + y = tsr.test2_0_2((y&~3)+3); + y = tsr.test2_0_3((y&~3)+3); + y = tsr.test2_0_4((y&~3)+3); + y = tsr.test2_0_5((y&~3)+3); + y = tsr.test2_0_6((y&~3)+3); + + y = tsr.test2_1_0(y&~3); + y = tsr.test2_1_1(y&~3); + y = tsr.test2_1_2(y&~3); + y = tsr.test2_1_3(y&~3); + y = tsr.test2_1_4(y&~3); + y = tsr.test2_1_5(y&~3); + y = tsr.test2_1_6(y&~3); + y = tsr.test2_1_0((y&~3)+3); + y = tsr.test2_1_1((y&~3)+3); + y = tsr.test2_1_2((y&~3)+3); + y = tsr.test2_1_3((y&~3)+3); + y = tsr.test2_1_4((y&~3)+3); + y = tsr.test2_1_5((y&~3)+3); + y = tsr.test2_1_6((y&~3)+3); + + y = tsr.test2_2_0(y&~3); + y = tsr.test2_2_1(y&~3); + y = tsr.test2_2_2(y&~3); + y = tsr.test2_2_3(y&~3); + y = tsr.test2_2_4(y&~3); + y = tsr.test2_2_5(y&~3); + y = tsr.test2_2_6(y&~3); + y = tsr.test2_2_0((y&~3)+3); + y = tsr.test2_2_1((y&~3)+3); + y = tsr.test2_2_2((y&~3)+3); + y = tsr.test2_2_3((y&~3)+3); + y = tsr.test2_2_4((y&~3)+3); + y = tsr.test2_2_5((y&~3)+3); + y = tsr.test2_2_6((y&~3)+3); + + } + + int z = 0; + y = tsr.test0_0_0(0); + System.out.println("After 'test0_0_0' y=" + y); + y = tsr.test0_0_1(0); + System.out.println("After 'test0_0_1' y=" + y); + y = tsr.test0_0_2(0); + System.out.println("After 'test0_0_2' y=" + y); + y = tsr.test0_0_3(0); + System.out.println("After 'test0_0_3' y=" + y); + y = tsr.test0_0_4(0); + System.out.println("After 'test0_0_4' y=" + y); + y = tsr.test0_0_5(0); + System.out.println("After 'test0_0_5' y=" + y); + y = tsr.test0_0_6(0); + System.out.println("After 'test0_0_6' y=" + y); + y = tsr.test0_1_3(0); + System.out.println("After 'test0_1_3' y=" + y); + y = tsr.test0_1_4(0); + System.out.println("After 'test0_1_4' y=" + y); + y = tsr.test0_1_5(0); + System.out.println("After 'test0_1_5' y=" + y); + y = tsr.test0_1_6(0); + System.out.println("After 'test0_1_6' y=" + y); + + y = tsr.test1_0_0(0); + System.out.println("After 'test1_0_0' y=" + y); + y = tsr.test1_0_1(0); + System.out.println("After 'test1_0_1' y=" + y); + y = tsr.test1_0_2(0); + System.out.println("After 'test1_0_2' y=" + y); + y = tsr.test1_0_3(0); + System.out.println("After 'test1_0_3' y=" + y); + y = tsr.test1_0_4(0); + System.out.println("After 'test1_0_4' y=" + y); + y = tsr.test1_0_5(0); + System.out.println("After 'test1_0_5' y=" + y); + y = tsr.test1_0_6(0); + System.out.println("After 'test1_0_6' y=" + y); + + y = tsr.test1_1_0(0); + System.out.println("After 'test1_1_0' y=" + y); + y = tsr.test1_1_1(0); + System.out.println("After 'test1_1_1' y=" + y); + y = tsr.test1_1_2(0); + System.out.println("After 'test1_1_2' y=" + y); + y = tsr.test1_1_3(0); + System.out.println("After 'test1_1_3' y=" + y); + y = tsr.test1_1_4(0); + System.out.println("After 'test1_1_4' y=" + y); + y = tsr.test1_1_5(0); + System.out.println("After 'test1_1_5' y=" + y); + y = tsr.test1_1_6(0); + System.out.println("After 'test1_1_6' y=" + y); + + y = tsr.test1_2_0(0); + System.out.println("After 'test1_2_0' y=" + y); + y = tsr.test1_2_1(0); + System.out.println("After 'test1_2_1' y=" + y); + y = tsr.test1_2_2(0); + System.out.println("After 'test1_2_2' y=" + y); + y = tsr.test1_2_3(0); + System.out.println("After 'test1_2_3' y=" + y); + y = tsr.test1_2_4(0); + System.out.println("After 'test1_2_4' y=" + y); + y = tsr.test1_2_5(0); + System.out.println("After 'test1_2_5' y=" + y); + y = tsr.test1_2_6(0); + System.out.println("After 'test1_2_6' y=" + y); + + y = tsr.test2_0_0(0); + System.out.println("After 'test2_0_0' y=" + y); + y = tsr.test2_0_1(0); + System.out.println("After 'test2_0_1' y=" + y); + y = tsr.test2_0_2(0); + System.out.println("After 'test2_0_2' y=" + y); + y = tsr.test2_0_3(0); + System.out.println("After 'test2_0_3' y=" + y); + y = tsr.test2_0_4(0); + System.out.println("After 'test2_0_4' y=" + y); + y = tsr.test2_0_5(0); + System.out.println("After 'test2_0_5' y=" + y); + y = tsr.test2_0_6(0); + System.out.println("After 'test2_0_6' y=" + y); + + y = tsr.test2_1_0(0); + System.out.println("After 'test2_1_0' y=" + y); + y = tsr.test2_1_1(0); + System.out.println("After 'test2_1_1' y=" + y); + y = tsr.test2_1_2(0); + System.out.println("After 'test2_1_2' y=" + y); + y = tsr.test2_1_3(0); + System.out.println("After 'test2_1_3' y=" + y); + y = tsr.test2_1_4(0); + System.out.println("After 'test2_1_4' y=" + y); + y = tsr.test2_1_5(0); + System.out.println("After 'test2_1_5' y=" + y); + y = tsr.test2_1_6(0); + System.out.println("After 'test2_1_6' y=" + y); + + y = tsr.test2_2_0(0); + System.out.println("After 'test2_2_0' y=" + y); + y = tsr.test2_2_1(0); + System.out.println("After 'test2_2_1' y=" + y); + y = tsr.test2_2_2(0); + System.out.println("After 'test2_2_2' y=" + y); + y = tsr.test2_2_3(0); + System.out.println("After 'test2_2_3' y=" + y); + y = tsr.test2_2_4(0); + System.out.println("After 'test2_2_4' y=" + y); + y = tsr.test2_2_5(0); + System.out.println("After 'test2_2_5' y=" + y); + y = tsr.test2_2_6(0); + System.out.println("After 'test2_2_6' y=" + y); + + } +} From 91e177bfd9df715754a6682eaa49d8484f33b1cd Mon Sep 17 00:00:00 2001 From: Swamy Venkataramanappa Date: Tue, 29 Jul 2008 13:54:27 -0700 Subject: [PATCH 17/52] 6710791: Remove files or build from source:maf-1_0.jar, jlfg-1_0.jar Removed maf-1_0.jar and jlfg-1_0.jar files. Reviewed-by: poonam, jjh --- hotspot/agent/make/Makefile | 61 +-- hotspot/agent/make/bugspot.bat | 2 +- hotspot/agent/make/build.xml | 18 +- hotspot/agent/make/hsdb.bat | 2 +- hotspot/agent/make/hsdb.sh | 2 +- hotspot/agent/make/saenv.bat | 2 +- hotspot/agent/make/saenv.sh | 2 +- hotspot/agent/make/saenv64.bat | 2 +- hotspot/agent/make/saenv64.sh | 2 +- .../sun/java/swing/action/AboutAction.java | 57 +++ .../sun/java/swing/action/ActionManager.java | 95 +++++ .../java/swing/action/ActionUtilities.java | 49 +++ .../java/swing/action/AlignCenterAction.java | 60 +++ .../java/swing/action/AlignLeftAction.java | 60 +++ .../java/swing/action/AlignRightAction.java | 60 +++ .../sun/java/swing/action/ApplyAction.java | 60 +++ .../com/sun/java/swing/action/BackAction.java | 60 +++ .../sun/java/swing/action/CancelAction.java | 60 +++ .../sun/java/swing/action/DelegateAction.java | 65 +++ .../com/sun/java/swing/action/ExitAction.java | 55 +++ .../com/sun/java/swing/action/FileMenu.java | 53 +++ .../sun/java/swing/action/FinishAction.java | 60 +++ .../com/sun/java/swing/action/HelpAction.java | 60 +++ .../com/sun/java/swing/action/HelpMenu.java | 53 +++ .../com/sun/java/swing/action/NewAction.java | 60 +++ .../com/sun/java/swing/action/NextAction.java | 60 +++ .../com/sun/java/swing/action/OkAction.java | 60 +++ .../com/sun/java/swing/action/OpenAction.java | 60 +++ .../com/sun/java/swing/action/SaveAction.java | 60 +++ .../sun/java/swing/action/SaveAsAction.java | 57 +++ .../java/swing/action/StateChangeAction.java | 88 ++++ .../com/sun/java/swing/action/ViewMenu.java | 53 +++ .../com/sun/java/swing/ui/CommonMenuBar.java | 108 +++++ .../com/sun/java/swing/ui/CommonToolBar.java | 95 +++++ .../com/sun/java/swing/ui/CommonUI.java | 392 ++++++++++++++++++ .../java/swing/ui/OkCancelButtonPanel.java | 51 +++ .../com/sun/java/swing/ui/OkCancelDialog.java | 82 ++++ .../com/sun/java/swing/ui/SplashScreen.java | 85 ++++ .../com/sun/java/swing/ui/StatusBar.java | 178 ++++++++ .../com/sun/java/swing/ui/TabsDlg.java | 221 ++++++++++ .../ToggleActionPropertyChangeListener.java | 52 +++ .../com/sun/java/swing/ui/WizardDlg.java | 336 +++++++++++++++ .../development/Server16.gif | Bin 0 -> 636 bytes .../development/Server24.gif | Bin 0 -> 775 bytes .../toolbarButtonGraphics/general/About16.gif | Bin 0 -> 644 bytes .../toolbarButtonGraphics/general/About24.gif | Bin 0 -> 797 bytes .../general/Delete16.gif | Bin 0 -> 208 bytes .../general/Delete24.gif | Bin 0 -> 249 bytes .../toolbarButtonGraphics/general/Find16.gif | Bin 0 -> 434 bytes .../toolbarButtonGraphics/general/Help16.gif | Bin 0 -> 661 bytes .../toolbarButtonGraphics/general/Help24.gif | Bin 0 -> 1328 bytes .../general/History16.gif | Bin 0 -> 677 bytes .../general/History24.gif | Bin 0 -> 1304 bytes .../general/Information16.gif | Bin 0 -> 661 bytes .../general/Information24.gif | Bin 0 -> 1328 bytes .../toolbarButtonGraphics/general/New16.gif | Bin 0 -> 426 bytes .../toolbarButtonGraphics/general/New24.gif | Bin 0 -> 778 bytes .../toolbarButtonGraphics/general/Open16.gif | Bin 0 -> 228 bytes .../toolbarButtonGraphics/general/Open24.gif | Bin 0 -> 462 bytes .../toolbarButtonGraphics/general/Save16.gif | Bin 0 -> 206 bytes .../toolbarButtonGraphics/general/Save24.gif | Bin 0 -> 266 bytes .../general/SaveAs16.gif | Bin 0 -> 255 bytes .../general/SaveAs24.gif | Bin 0 -> 348 bytes .../toolbarButtonGraphics/general/Zoom16.gif | Bin 0 -> 303 bytes .../general/ZoomIn16.gif | Bin 0 -> 304 bytes .../general/ZoomIn24.gif | Bin 0 -> 484 bytes .../navigation/Down16.gif | Bin 0 -> 185 bytes .../toolbarButtonGraphics/navigation/Up16.gif | Bin 0 -> 184 bytes .../text/AlignCenter16.gif | Bin 0 -> 163 bytes .../text/AlignCenter24.gif | Bin 0 -> 179 bytes .../text/AlignLeft16.gif | Bin 0 -> 165 bytes .../text/AlignLeft24.gif | Bin 0 -> 178 bytes .../text/AlignRight16.gif | Bin 0 -> 165 bytes .../text/AlignRight24.gif | Bin 0 -> 178 bytes hotspot/agent/src/share/lib/jlfgr-1_0.jar | Bin 126642 -> 0 bytes hotspot/agent/src/share/lib/maf-1_0.jar | Bin 59918 -> 0 bytes 76 files changed, 3058 insertions(+), 40 deletions(-) create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/action/AboutAction.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/action/ActionManager.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/action/ActionUtilities.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/action/AlignCenterAction.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/action/AlignLeftAction.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/action/AlignRightAction.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/action/ApplyAction.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/action/BackAction.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/action/CancelAction.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/action/DelegateAction.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/action/ExitAction.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/action/FileMenu.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/action/FinishAction.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/action/HelpAction.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/action/HelpMenu.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/action/NewAction.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/action/NextAction.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/action/OkAction.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/action/OpenAction.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/action/SaveAction.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/action/SaveAsAction.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/action/StateChangeAction.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/action/ViewMenu.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/ui/CommonMenuBar.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/ui/CommonToolBar.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/ui/CommonUI.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/ui/OkCancelButtonPanel.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/ui/OkCancelDialog.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/ui/SplashScreen.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/ui/StatusBar.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/ui/TabsDlg.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/ui/ToggleActionPropertyChangeListener.java create mode 100644 hotspot/agent/src/share/classes/com/sun/java/swing/ui/WizardDlg.java create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/development/Server16.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/development/Server24.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/About16.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/About24.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Delete16.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Delete24.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Find16.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Help16.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Help24.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/History16.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/History24.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Information16.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Information24.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/New16.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/New24.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Open16.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Open24.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Save16.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Save24.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/SaveAs16.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/SaveAs24.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Zoom16.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/ZoomIn16.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/ZoomIn24.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/navigation/Down16.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/navigation/Up16.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignCenter16.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignCenter24.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignLeft16.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignLeft24.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignRight16.gif create mode 100644 hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignRight24.gif delete mode 100644 hotspot/agent/src/share/lib/jlfgr-1_0.jar delete mode 100644 hotspot/agent/src/share/lib/maf-1_0.jar diff --git a/hotspot/agent/make/Makefile b/hotspot/agent/make/Makefile index ae10cb3cb97..bdde49eec1a 100644 --- a/hotspot/agent/make/Makefile +++ b/hotspot/agent/make/Makefile @@ -32,6 +32,12 @@ else include $(GAMMADIR)/make/defs.make endif +ifeq "x$(HOTSPOT_BUILD_VERSION)" "x" +SA_BUILD_VERSION=$(HOTSPOT_RELEASE_VERSION) +else +SA_BUILD_VERSION=$(HOTSPOT_RELEASE_VERSION)-$(HOTSPOT_BUILD_VERSION) +endif + PKGLIST = \ sun.jvm.hotspot \ sun.jvm.hotspot.asm \ @@ -117,7 +123,9 @@ sun.jvm.hotspot.ui.tree \ sun.jvm.hotspot.ui.treetable \ sun.jvm.hotspot.utilities \ sun.jvm.hotspot.utilities.memo \ -sun.jvm.hotspot.utilities.soql +sun.jvm.hotspot.utilities.soql \ +com.sun.java.swing.action \ +com.sun.java.swing.ui #END PKGLIST # Generated using the build-filelist script @@ -198,7 +206,9 @@ sun/jvm/hotspot/ui/tree/*.java \ sun/jvm/hotspot/ui/treetable/*.java \ sun/jvm/hotspot/utilities/*.java \ sun/jvm/hotspot/utilities/memo/*.java \ -sun/jvm/hotspot/utilities/soql/*.java +sun/jvm/hotspot/utilities/soql/*.java \ +com/sun/java/swing/action/*.java \ +com/sun/java/swing/ui/*.java #END FILELIST ifneq "x$(ALT_BOOTDIR)" "x" @@ -220,8 +230,6 @@ else endif SRC_DIR = ../src/share/classes -LIB_DIR = ../src/share/lib -CLOSED_LIB_DIR = ../closed/src/share/lib BUILD_DIR = ../build OUTPUT_DIR = $(BUILD_DIR)/classes DOC_DIR = $(BUILD_DIR)/doc @@ -231,9 +239,9 @@ DOC_DIR = $(BUILD_DIR)/doc ALLFILES := $(patsubst %,$(SRC_DIR)/%,$(FILELIST)) ALLFILES := $(shell /bin/ls $(ALLFILES)) +# tools.jar is used by the sa-jdi binding +CLASSPATH = $(JDK_HOME)/lib/tools.jar -# tools.jar is needed by the JDI - SA binding -CLASSPATH = $(LIB_DIR)/maf-1_0.jar$(CPS)$(JDK_HOME)/lib/tools.jar CLASSPATH := $(subst \,/,$(CLASSPATH)) # FIXME: autogenerate call to rmic @@ -241,24 +249,36 @@ CLASSPATH := $(subst \,/,$(CLASSPATH)) SA_BUILD_VERSION_PROP = "sun.jvm.hotspot.runtime.VM.saBuildVersion=$(SA_BUILD_VERSION)" SA_PROPERTIES = $(OUTPUT_DIR)/sa.properties +JAVAC = $(JDK_HOME)/bin/javac +JAVADOC = $(JDK_HOME)/bin/javadoc +RMIC = $(JDK_HOME)/bin/rmic # Tagging it on because there's no reason not to run it all: filelist @mkdir -p $(OUTPUT_DIR) @echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES) - @${JDK_HOME}/bin/javac -source 1.4 -classpath $(CLASSPATH) -deprecation -sourcepath $(SRC_DIR) -g -d $(OUTPUT_DIR) @filelist - @${JDK_HOME}/bin/rmic -classpath $(OUTPUT_DIR) -d $(OUTPUT_DIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer + $(JAVAC) -source 1.4 -classpath $(CLASSPATH) -deprecation -sourcepath $(SRC_DIR) -g -d $(OUTPUT_DIR) @filelist + $(RMIC) -classpath $(OUTPUT_DIR) -d $(OUTPUT_DIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer rm -f $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql/sa.js cp $(SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql + mkdir -p $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources + rm -f $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources/* + cp $(SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources/ + cp -r $(SRC_DIR)/images/* $(OUTPUT_DIR)/ allprof: filelist @mkdir -p $(OUTPUT_DIR) @echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES) - @${JDK_HOME}/bin/javac -source 1.4 -J-Xprof -classpath $(CLASSPATH) -deprecation -sourcepath $(SRC_DIR) -g -d $(OUTPUT_DIR) @filelist - @${JDK_HOME}/bin/rmic -classpath $(OUTPUT_DIR) -d $(OUTPUT_DIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer + $(JAVAC) -source 1.4 -J-Xprof -classpath $(CLASSPATH) -deprecation -sourcepath $(SRC_DIR) -g -d $(OUTPUT_DIR) @filelist + $(RMIC) -classpath $(OUTPUT_DIR) -d $(OUTPUT_DIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer rm -f $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql/sa.js cp $(SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql + mkdir -p $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources + rm -f $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources/* + cp $(SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources/ + cp -r $(SRC_DIR)/images/* $(OUTPUT_DIR)/ +.PHONY: filelist filelist: $(ALLFILES) @if [ ! -f $(JDK_HOME)/lib/tools.jar ] ; then \ echo "Missing $(JDK_HOME)/lib/tools.jar file. Use 1.6.0 or later version jdk to build SA."; \ @@ -274,36 +294,23 @@ natives: .PHONY: sa-jdi.jar sa-jdi.jar: - if [ ! -f $(JDK_HOME)/lib/tools.jar ] ; then \ - echo "Missing $(JDK_HOME)/lib/tools.jar file. Use 1.6.0 or later version jdk to build SA.";\ - exit 1; \ - fi - rm -f $(BUILD_DIR)/sa-jdi.jar - rm -f $(OUTPUT_DIR)/jdi_class_files - javac -source 1.4 ClosureFinder.java -d $(OUTPUT_DIR) - cd $(OUTPUT_DIR) ; find sun/jvm/hotspot/jdi -name "*.class" > jdi_class_files - cd $(OUTPUT_DIR) ; jar cvf ../sa-jdi.jar `java ClosureFinder jdi_class_files .` - cd $(BUILD_DIR) ; jar uvf sa-jdi.jar -C $(SRC_DIR) META-INF/services/com.sun.jdi.connect.Connector - cd $(BUILD_DIR) ; jar uvf sa-jdi.jar -C $(OUTPUT_DIR) sa.properties - rm -f $(OUTPUT_DIR)/ClosureFinder.class - rm -f $(OUTPUT_DIR)/jdi_class_files + echo "sa-jdi.jar is built by a hotspot build." docs: - @javadoc -private -classpath $(CLASSPATH) -sourcepath $(SRC_DIR) -d $(DOC_DIR) $(PKGLIST) + @$(JAVADOC) -private -classpath $(CLASSPATH) -sourcepath $(SRC_DIR) -d $(DOC_DIR) $(PKGLIST) sizes: $(ALLFILES) wc -l $(ALLFILES) cscope: $(ALLFILES) + rm -f java.files echo $(ALLFILES) > java.files cscope -b -i java.files -f java.out + rm -f java.files .PHONY: sa.jar sa.jar: rm -f $(BUILD_DIR)/sa.jar - mkdir -p $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources - rm -f $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources/* - cp $(SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources/ cd $(OUTPUT_DIR) ; jar cvf ../sa.jar * clean:: diff --git a/hotspot/agent/make/bugspot.bat b/hotspot/agent/make/bugspot.bat index da0880c4da8..c3330f05bb4 100644 --- a/hotspot/agent/make/bugspot.bat +++ b/hotspot/agent/make/bugspot.bat @@ -22,4 +22,4 @@ REM have any questions. REM REM -java -showversion -cp ..\build\classes;..\src\share\lib\maf-1_0.jar;..\src\share\lib\jlfgr-1_0.jar;..\src\share\lib\js.jar;sa.jar;lib\maf-1_0.jar;lib\jlfgr-1_0.jar;lib\js.jar sun.jvm.hotspot.bugspot.Main +java -showversion -cp ..\build\classes;..\src\share\lib\js.jar;.\sa.jar;lib\js.jar sun.jvm.hotspot.bugspot.Main diff --git a/hotspot/agent/make/build.xml b/hotspot/agent/make/build.xml index ebd5d39b785..caad5c76974 100644 --- a/hotspot/agent/make/build.xml +++ b/hotspot/agent/make/build.xml @@ -42,7 +42,6 @@ - - - - - - + + + + + + + + + + + + diff --git a/hotspot/agent/make/hsdb.bat b/hotspot/agent/make/hsdb.bat index 6b12916d998..9d435179baf 100644 --- a/hotspot/agent/make/hsdb.bat +++ b/hotspot/agent/make/hsdb.bat @@ -22,4 +22,4 @@ REM have any questions. REM REM -java -showversion -cp ..\build\classes;..\src\share\lib\maf-1_0.jar;..\src\share\lib\jlfgr-1_0.jar;..\src\share\lib\js.jar;sa.jar;lib\maf-1_0.jar;lib\jlfgr-1_0.jar;lib\js.jar sun.jvm.hotspot.HSDB %1 %2 +java -showversion -cp ..\build\classes;..\src\share\lib\js.jar;.\sa.jar;lib\js.jar sun.jvm.hotspot.HSDB %1 %2 diff --git a/hotspot/agent/make/hsdb.sh b/hotspot/agent/make/hsdb.sh index 3e5cc2df040..4dd11081f31 100644 --- a/hotspot/agent/make/hsdb.sh +++ b/hotspot/agent/make/hsdb.sh @@ -29,4 +29,4 @@ if [ "x$SA_JAVA" = "x" ]; then SA_JAVA=java fi -$SA_JAVA -showversion -cp $STARTDIR/../build/classes:$STARTDIR/../src/share/lib/maf-1_0.jar:$STARTDIR/../src/share/lib/jlfgr-1_0.jar:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar:$STARTDIR/lib/maf-1_0.jar:$STARTDIR/lib/jlfgr-1_0.jar:$STARTDIR/lib/js.jar sun.jvm.hotspot.HSDB $* +$SA_JAVA -showversion -cp $STARTDIR/../build/classes:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar:$STARTDIR/lib/js.jar sun.jvm.hotspot.HSDB $* diff --git a/hotspot/agent/make/saenv.bat b/hotspot/agent/make/saenv.bat index b5342027b98..0bb3704aeaa 100644 --- a/hotspot/agent/make/saenv.bat +++ b/hotspot/agent/make/saenv.bat @@ -39,7 +39,7 @@ set SA_JAVA=java :sa_java_set -set SA_CLASSPATH=..\build\classes;..\src\share\lib\maf-1_0.jar;..\src\share\lib\jlfgr-1_0.jar;..\src\share\lib\js.jar;sa.jar;lib\maf-1_0.jar;lib\jlfgr-1_0.jar;lib\js.jar +set SA_CLASSPATH=..\build\classes;..\src\share\lib\js.jar;sa.jar;lib\js.jar set SA_LIBPATH=..\src\os\win32\windbg\i386;.\win32\i386 diff --git a/hotspot/agent/make/saenv.sh b/hotspot/agent/make/saenv.sh index e5e5c485dd4..d0b12c5ef8a 100644 --- a/hotspot/agent/make/saenv.sh +++ b/hotspot/agent/make/saenv.sh @@ -58,7 +58,7 @@ if [ "x$SA_DISABLE_VERS_CHK" != "x" ]; then fi -SA_CLASSPATH=$STARTDIR/../build/classes:$STARTDIR/../src/share/lib/maf-1_0.jar:$STARTDIR/../src/share/lib/jlfgr-1_0.jar:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar:$STARTDIR/lib/maf-1_0.jar:$STARTDIR/lib/jlfgr-1_0.jar:$STARTDIR/lib/js.jar +SA_CLASSPATH=$STARTDIR/../build/classes:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar:$STARTDIR/lib/js.jar OPTIONS="-Djava.system.class.loader=sun.jvm.hotspot.SALauncherLoader ${OPTIONS}" diff --git a/hotspot/agent/make/saenv64.bat b/hotspot/agent/make/saenv64.bat index 84e30c31bc2..305795268ca 100644 --- a/hotspot/agent/make/saenv64.bat +++ b/hotspot/agent/make/saenv64.bat @@ -43,7 +43,7 @@ set SA_JAVA=java :sa_java_set -set SA_CLASSPATH=..\build\classes;..\src\share\lib\maf-1_0.jar;..\src\share\lib\jlfgr-1_0.jar;..\src\share\lib\js.jar;sa.jar;lib\maf-1_0.jar;lib\jlfgr-1_0.jar;lib\js.jar +set SA_CLASSPATH=..\build\classes;..\src\share\lib\js.jar;sa.jar;lib\js.jar REM For now, only AMD-64, IA-64 stack walking is not working anyway set SA_LIBPATH=.\src\os\win32\windbg\amd64;.\win32\amd64 diff --git a/hotspot/agent/make/saenv64.sh b/hotspot/agent/make/saenv64.sh index ea22420496b..487004d6269 100644 --- a/hotspot/agent/make/saenv64.sh +++ b/hotspot/agent/make/saenv64.sh @@ -55,7 +55,7 @@ if [ "x$SA_DISABLE_VERS_CHK" != "x" ]; then OPTIONS="-Dsun.jvm.hotspot.runtime.VM.disableVersionCheck ${OPTIONS}" fi -SA_CLASSPATH=$STARTDIR/../build/classes:$STARTDIR/../src/share/lib/maf-1_0.jar:$STARTDIR/../src/share/lib/jlfgr-1_0.jar:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar:$STARTDIR/lib/maf-1_0.jar:$STARTDIR/lib/jlfgr-1_0.jar:$STARTDIR/lib/js.jar +SA_CLASSPATH=$STARTDIR/../build/classes:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar::$STARTDIR/lib/js.jar OPTIONS="-Djava.system.class.loader=sun.jvm.hotspot.SALauncherLoader ${OPTIONS}" diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/AboutAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/AboutAction.java new file mode 100644 index 00000000000..e6d1094a145 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/AboutAction.java @@ -0,0 +1,57 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class AboutAction extends DelegateAction +{ + + public AboutAction() + { + this("general/About16.gif"); + } + + public AboutAction(String iconPath) + { + super("About...", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "about-command"); + putValue("ShortDescription", "About..."); + putValue("LongDescription", "System information and version of the application."); + putValue("MnemonicKey", VALUE_MNEMONIC); + } + + public static final String VALUE_COMMAND = "about-command"; + public static final String VALUE_NAME = "About..."; + public static final String VALUE_SMALL_ICON = "general/About16.gif"; + public static final String VALUE_LARGE_ICON = "general/About24.gif"; + public static final Integer VALUE_MNEMONIC = new Integer(65); + public static final String VALUE_SHORT_DESCRIPTION = "About..."; + public static final String VALUE_LONG_DESCRIPTION = "System information and version of the application."; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/ActionManager.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ActionManager.java new file mode 100644 index 00000000000..d73fbda2eb7 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ActionManager.java @@ -0,0 +1,95 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import java.util.HashMap; +import javax.swing.Action; +import javax.swing.ImageIcon; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, StateChangeAction, ActionUtilities + +public abstract class ActionManager +{ + + protected ActionManager() + { + actions = new HashMap(); + addActions(); + } + + public static ActionManager getInstance() + { + return manager; + } + + protected abstract void addActions(); + + protected void addAction(String cmdname, Action action) + { + actions.put(cmdname, action); + } + + public Action getAction(String key) + { + return (Action)actions.get(key); + } + + public DelegateAction getDelegateAction(String name) + { + Action a = getAction(name); + if(a instanceof DelegateAction) + return (DelegateAction)a; + else + return null; + } + + public StateChangeAction getStateChangeAction(String name) + { + Action a = getAction(name); + if(a instanceof StateChangeAction) + return (StateChangeAction)a; + else + return null; + } + + public static ImageIcon getIcon(String name) + { + return utilities.getIcon(name); + } + + public void setActionEnabled(String name, boolean enabled) + { + Action action = getAction(name); + if(action != null) + action.setEnabled(enabled); + } + + private HashMap actions; + private static ActionUtilities utilities = new ActionUtilities(); + protected static ActionManager manager; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/ActionUtilities.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ActionUtilities.java new file mode 100644 index 00000000000..67097f77b00 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ActionUtilities.java @@ -0,0 +1,49 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.ImageIcon; + +class ActionUtilities +{ + + ActionUtilities() + { + } + + public ImageIcon getIcon(String name) + { + String imagePath = "/toolbarButtonGraphics/" + name; + java.net.URL url = getClass().getResource(imagePath); + if(url != null) + return new ImageIcon(url); + else + return null; + } + + public static final String IMAGE_DIR = "/toolbarButtonGraphics/"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/AlignCenterAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/AlignCenterAction.java new file mode 100644 index 00000000000..5ce24155ddd --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/AlignCenterAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// StateChangeAction, ActionManager + +public class AlignCenterAction extends StateChangeAction +{ + + public AlignCenterAction() + { + this("text/AlignCenter16.gif"); + } + + public AlignCenterAction(String iconPath) + { + super("Center", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "align-center-command"); + putValue("ShortDescription", "Center"); + putValue("LongDescription", "Adjust the placement of text to the center of the line"); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "align-center-command"; + public static final String VALUE_NAME = "Center"; + public static final String VALUE_SMALL_ICON = "text/AlignCenter16.gif"; + public static final String VALUE_LARGE_ICON = "text/AlignCenter24.gif"; + public static final Integer VALUE_MNEMONIC = new Integer(78); + public static final KeyStroke VALUE_ACCELERATOR = KeyStroke.getKeyStroke(69, 2); + public static final String VALUE_SHORT_DESCRIPTION = "Center"; + public static final String VALUE_LONG_DESCRIPTION = "Adjust the placement of text to the center of the line"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/AlignLeftAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/AlignLeftAction.java new file mode 100644 index 00000000000..b94f2c102f1 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/AlignLeftAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// StateChangeAction, ActionManager + +public class AlignLeftAction extends StateChangeAction +{ + + public AlignLeftAction() + { + this("text/AlignLeft16.gif"); + } + + public AlignLeftAction(String iconPath) + { + super("Left Align", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "align-left-command"); + putValue("ShortDescription", "Left Align"); + putValue("LongDescription", "Adjust the placement of text along the left edge"); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "align-left-command"; + public static final String VALUE_NAME = "Left Align"; + public static final String VALUE_SMALL_ICON = "text/AlignLeft16.gif"; + public static final String VALUE_LARGE_ICON = "text/AlignLeft24.gif"; + public static final Integer VALUE_MNEMONIC = new Integer(76); + public static final KeyStroke VALUE_ACCELERATOR = KeyStroke.getKeyStroke(76, 2); + public static final String VALUE_SHORT_DESCRIPTION = "Left Align"; + public static final String VALUE_LONG_DESCRIPTION = "Adjust the placement of text along the left edge"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/AlignRightAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/AlignRightAction.java new file mode 100644 index 00000000000..46c0204bf66 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/AlignRightAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// StateChangeAction, ActionManager + +public class AlignRightAction extends StateChangeAction +{ + + public AlignRightAction() + { + this("text/AlignRight16.gif"); + } + + public AlignRightAction(String iconPath) + { + super("Right Align", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "align-right-command"); + putValue("ShortDescription", "Right Align"); + putValue("LongDescription", "Adjust the placement of text along the right edge"); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "align-right-command"; + public static final String VALUE_NAME = "Right Align"; + public static final String VALUE_SMALL_ICON = "text/AlignRight16.gif"; + public static final String VALUE_LARGE_ICON = "text/AlignRight24.gif"; + public static final Integer VALUE_MNEMONIC = new Integer(82); + public static final KeyStroke VALUE_ACCELERATOR = KeyStroke.getKeyStroke(82, 2); + public static final String VALUE_SHORT_DESCRIPTION = "Right Align"; + public static final String VALUE_LONG_DESCRIPTION = "Adjust the placement of text along the right edge"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/ApplyAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ApplyAction.java new file mode 100644 index 00000000000..0851431c873 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ApplyAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class ApplyAction extends DelegateAction +{ + + public ApplyAction() + { + this(VALUE_SMALL_ICON); + } + + public ApplyAction(String iconPath) + { + super("Apply", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "apply-command"); + putValue("ShortDescription", "Apply the activity"); + putValue("LongDescription", "Apply the activity"); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "apply-command"; + public static final String VALUE_NAME = "Apply"; + public static final String VALUE_SMALL_ICON = null; + public static final String VALUE_LARGE_ICON = null; + public static final Integer VALUE_MNEMONIC = new Integer(65); + public static final KeyStroke VALUE_ACCELERATOR = null; + public static final String VALUE_SHORT_DESCRIPTION = "Apply the activity"; + public static final String VALUE_LONG_DESCRIPTION = "Apply the activity"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/BackAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/BackAction.java new file mode 100644 index 00000000000..d0163cc37bc --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/BackAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class BackAction extends DelegateAction +{ + + public BackAction() + { + this(VALUE_SMALL_ICON); + } + + public BackAction(String iconPath) + { + super("< Back", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "back-command"); + putValue("ShortDescription", "Select previous item"); + putValue("LongDescription", "Select previous item"); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "back-command"; + public static final String VALUE_NAME = "< Back"; + public static final String VALUE_SMALL_ICON = null; + public static final String VALUE_LARGE_ICON = null; + public static final Integer VALUE_MNEMONIC = new Integer(66); + public static final KeyStroke VALUE_ACCELERATOR = null; + public static final String VALUE_SHORT_DESCRIPTION = "Select previous item"; + public static final String VALUE_LONG_DESCRIPTION = "Select previous item"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/CancelAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/CancelAction.java new file mode 100644 index 00000000000..aa9801d588f --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/CancelAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class CancelAction extends DelegateAction +{ + + public CancelAction() + { + this(VALUE_SMALL_ICON); + } + + public CancelAction(String iconPath) + { + super("Cancel", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "cancel-command"); + putValue("ShortDescription", "Cancels the action"); + putValue("LongDescription", "Cancels the action"); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "cancel-command"; + public static final String VALUE_NAME = "Cancel"; + public static final String VALUE_SMALL_ICON = null; + public static final String VALUE_LARGE_ICON = null; + public static final Integer VALUE_MNEMONIC = new Integer(67); + public static final KeyStroke VALUE_ACCELERATOR = null; + public static final String VALUE_SHORT_DESCRIPTION = "Cancels the action"; + public static final String VALUE_LONG_DESCRIPTION = "Cancels the action"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/DelegateAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/DelegateAction.java new file mode 100644 index 00000000000..41e7ed80322 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/DelegateAction.java @@ -0,0 +1,65 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.AbstractAction; +import javax.swing.Icon; + +public abstract class DelegateAction extends AbstractAction +{ + + public DelegateAction(String name, Icon icon) + { + super(name, icon); + } + + public void addActionListener(ActionListener listener) + { + this.listener = listener; + } + + public void removeActionListener(ActionListener listener) + { + this.listener = null; + } + + public ActionListener[] getActionListeners() + { + return (new ActionListener[] { + listener + }); + } + + public void actionPerformed(ActionEvent evt) + { + if(listener != null) + listener.actionPerformed(evt); + } + + private ActionListener listener; +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/ExitAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ExitAction.java new file mode 100644 index 00000000000..79c5d31dff8 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ExitAction.java @@ -0,0 +1,55 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class ExitAction extends DelegateAction +{ + + public ExitAction() + { + super("Exit", ActionManager.getIcon(VALUE_SMALL_ICON)); + putValue("ActionCommandKey", "exit-command"); + putValue("ShortDescription", "Exits the application"); + putValue("LongDescription", "Exits the application"); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "exit-command"; + public static final String VALUE_NAME = "Exit"; + public static final String VALUE_SMALL_ICON = null; + public static final String VALUE_LARGE_ICON = null; + public static final Integer VALUE_MNEMONIC = new Integer(88); + public static final KeyStroke VALUE_ACCELERATOR = null; + public static final String VALUE_SHORT_DESCRIPTION = "Exits the application"; + public static final String VALUE_LONG_DESCRIPTION = "Exits the application"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/FileMenu.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/FileMenu.java new file mode 100644 index 00000000000..ab078b1b5e7 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/FileMenu.java @@ -0,0 +1,53 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import java.awt.event.ActionEvent; +import javax.swing.AbstractAction; + +public class FileMenu extends AbstractAction +{ + + public FileMenu() + { + super("File"); + putValue("ActionCommandKey", "file-menu-command"); + putValue("ShortDescription", "File operations"); + putValue("LongDescription", "File operations"); + putValue("MnemonicKey", VALUE_MNEMONIC); + } + + public void actionPerformed(ActionEvent actionevent) + { + } + + public static final String VALUE_COMMAND = "file-menu-command"; + public static final String VALUE_NAME = "File"; + public static final Integer VALUE_MNEMONIC = new Integer(70); + public static final String VALUE_SHORT_DESCRIPTION = "File operations"; + public static final String VALUE_LONG_DESCRIPTION = "File operations"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/FinishAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/FinishAction.java new file mode 100644 index 00000000000..1e80dc2e7fc --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/FinishAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class FinishAction extends DelegateAction +{ + + public FinishAction() + { + this(VALUE_SMALL_ICON); + } + + public FinishAction(String iconPath) + { + super("Finish", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "finish-command"); + putValue("ShortDescription", "Finish the activity"); + putValue("LongDescription", "Finish the activity"); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "finish-command"; + public static final String VALUE_NAME = "Finish"; + public static final String VALUE_SMALL_ICON = null; + public static final String VALUE_LARGE_ICON = null; + public static final Integer VALUE_MNEMONIC = new Integer(70); + public static final KeyStroke VALUE_ACCELERATOR = null; + public static final String VALUE_SHORT_DESCRIPTION = "Finish the activity"; + public static final String VALUE_LONG_DESCRIPTION = "Finish the activity"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/HelpAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/HelpAction.java new file mode 100644 index 00000000000..73cf8ec1e5b --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/HelpAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class HelpAction extends DelegateAction +{ + + public HelpAction() + { + this("general/Help16.gif"); + } + + public HelpAction(String iconPath) + { + super("Help", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "help-command"); + putValue("ShortDescription", "Help..."); + putValue("LongDescription", "Provide information which may aid the user."); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "help-command"; + public static final String VALUE_NAME = "Help"; + public static final String VALUE_SMALL_ICON = "general/Help16.gif"; + public static final String VALUE_LARGE_ICON = "general/Help24.gif"; + public static final Integer VALUE_MNEMONIC = new Integer(72); + public static final KeyStroke VALUE_ACCELERATOR = KeyStroke.getKeyStroke(112, 0); + public static final String VALUE_SHORT_DESCRIPTION = "Help..."; + public static final String VALUE_LONG_DESCRIPTION = "Provide information which may aid the user."; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/HelpMenu.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/HelpMenu.java new file mode 100644 index 00000000000..c329ab4b47e --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/HelpMenu.java @@ -0,0 +1,53 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import java.awt.event.ActionEvent; +import javax.swing.AbstractAction; + +public class HelpMenu extends AbstractAction +{ + + public HelpMenu() + { + super("Help"); + putValue("ActionCommandKey", "help-menu-command"); + putValue("ShortDescription", "Help operations"); + putValue("LongDescription", "Help operations"); + putValue("MnemonicKey", VALUE_MNEMONIC); + } + + public void actionPerformed(ActionEvent actionevent) + { + } + + public static final String VALUE_COMMAND = "help-menu-command"; + public static final String VALUE_NAME = "Help"; + public static final Integer VALUE_MNEMONIC = new Integer(72); + public static final String VALUE_SHORT_DESCRIPTION = "Help operations"; + public static final String VALUE_LONG_DESCRIPTION = "Help operations"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/NewAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/NewAction.java new file mode 100644 index 00000000000..62d4f54a3ff --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/NewAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class NewAction extends DelegateAction +{ + + public NewAction() + { + this("general/New16.gif"); + } + + public NewAction(String iconPath) + { + super("New", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "new-command"); + putValue("ShortDescription", "Create a new object."); + putValue("LongDescription", "Create a new object."); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "new-command"; + public static final String VALUE_NAME = "New"; + public static final String VALUE_SMALL_ICON = "general/New16.gif"; + public static final String VALUE_LARGE_ICON = "general/New24.gif"; + public static final Integer VALUE_MNEMONIC = new Integer(78); + public static final KeyStroke VALUE_ACCELERATOR = KeyStroke.getKeyStroke(78, 2); + public static final String VALUE_SHORT_DESCRIPTION = "Create a new object."; + public static final String VALUE_LONG_DESCRIPTION = "Create a new object."; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/NextAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/NextAction.java new file mode 100644 index 00000000000..a133198ba70 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/NextAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class NextAction extends DelegateAction +{ + + public NextAction() + { + this(VALUE_SMALL_ICON); + } + + public NextAction(String iconPath) + { + super("Next >", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "next-command"); + putValue("ShortDescription", "Select next item"); + putValue("LongDescription", "Select next item"); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "next-command"; + public static final String VALUE_NAME = "Next >"; + public static final String VALUE_SMALL_ICON = null; + public static final String VALUE_LARGE_ICON = null; + public static final Integer VALUE_MNEMONIC = new Integer(78); + public static final KeyStroke VALUE_ACCELERATOR = null; + public static final String VALUE_SHORT_DESCRIPTION = "Select next item"; + public static final String VALUE_LONG_DESCRIPTION = "Select next item"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/OkAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/OkAction.java new file mode 100644 index 00000000000..87bd03efed3 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/OkAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class OkAction extends DelegateAction +{ + + public OkAction() + { + this(VALUE_SMALL_ICON); + } + + public OkAction(String iconPath) + { + super("OK", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "ok-command"); + putValue("ShortDescription", "Acknowleges the action"); + putValue("LongDescription", "Acknowleges the action"); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "ok-command"; + public static final String VALUE_NAME = "OK"; + public static final String VALUE_SMALL_ICON = null; + public static final String VALUE_LARGE_ICON = null; + public static final Integer VALUE_MNEMONIC = new Integer(79); + public static final KeyStroke VALUE_ACCELERATOR = null; + public static final String VALUE_SHORT_DESCRIPTION = "Acknowleges the action"; + public static final String VALUE_LONG_DESCRIPTION = "Acknowleges the action"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/OpenAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/OpenAction.java new file mode 100644 index 00000000000..82609a0ecb2 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/OpenAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class OpenAction extends DelegateAction +{ + + public OpenAction() + { + this("general/Open16.gif"); + } + + public OpenAction(String iconPath) + { + super("Open...", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "open-command"); + putValue("ShortDescription", "Open the specified object."); + putValue("LongDescription", "Open the specified object."); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "open-command"; + public static final String VALUE_NAME = "Open..."; + public static final String VALUE_SMALL_ICON = "general/Open16.gif"; + public static final String VALUE_LARGE_ICON = "general/Open24.gif"; + public static final Integer VALUE_MNEMONIC = new Integer(79); + public static final KeyStroke VALUE_ACCELERATOR = KeyStroke.getKeyStroke(79, 2); + public static final String VALUE_SHORT_DESCRIPTION = "Open the specified object."; + public static final String VALUE_LONG_DESCRIPTION = "Open the specified object."; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/SaveAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/SaveAction.java new file mode 100644 index 00000000000..3255d2856d8 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/SaveAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class SaveAction extends DelegateAction +{ + + public SaveAction() + { + this("general/Save16.gif"); + } + + public SaveAction(String iconPath) + { + super("Save", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "save-command"); + putValue("ShortDescription", "Commit changes to a permanent storage area"); + putValue("LongDescription", "Commit changes to a permanent storage area"); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "save-command"; + public static final String VALUE_NAME = "Save"; + public static final String VALUE_SMALL_ICON = "general/Save16.gif"; + public static final String VALUE_LARGE_ICON = "general/Save24.gif"; + public static final Integer VALUE_MNEMONIC = new Integer(83); + public static final KeyStroke VALUE_ACCELERATOR = KeyStroke.getKeyStroke(83, 2); + public static final String VALUE_SHORT_DESCRIPTION = "Commit changes to a permanent storage area"; + public static final String VALUE_LONG_DESCRIPTION = "Commit changes to a permanent storage area"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/SaveAsAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/SaveAsAction.java new file mode 100644 index 00000000000..385024da9df --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/SaveAsAction.java @@ -0,0 +1,57 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class SaveAsAction extends DelegateAction +{ + + public SaveAsAction() + { + this("general/SaveAs16.gif"); + } + + public SaveAsAction(String iconPath) + { + super("Save As", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "save-as-command"); + putValue("ShortDescription", "Save as a new file"); + putValue("LongDescription", "Saves the current object as another object"); + putValue("MnemonicKey", VALUE_MNEMONIC); + } + + public static final String VALUE_COMMAND = "save-as-command"; + public static final String VALUE_NAME = "Save As"; + public static final String VALUE_SMALL_ICON = "general/SaveAs16.gif"; + public static final String VALUE_LARGE_ICON = "general/SaveAs24.gif"; + public static final Integer VALUE_MNEMONIC = new Integer(65); + public static final String VALUE_SHORT_DESCRIPTION = "Save as a new file"; + public static final String VALUE_LONG_DESCRIPTION = "Saves the current object as another object"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/StateChangeAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/StateChangeAction.java new file mode 100644 index 00000000000..d00761feeb8 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/StateChangeAction.java @@ -0,0 +1,88 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import javax.swing.Icon; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction + +public abstract class StateChangeAction extends DelegateAction + implements ItemListener +{ + + public StateChangeAction(String name) + { + super(name, null); + selected = false; + } + + public StateChangeAction(String name, Icon icon) + { + super(name, icon); + selected = false; + } + + public boolean isSelected() + { + return selected; + } + + public synchronized void setSelected(boolean newValue) + { + boolean oldValue = selected; + if(oldValue != newValue) + { + selected = newValue; + firePropertyChange("selected", Boolean.valueOf(oldValue), Boolean.valueOf(newValue)); + } + } + + public void setItemListener(ItemListener listener) + { + this.listener = listener; + } + + public ItemListener getItemListener() + { + return listener; + } + + public void itemStateChanged(ItemEvent evt) + { + if(evt.getStateChange() == 1) + setSelected(true); + else + setSelected(false); + if(listener != null) + listener.itemStateChanged(evt); + } + + protected boolean selected; + private ItemListener listener; +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/ViewMenu.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ViewMenu.java new file mode 100644 index 00000000000..5501ba8fcb7 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ViewMenu.java @@ -0,0 +1,53 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import java.awt.event.ActionEvent; +import javax.swing.AbstractAction; + +public class ViewMenu extends AbstractAction +{ + + public ViewMenu() + { + super("View"); + putValue("ActionCommandKey", "view-menu-command"); + putValue("ShortDescription", "View operations"); + putValue("LongDescription", "View operations"); + putValue("MnemonicKey", VALUE_MNEMONIC); + } + + public void actionPerformed(ActionEvent actionevent) + { + } + + public static final String VALUE_COMMAND = "view-menu-command"; + public static final String VALUE_NAME = "View"; + public static final Integer VALUE_MNEMONIC = new Integer(86); + public static final String VALUE_SHORT_DESCRIPTION = "View operations"; + public static final String VALUE_LONG_DESCRIPTION = "View operations"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/ui/CommonMenuBar.java b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/CommonMenuBar.java new file mode 100644 index 00000000000..20ebbb52111 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/CommonMenuBar.java @@ -0,0 +1,108 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.ui; + +import com.sun.java.swing.action.ActionManager; +import com.sun.java.swing.action.StateChangeAction; +import javax.swing.*; + +// Referenced classes of package com.sun.java.swing.ui: +// ToggleActionPropertyChangeListener, StatusBar + +public abstract class CommonMenuBar extends JMenuBar +{ + + protected CommonMenuBar(ActionManager manager) + { + this(manager, StatusBar.getInstance()); + } + + protected CommonMenuBar(ActionManager manager, StatusBar status) + { + this.manager = manager; + statusBar = status; + configureMenu(); + } + + protected abstract void configureMenu(); + + protected void configureToggleMenuItem(JMenuItem menuItem, Action action) + { + configureMenuItem(menuItem, action); + action.addPropertyChangeListener(new ToggleActionPropertyChangeListener(menuItem)); + } + + protected void configureMenuItem(JMenuItem menuItem, Action action) + { + menuItem.addMouseListener(statusBar); + } + + protected JMenu createMenu(String name, char mnemonic) + { + JMenu menu = new JMenu(name); + menu.setMnemonic(mnemonic); + return menu; + } + + protected void addMenuItem(JMenu menu, Action action) + { + JMenuItem menuItem = menu.add(action); + configureMenuItem(menuItem, action); + } + + protected void addCheckBoxMenuItem(JMenu menu, StateChangeAction a) + { + addCheckBoxMenuItem(menu, a, false); + } + + protected void addCheckBoxMenuItem(JMenu menu, StateChangeAction a, boolean selected) + { + JCheckBoxMenuItem mi = new JCheckBoxMenuItem(a); + mi.addItemListener(a); + mi.setSelected(selected); + menu.add(mi); + configureToggleMenuItem(mi, a); + } + + protected void addRadioButtonMenuItem(JMenu menu, ButtonGroup group, StateChangeAction a) + { + addRadioButtonMenuItem(menu, group, a, false); + } + + protected void addRadioButtonMenuItem(JMenu menu, ButtonGroup group, StateChangeAction a, boolean selected) + { + JRadioButtonMenuItem mi = new JRadioButtonMenuItem(a); + mi.addItemListener(a); + mi.setSelected(selected); + menu.add(mi); + if(group != null) + group.add(mi); + configureToggleMenuItem(mi, a); + } + + protected ActionManager manager; + private StatusBar statusBar; +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/ui/CommonToolBar.java b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/CommonToolBar.java new file mode 100644 index 00000000000..d65e06e3af8 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/CommonToolBar.java @@ -0,0 +1,95 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.ui; + +import com.sun.java.swing.action.ActionManager; +import com.sun.java.swing.action.StateChangeAction; +import java.awt.Dimension; +import java.awt.Insets; +import javax.swing.*; + +// Referenced classes of package com.sun.java.swing.ui: +// ToggleActionPropertyChangeListener, StatusBar, CommonUI + +public abstract class CommonToolBar extends JToolBar +{ + + protected CommonToolBar(ActionManager manager) + { + this(manager, StatusBar.getInstance()); + } + + protected CommonToolBar(ActionManager manager, StatusBar status) + { + this.manager = manager; + statusBar = status; + buttonSize = new Dimension(CommonUI.buttconPrefSize); + buttonInsets = new Insets(0, 0, 0, 0); + addComponents(); + } + + protected abstract void addComponents(); + + protected void addButton(Action action) + { + javax.swing.JButton button = add(action); + configureButton(button, action); + } + + protected void addToggleButton(StateChangeAction a) + { + addToggleButton(a, null); + } + + protected void addToggleButton(StateChangeAction a, ButtonGroup group) + { + JToggleButton button = new JToggleButton(a); + button.addItemListener(a); + button.setSelected(a.isSelected()); + if(group != null) + group.add(button); + add(button); + configureToggleButton(button, a); + } + + protected void configureToggleButton(JToggleButton button, Action action) + { + configureButton(button, action); + action.addPropertyChangeListener(new ToggleActionPropertyChangeListener(button)); + } + + protected void configureButton(AbstractButton button, Action action) + { + button.setToolTipText((String)action.getValue("Name")); + button.setText(""); + button.addMouseListener(statusBar); + } + + protected ActionManager manager; + private Dimension buttonSize; + private Insets buttonInsets; + private StatusBar statusBar; +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/ui/CommonUI.java b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/CommonUI.java new file mode 100644 index 00000000000..6429ea0fa31 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/CommonUI.java @@ -0,0 +1,392 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.ui; + +import java.awt.*; +import java.awt.event.ActionListener; +import java.awt.event.KeyListener; +import java.util.StringTokenizer; +import java.util.Vector; +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.text.*; + +public class CommonUI +{ + private static class NumberDocument extends PlainDocument + { + + public void insertString(int offs, String str, AttributeSet atts) + throws BadLocationException + { + if(!Character.isDigit(str.charAt(0))) + { + return; + } else + { + super.insertString(offs, str, atts); + return; + } + } + + private NumberDocument() + { + } + + } + + + public CommonUI() + { + } + + public static JLabel createLabel(String text, int mnemonic, Component comp) + { + JLabel label = new JLabel(" " + text); + label.setMinimumSize(labelPrefSize); + if(mnemonic != -1) + label.setDisplayedMnemonic(mnemonic); + if(comp != null) + label.setLabelFor(comp); + if(text.length() == 0) + label.setPreferredSize(labelPrefSize); + return label; + } + + public static JLabel createLabel(String text) + { + return createLabel(text, -1, null); + } + + public static JTextField createTextField(String text, KeyListener listener, boolean numbers) + { + JTextField field = new JTextField(text); + field.setMinimumSize(textPrefSize); + if(text.length() == 0) + field.setPreferredSize(textPrefSize); + if(listener != null) + field.addKeyListener(listener); + if(numbers) + field.setDocument(new NumberDocument()); + return field; + } + + public static JTextField createTextField(String text, boolean numbers) + { + return createTextField(text, null, numbers); + } + + public static JTextField createTextField(String text, KeyListener listener) + { + return createTextField(text, listener, false); + } + + public static JTextField createTextField(String text) + { + return createTextField(text, null, false); + } + + public static JRadioButton createRadioButton(String text, int mnemonic, ActionListener listener, boolean selected) + { + JRadioButton button = new JRadioButton(text); + button.setMnemonic(mnemonic); + button.setSelected(selected); + button.setMinimumSize(labelPrefSize); + if(listener != null) + button.addActionListener(listener); + if(text.length() == 0) + button.setPreferredSize(labelPrefSize); + return button; + } + + public static JRadioButton createRadioButton(String text, int mnemonic, boolean selected) + { + return createRadioButton(text, mnemonic, null, selected); + } + + public static JRadioButton createRadioButton(String text, int mnemonic, ActionListener listener) + { + return createRadioButton(text, mnemonic, listener, false); + } + + public static JRadioButton createRadioButton(String text, int mnemonic) + { + return createRadioButton(text, mnemonic, null, false); + } + + public static JRadioButton createRadioButton(String text) + { + return createRadioButton(text, -1, null, false); + } + + public static JCheckBox createCheckBox(String text, int mnemonic, ActionListener listener, boolean selected) + { + JCheckBox checkbox = new JCheckBox(text); + checkbox.setMinimumSize(labelPrefSize); + if(mnemonic != -1) + checkbox.setMnemonic(mnemonic); + checkbox.setSelected(selected); + if(text.length() == 0) + checkbox.setPreferredSize(labelPrefSize); + if(listener != null) + checkbox.addActionListener(listener); + return checkbox; + } + + public static JCheckBox createCheckBox(String text, int mnemonic, ActionListener listener) + { + return createCheckBox(text, mnemonic, listener, false); + } + + public static JCheckBox createCheckBox(String text, int mnemonic, boolean selected) + { + return createCheckBox(text, mnemonic, null, selected); + } + + public static JCheckBox createCheckBox(String text, int mnemonic) + { + return createCheckBox(text, mnemonic, null, false); + } + + public static JCheckBox createCheckBox(String text) + { + return createCheckBox(text, -1, null, false); + } + + public static JComboBox createComboBox(Object items[], ActionListener listener, boolean editable) + { + JComboBox comboBox = new JComboBox(items); + if(listener != null) + comboBox.addActionListener(listener); + comboBox.setEditable(editable); + return comboBox; + } + + public static JComboBox createComboBox(Object items[], boolean editable) + { + return createComboBox(items, null, editable); + } + + public static JComboBox createComboBox(Vector items, ActionListener listener, boolean editable) + { + JComboBox comboBox = new JComboBox(items); + if(listener != null) + comboBox.addActionListener(listener); + comboBox.setEditable(editable); + return comboBox; + } + + public static JComboBox createComboBox(Vector items, boolean editable) + { + return createComboBox(items, null, editable); + } + + public static JButton createButton(Action action) + { + JButton button = new JButton(action); + setButtonSize(button, buttonPrefSize); + return button; + } + + public static JButton createButton(String text, ActionListener listener, int mnemonic) + { + JButton button = new JButton(text); + if(listener != null) + button.addActionListener(listener); + if(mnemonic != -1) + button.setMnemonic(mnemonic); + setButtonSize(button, buttonPrefSize); + return button; + } + + private static void setButtonSize(JButton button, Dimension size) + { + String text = button.getText(); + button.setMinimumSize(size); + if(text.length() == 0) + { + button.setPreferredSize(size); + } else + { + Dimension psize = button.getPreferredSize(); + if(psize.width < size.width) + button.setPreferredSize(size); + } + } + + public static JButton createButton(String text, ActionListener listener) + { + return createButton(text, listener, -1); + } + + public static JButton createSmallButton(String text, ActionListener listener, int mnemonic) + { + JButton button = createButton(text, listener, mnemonic); + setButtonSize(button, smbuttonPrefSize); + return button; + } + + public static JButton createSmallButton(String text, ActionListener listener) + { + return createSmallButton(text, listener, -1); + } + + public static Border createBorder(String text) + { + Border border = BorderFactory.createEtchedBorder(); + return BorderFactory.createTitledBorder(border, text, 0, 2); + } + + public static Border createBorder() + { + return BorderFactory.createEmptyBorder(4, 4, 4, 4); + } + + public static JScrollPane createListPane(JList list, String text) + { + JScrollPane pane = new JScrollPane(list); + pane.setBorder(BorderFactory.createCompoundBorder(createBorder(text), BorderFactory.createLoweredBevelBorder())); + return pane; + } + + public static void centerComponent(Component source, Component parent) + { + Dimension dim = source.getSize(); + Rectangle rect; + if(parent != null) + { + rect = parent.getBounds(); + } else + { + Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); + rect = new Rectangle(0, 0, d.width, d.height); + } + int x = rect.x + (rect.width - dim.width) / 2; + int y = rect.y + (rect.height - dim.height) / 2; + source.setLocation(x, y); + } + + public static void centerComponent(Component source) + { + centerComponent(source, null); + } + + public static JFrame getParentFrame(Component source) + { + Container parent; + for(parent = source.getParent(); parent != null; parent = parent.getParent()) + if(parent instanceof JFrame) + break; + + if(parent == null) + return null; + else + return (JFrame)parent; + } + + public static Integer msToSec(Integer ms) + { + int value = ms.intValue(); + value /= 1000; + return new Integer(value); + } + + public static Integer secToMs(Integer sec) + { + int value = sec.intValue(); + value *= 1000; + return new Integer(value); + } + + public static String stringFromStringArray(String strings[], String delim) + { + String string = ""; + String separator; + if(delim == null || delim.equals("")) + separator = " "; + else + separator = delim; + for(int i = 0; i < strings.length; i++) + { + string = string + strings[i]; + string = string + separator; + } + + return string; + } + + public static String stringFromStringArray(String strings[]) + { + return stringFromStringArray(strings, ""); + } + + public static String[] stringArrayFromString(String string, String delim) + { + StringTokenizer st; + if(delim == null || delim.equals("")) + st = new StringTokenizer(string); + else + st = new StringTokenizer(string, delim); + int numTokens = st.countTokens(); + String strings[] = new String[numTokens]; + int index = 0; + while(st.hasMoreTokens()) + strings[index++] = st.nextToken(); + return strings; + } + + public static String[] stringArrayFromString(String string) + { + return stringArrayFromString(string, ""); + } + + public static void setWaitCursor(Component comp) + { + comp.setCursor(Cursor.getPredefinedCursor(3)); + } + + public static void setDefaultCursor(Component comp) + { + comp.setCursor(Cursor.getPredefinedCursor(0)); + } + + public static final int BUTTON_WIDTH = 100; + public static final int BUTTON_HEIGHT = 26; + public static final int BUTTCON_WIDTH = 28; + public static final int BUTTCON_HEIGHT = 28; + public static final int SM_BUTTON_WIDTH = 72; + public static final int SM_BUTTON_HEIGHT = 26; + public static final int LABEL_WIDTH = 100; + public static final int LABEL_HEIGHT = 20; + public static final int TEXT_WIDTH = 150; + public static final int TEXT_HEIGHT = 20; + public static Dimension buttonPrefSize = new Dimension(100, 26); + public static Dimension buttconPrefSize = new Dimension(28, 28); + public static Dimension smbuttonPrefSize = new Dimension(72, 26); + public static Dimension labelPrefSize = new Dimension(100, 20); + public static Dimension textPrefSize = new Dimension(150, 20); + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/ui/OkCancelButtonPanel.java b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/OkCancelButtonPanel.java new file mode 100644 index 00000000000..d89404dffd7 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/OkCancelButtonPanel.java @@ -0,0 +1,51 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.ui; + +import com.sun.java.swing.action.*; +import java.awt.event.ActionListener; +import javax.swing.JPanel; + +// Referenced classes of package com.sun.java.swing.ui: +// CommonUI + +public class OkCancelButtonPanel extends JPanel +{ + + public OkCancelButtonPanel(ActionListener listener) + { + DelegateAction okAction = new OkAction(); + okAction.addActionListener(listener); + DelegateAction cancelAction = new CancelAction(); + cancelAction.addActionListener(listener); + add(CommonUI.createButton(okAction)); + add(CommonUI.createButton(cancelAction)); + } + + public static final String OK_COMMAND = "ok-command"; + public static final String CANCEL_COMMAND = "cancel-command"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/ui/OkCancelDialog.java b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/OkCancelDialog.java new file mode 100644 index 00000000000..619a97c4fb8 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/OkCancelDialog.java @@ -0,0 +1,82 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.ui; + +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.JDialog; +import javax.swing.JPanel; + +// Referenced classes of package com.sun.java.swing.ui: +// OkCancelButtonPanel, CommonUI + +public class OkCancelDialog extends JDialog + implements ActionListener +{ + + public OkCancelDialog(String title, JPanel panel) + { + this(title, panel, true); + } + + public OkCancelDialog(String title, JPanel panel, boolean modal) + { + setTitle(title); + setModal(modal); + Container pane = getContentPane(); + pane.setLayout(new BorderLayout()); + pane.add(panel, "Center"); + pane.add(new OkCancelButtonPanel(this), "South"); + pack(); + CommonUI.centerComponent(this); + } + + public boolean isOk() + { + return okPressed; + } + + public void actionPerformed(ActionEvent evt) + { + String command = evt.getActionCommand(); + if(command.equals("ok-command")) + { + okPressed = true; + setVisible(false); + dispose(); + } else + if(command.equals("cancel-command")) + { + okPressed = false; + setVisible(false); + dispose(); + } + } + + private boolean okPressed; +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/ui/SplashScreen.java b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/SplashScreen.java new file mode 100644 index 00000000000..4f575f9cc03 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/SplashScreen.java @@ -0,0 +1,85 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.ui; + +import java.awt.*; +import javax.swing.ImageIcon; + +public class SplashScreen extends Window +{ + + public SplashScreen(Frame f) + { + super(f); + setBackground(Color.white); + java.net.URL url = getClass().getResource("/images/SplashScreen.jpg"); + if(url != null) + { + screen = new ImageIcon(url); + MediaTracker mt = new MediaTracker(this); + mt.addImage(screen.getImage(), 0); + try + { + mt.waitForAll(); + } + catch(Exception ex) { } + } + } + + public void setVisible(boolean val) + { + if(screen == null) + return; + if(val) + { + setSize(screen.getIconWidth(), screen.getIconHeight()); + setLocation(-500, -500); + super.setVisible(true); + Dimension d = getToolkit().getScreenSize(); + Insets i = getInsets(); + int w = screen.getIconWidth() + i.left + i.right; + int h = screen.getIconHeight() + i.top + i.bottom; + setSize(w, h); + setLocation(d.width / 2 - w / 2, d.height / 2 - h / 2); + } else + { + super.setVisible(false); + } + } + + public void paint(Graphics g) + { + if(screen != null) + { + Dimension d = getSize(); + g.setColor(Color.black); + g.drawRect(0, 0, d.width - 1, d.height - 1); + g.drawImage(screen.getImage(), 1, 1, this); + } + } + + private ImageIcon screen; +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/ui/StatusBar.java b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/StatusBar.java new file mode 100644 index 00000000000..dd041974216 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/StatusBar.java @@ -0,0 +1,178 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.ui; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + +public class StatusBar extends JPanel + implements ActionListener, MouseListener +{ + + public StatusBar() + { + setLayout(new FlowLayout(0)); + setBorder(BorderFactory.createEtchedBorder()); + progressBar = new JProgressBar(0, 0, 100); + progressBar.setPreferredSize(new Dimension(60, progressBar.getPreferredSize().height + 2)); + progressBar.setVisible(false); + label = new JLabel(" "); + preferredSize = new Dimension(getWidth(label.getText()), 2 * getFontHeight()); + add(progressBar); + add(label); + } + + public static StatusBar getInstance() + { + if(statusBar == null) + statusBar = new StatusBar(); + return statusBar; + } + + public static void setInstance(StatusBar sb) + { + statusBar = sb; + } + + protected int getWidth(String s) + { + FontMetrics fm = getFontMetrics(getFont()); + if(fm == null) + return 0; + else + return fm.stringWidth(s); + } + + protected int getFontHeight() + { + FontMetrics fm = getFontMetrics(getFont()); + if(fm == null) + return 0; + else + return fm.getHeight(); + } + + public Dimension getPreferredSize() + { + return preferredSize; + } + + public void setMessage(String message) + { + label.setText(message); + label.repaint(); + } + + public void startBusyBar() + { + forward = true; + if(timer == null) + { + setMessage(""); + progressBar.setVisible(true); + timer = new Timer(15, this); + timer.start(); + } + } + + public void stopBusyBar() + { + if(timer != null) + { + timer.stop(); + timer = null; + } + setMessage(""); + progressBar.setVisible(false); + progressBar.setValue(0); + } + + public void actionPerformed(ActionEvent evt) + { + int value = progressBar.getValue(); + if(forward) + { + if(value < 100) + { + progressBar.setValue(value + 1); + } else + { + forward = false; + progressBar.setValue(value - 1); + } + } else + if(value > 0) + { + progressBar.setValue(value - 1); + } else + { + forward = true; + progressBar.setValue(value + 1); + } + } + + public void mouseClicked(MouseEvent mouseevent) + { + } + + public void mousePressed(MouseEvent mouseevent) + { + } + + public void mouseReleased(MouseEvent mouseevent) + { + } + + public void mouseExited(MouseEvent evt) + { + setMessage(""); + } + + public void mouseEntered(MouseEvent evt) + { + if(evt.getSource() instanceof AbstractButton) + { + AbstractButton button = (AbstractButton)evt.getSource(); + Action action = button.getAction(); + if(action != null) + { + String message = (String)action.getValue("LongDescription"); + setMessage(message); + } + } + } + + private static final int PROGRESS_MAX = 100; + private static final int PROGRESS_MIN = 0; + private JLabel label; + private Dimension preferredSize; + private JProgressBar progressBar; + private Timer timer; + private boolean forward; + private static StatusBar statusBar; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/ui/TabsDlg.java b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/TabsDlg.java new file mode 100644 index 00000000000..bace0097ef6 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/TabsDlg.java @@ -0,0 +1,221 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.ui; + +import com.sun.java.swing.action.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Vector; +import javax.swing.*; + +// Referenced classes of package com.sun.java.swing.ui: +// CommonUI + +public class TabsDlg extends JDialog +{ + private class ApplyListener + implements ActionListener + { + + public void actionPerformed(ActionEvent evt) + { + if(applyListener != null) + { + applyListener.actionPerformed(evt); + enableApplyButton(false); + } + } + + private ApplyListener() + { + } + + } + + private class CancelListener + implements ActionListener + { + + public void actionPerformed(ActionEvent evt) + { + if(cancelListener != null) + cancelListener.actionPerformed(evt); + setVisible(false); + } + + private CancelListener() + { + } + + } + + private class OkListener + implements ActionListener + { + + public void actionPerformed(ActionEvent evt) + { + if(okListener != null) + okListener.actionPerformed(evt); + setVisible(false); + } + + private OkListener() + { + } + + } + + + public TabsDlg(String title, Vector panels) + { + super(new JFrame(), title, true); + okListener = null; + cancelListener = null; + applyListener = null; + Container pane = getContentPane(); + pane.setLayout(new BorderLayout()); + tabsPanel = new JTabbedPane(); + int numPanels = panels.size(); + for(int i = 0; i < numPanels; i++) + { + JPanel panel = (JPanel)panels.elementAt(i); + tabsPanel.addTab(panel.getName(), panel); + } + + pane.add(tabsPanel, "Center"); + pane.add(createButtonPanel(), "South"); + pack(); + CommonUI.centerComponent(this); + } + + public static void main(String args[]) + { + JPanel p1 = new JPanel(); + p1.add(new JButton("One")); + p1.setName("One"); + JPanel p2 = new JPanel(); + p2.add(new JButton("Two")); + p2.setName("Two"); + JPanel p3 = new JPanel(); + p3.add(new JButton("Three")); + p3.setName("Three"); + JPanel p4 = new JPanel(); + p4.add(new JButton("Four")); + p4.setName("Four"); + Vector panels = new Vector(); + panels.addElement(p1); + panels.addElement(p2); + panels.addElement(p3); + panels.addElement(p4); + tabsDlg = new TabsDlg("Test Dialog", panels); + tabsDlg.addOkListener(new ActionListener() { + + public void actionPerformed(ActionEvent evt) + { + System.exit(0); + } + + } +); + tabsDlg.addCancelListener(new ActionListener() { + + public void actionPerformed(ActionEvent evt) + { + System.exit(0); + } + + } +); + tabsDlg.setVisible(true); + } + + private JPanel createButtonPanel() + { + JPanel panel = new JPanel(); + okAction = new OkAction(); + cancelAction = new CancelAction(); + applyAction = new ApplyAction(); + okAction.addActionListener(new OkListener()); + cancelAction.addActionListener(new CancelListener()); + applyAction.addActionListener(new ApplyListener()); + panel.add(CommonUI.createButton(okAction)); + panel.add(CommonUI.createButton(cancelAction)); + panel.add(CommonUI.createButton(applyAction)); + JPanel p2 = new JPanel(new BorderLayout()); + p2.add(panel, "Center"); + p2.add(new JSeparator(), "North"); + return p2; + } + + public void enableApplyButton(boolean enabled) + { + applyAction.setEnabled(enabled); + } + + public synchronized void addOkListener(ActionListener l) + { + okListener = AWTEventMulticaster.add(okListener, l); + } + + public synchronized void removeOkListener(ActionListener l) + { + okListener = AWTEventMulticaster.remove(okListener, l); + } + + public synchronized void addCancelListener(ActionListener l) + { + cancelListener = AWTEventMulticaster.add(cancelListener, l); + } + + public synchronized void removeCancelListener(ActionListener l) + { + cancelListener = AWTEventMulticaster.remove(cancelListener, l); + } + + public synchronized void addApplyListener(ActionListener l) + { + applyListener = AWTEventMulticaster.add(applyListener, l); + } + + public synchronized void removeApplyListener(ActionListener l) + { + applyListener = AWTEventMulticaster.remove(applyListener, l); + } + + private JTabbedPane tabsPanel; + private DelegateAction okAction; + private DelegateAction cancelAction; + private DelegateAction applyAction; + private ActionListener okListener; + private ActionListener cancelListener; + private ActionListener applyListener; + private static TabsDlg tabsDlg; + + + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/ui/ToggleActionPropertyChangeListener.java b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/ToggleActionPropertyChangeListener.java new file mode 100644 index 00000000000..afeeece4960 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/ToggleActionPropertyChangeListener.java @@ -0,0 +1,52 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.ui; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.AbstractButton; + +public class ToggleActionPropertyChangeListener + implements PropertyChangeListener +{ + + public ToggleActionPropertyChangeListener(AbstractButton button) + { + this.button = button; + } + + public void propertyChange(PropertyChangeEvent evt) + { + String propertyName = evt.getPropertyName(); + if(propertyName.equals("selected")) + { + Boolean selected = (Boolean)evt.getNewValue(); + button.setSelected(selected.booleanValue()); + } + } + + private AbstractButton button; +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/ui/WizardDlg.java b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/WizardDlg.java new file mode 100644 index 00000000000..cd2a696b19a --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/WizardDlg.java @@ -0,0 +1,336 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.ui; + +import com.sun.java.swing.action.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Vector; +import javax.swing.*; + +// Referenced classes of package com.sun.java.swing.ui: +// CommonUI + +public class WizardDlg extends JDialog +{ + private class CancelListener + implements ActionListener + { + + public void actionPerformed(ActionEvent evt) + { + if(cancelListener != null) + cancelListener.actionPerformed(evt); + setVisible(false); + } + + private CancelListener() + { + } + + } + + private class FinishListener + implements ActionListener + { + + public void actionPerformed(ActionEvent evt) + { + if(finishListener != null) + finishListener.actionPerformed(evt); + setVisible(false); + } + + private FinishListener() + { + } + + } + + private class NextListener + implements ActionListener + { + + public void actionPerformed(ActionEvent evt) + { + cardShowing++; + if(cardShowing > numCards) + cardShowing = numCards; + else + panesLayout.next(panesPanel); + if(nextListener != null) + nextListener.actionPerformed(evt); + enableBackNextButtons(); + } + + private NextListener() + { + } + + } + + private class BackListener + implements ActionListener + { + + public void actionPerformed(ActionEvent evt) + { + cardShowing--; + if(cardShowing < 1) + cardShowing = 1; + else + panesLayout.previous(panesPanel); + if(backListener != null) + backListener.actionPerformed(evt); + enableBackNextButtons(); + } + + private BackListener() + { + } + + } + + + public WizardDlg(JFrame frame, String title, Vector panels, Vector images) + { + super(frame, title, true); + this.title = title; + this.images = images; + Container pane = getContentPane(); + pane.setLayout(new BorderLayout()); + panesLayout = new CardLayout(); + panesPanel = new JPanel(panesLayout); + pane.add(panesPanel, "Center"); + pane.add(createButtonPanel(), "South"); + setPanels(panels); + pack(); + CommonUI.centerComponent(this); + } + + public WizardDlg(JFrame frame, String title, Vector panels) + { + this(frame, title, panels, null); + } + + public WizardDlg(String title, Vector panels) + { + this(new JFrame(), title, panels, null); + } + + public void setPanels(Vector panels) + { + numCards = panels.size(); + cardShowing = 1; + this.panels = panels; + panesPanel.removeAll(); + for(int i = 0; i < numCards; i++) + panesPanel.add((JPanel)panels.elementAt(i), (new Integer(i)).toString()); + + validate(); + enableBackNextButtons(); + } + + public void reset() + { + cardShowing = 1; + panesLayout.first(panesPanel); + enableBackNextButtons(); + } + + public void setWestPanel(JPanel panel) + { + Container pane = getContentPane(); + pane.add(panel, "West"); + } + + public static void main(String args[]) + { + JPanel p1 = new JPanel(); + p1.add(new JButton("One")); + JPanel p2 = new JPanel(); + p2.add(new JButton("Two")); + JPanel p3 = new JPanel(); + p3.add(new JButton("Three")); + JPanel p4 = new JPanel(); + p4.add(new JButton("Four")); + Vector panels = new Vector(); + panels.addElement(p1); + panels.addElement(p2); + panels.addElement(p3); + panels.addElement(p4); + wizardDlg = new WizardDlg("Test Dialog", panels); + wizardDlg.addFinishListener(new ActionListener() { + + public void actionPerformed(ActionEvent evt) + { + System.exit(0); + } + + } +); + wizardDlg.addCancelListener(new ActionListener() { + + public void actionPerformed(ActionEvent evt) + { + System.exit(0); + } + + } +); + wizardDlg.setVisible(true); + } + + private JPanel createButtonPanel() + { + JPanel panel = new JPanel(); + backAction = new BackAction(); + nextAction = new NextAction(); + finishAction = new FinishAction(); + cancelAction = new CancelAction(); + backAction.setEnabled(false); + finishAction.setEnabled(false); + backAction.addActionListener(new BackListener()); + nextAction.addActionListener(new NextListener()); + finishAction.addActionListener(new FinishListener()); + cancelAction.addActionListener(new CancelListener()); + panel.add(CommonUI.createButton(backAction)); + panel.add(CommonUI.createButton(nextAction)); + panel.add(CommonUI.createButton(finishAction)); + panel.add(CommonUI.createButton(cancelAction)); + JPanel p2 = new JPanel(new BorderLayout()); + p2.add(panel, "Center"); + p2.add(new JSeparator(), "North"); + return p2; + } + + private void enableBackNextButtons() + { + if(cardShowing == 1) + { + backAction.setEnabled(false); + finishAction.setEnabled(false); + if(numCards > 1) + { + nextAction.setEnabled(true); + } else + { + finishAction.setEnabled(true); + nextAction.setEnabled(false); + } + } else + if(cardShowing == numCards) + { + nextAction.setEnabled(false); + finishAction.setEnabled(true); + if(numCards > 1) + backAction.setEnabled(true); + else + backAction.setEnabled(false); + } else + { + backAction.setEnabled(true); + nextAction.setEnabled(true); + finishAction.setEnabled(false); + } + setTitle(); + } + + private void setTitle() + { + JPanel panel = (JPanel)panels.elementAt(cardShowing - 1); + String newTitle = title; + String panelTitle = panel.getName(); + if(panelTitle != null && panelTitle.equals("")) + { + newTitle = newTitle + " - "; + newTitle = newTitle + panelTitle; + } + super.setTitle(newTitle); + } + + public synchronized void addFinishListener(ActionListener l) + { + finishListener = AWTEventMulticaster.add(finishListener, l); + } + + public synchronized void removeFinishListener(ActionListener l) + { + finishListener = AWTEventMulticaster.remove(finishListener, l); + } + + public synchronized void addCancelListener(ActionListener l) + { + cancelListener = AWTEventMulticaster.add(cancelListener, l); + } + + public synchronized void removeCancelListener(ActionListener l) + { + cancelListener = AWTEventMulticaster.remove(cancelListener, l); + } + + public synchronized void addNextListener(ActionListener l) + { + nextListener = AWTEventMulticaster.add(nextListener, l); + } + + public synchronized void removeNextListener(ActionListener l) + { + nextListener = AWTEventMulticaster.remove(nextListener, l); + } + + public synchronized void addBackListener(ActionListener l) + { + backListener = AWTEventMulticaster.add(backListener, l); + } + + public synchronized void removeBackListener(ActionListener l) + { + backListener = AWTEventMulticaster.remove(backListener, l); + } + + private CardLayout panesLayout; + private JPanel panesPanel; + private DelegateAction backAction; + private DelegateAction nextAction; + private DelegateAction finishAction; + private DelegateAction cancelAction; + private ActionListener finishListener; + private ActionListener cancelListener; + private ActionListener nextListener; + private ActionListener backListener; + private int numCards; + private int cardShowing; + private String title; + private Vector panels; + private Vector images; + private static WizardDlg wizardDlg; + + + + +} diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/development/Server16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/development/Server16.gif new file mode 100644 index 0000000000000000000000000000000000000000..4e76682efa30eade53022a97f7d632312352f665 GIT binary patch literal 636 zcmZ?wbhEHb6krfwxcZ;r|Ns974jj03^VY_7o6jA+c4E)fll!i2T)z9%{;OM7@7=b3 z?}d}sFP*t@@$~hp7jIrZe|^K+%~vnosH&{4tf;zq$hCLdh5cO>z6Ows3@#j0_Bn3_2i_Kz?FiOE}O_;GrWHd_v`th7aSs0QJkAPMm%sD=$V)^6^l7E11B< zs~~T9QL@v*jsNR}w{o3Nd>NWA?$G(b=qJY|&B@Z>Cn_o?CE39sAU#= z<;mc~7_eymf~Aa(4A%Q*-8;47`Sm?{iN5E~p6ToET)$@3l7;iPZ{70wK$yB)XkY(+dr*t>C*ZY^UA{`7A9#Y3(3<7A<;dB_N9;vAiAnlajN&6gB;3FM$GrKO@uw?aYQr<0!+@}0H zw9iRdbhf}JI_P0SBop>C(IANIGDaOfG^nN{kO~8{al>T50Ucu~s8$U_5CaUv%^NN& z<+f2SBI>o%(J(X`aE6Wn5L2s%A&kWZA>?p4$o~=V4=Vvd5)l3&{_qoo z{beLUGpZdMpU_C3PCb)Oj!BUhv$NRrC?=64-OIak?#%o`0@i-_Y$BU|DtB=KW96f5 zyj#gR`f2Po&yw9*UHf4Y%dO8jQgib}lXC*gsY$8zHJuEMW2YONeL`U!m_e>KwOnry zamAmtSj+K}hKp6jSwCJPB{#Ugvp7Y+@)BqECvDuK?AA08R^2!PII~FIs1}gM23xsSSh9AZ^)A*P3YM9-dFFz zO8Q8Hrl4w$W$At`M6QTe&6W#u1~RkE;;?*YaEYAbsGjd>(RZe=YV-Ej^n2EBcH18L z?&qQq;r*>E@9S47y6$%lpv3}#0F|oH#)rM=wXP0DpHih9kUvoJ(W>5#LbR->2NfR% hm8e**lq&}1vO-R3b!`P&DMp*+3bd$Dz)3}}`~zg}Z2JHJ literal 0 HcmV?d00001 diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/About16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/About16.gif new file mode 100644 index 0000000000000000000000000000000000000000..04da95eb831806d5586b246423126eb2b477eb7b GIT binary patch literal 644 zcmZ?wbhEHb6krfwc=n$G2>$>7fBxKqdw1V2U9x-Uj&r9@-aC2X?up}fu3Ubem^d*n zZ=QpL*NhqK=FZ)`W5>ni%l9o>wB6S?{P5x1>((9Fw(ZQ;t)~wjyuN?`)qVS}?A?2L z_wI|^w*v)F9X)#c@Zp>L_g~q!@A9Ti$BrJob>zs+g9oqf-+y`U-ixPCKR9&g+RdBq zE?<6rE_MX*RH*|aN*&( zbNA1jxqJHboqPA*-@W_p&Yia(KmOl;;M%d{cg|mUx^4T3PoF+bn>MYluaB3P_rQSz zAny%sp!k!8k%7UJK?meaP@FKZ_ceGnHMg|3dN6c!@VPU#b{aXDnQCjX2)Xq&F(_zr zTG?{xsVU2O%xv;-;!rhaVz$;-RN?h-o$V~ku4%z#XJeo)&oIkFKuU~Fm)p|L#6WOc zvxm5%C_k65rM=;$77r0g84VqCmwW9Z60Ay{+uK%(I39Wb;eqs#4=oJRJhOgz{s{cR zZr~u;#30Pa#loQY&)+$}pt2}4J)=ay$iTorA*oU!xHM0}H#4~?zqqovBsI5KN5L~M tSx><+Cr2R&q_9{aD784Xs4O)_kC)5K$4$XKNFgk>NWoCgfR~HG8UQ|A?xX+! literal 0 HcmV?d00001 diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/About24.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/About24.gif new file mode 100644 index 0000000000000000000000000000000000000000..9e1168954afff026f45a013c9311eacd0ef27424 GIT binary patch literal 797 zcmbV}>rYYv0L52?K;X(Fd}f(FTwiQ6(tn}f$Ftx0a!y)CYHVC_Fc1tZdx0&y zUN2&tH|RZX*N;hoQ81xbDIKCIWJ+ihP8zftw+3=SYNuK?YcYQ=E`C~B`Le#gtD|F( z!{PSyj0_A2`}@Z!lmb2<;_=kO!zwOUF*XK|j_UY)HIJtn8d3}l2&SiPVzEUeG7E*s z#Kgz(@hw3sm!mS7O(L;~#b%Mn#OJF_rWL(@QK_6&C{T%HD@0&;PN(x|wQiZrYBqm1 z7#8&Uc^LLUkVC1oD-<@l+-fo{A;_Z9xS-KER4Tj2^BYCK&CINr%}X%s)@q&0%Nr=V zYO{T@T2~Nc-e{aN7(9CYCm43=bk4OkuiO2@<@)Y)t~ngvQ1q+a{^i#%@8aS*e?%jZ zTF1sAxnf2KyX@%K_4RcWMPV3bv)N206OYGBrPA#k{|mwfW(NRN0L1O~_9uX^x4xpW zshQc*`sgtWC~sr8A1K?wYR^pV<~-jY40N`ZpH9OST`x$d^qs^82KAIO%MV51{PGHO z1N@T`&PI~o^)&Yqark|Od6)eI5|U2Dhy%+@ZZ`pGp?F;Uxs06{pR1RWqfZ?UGL?~6G-Pj1T}^4Y8B*VA~9H2RxJ~-5c?W1tkCEd;9htM zjNN@F9(zsR(A*NTRKNF1Oe*~1&9hhzR4tY631}b8pjaRbhujtkV}Q4%VZIZL)r0+a z!e1990e`rgtJ&na-WI>Y;|(Q0=LGBnSRa7!H#@nix{h9UyR-(3A(P4AjXLmRZ6!!4 zyGgHN)G=ykcNs)5qw*#ROsuE?soNq0q|z8P`hD6h5+0YCl?tX&!F(DWJVqkpaln~> D&2)*( literal 0 HcmV?d00001 diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Delete16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Delete16.gif new file mode 100644 index 0000000000000000000000000000000000000000..d9d1a338f4dea468baac6c6ad2a763b4af4d5b5e GIT binary patch literal 208 zcmZ?wbhEHb6krfwSoELa|NsAI&YYP!b7opvnz6Al0|Uc>0|$Vl;!hSv1_m|;9UvR1 zQh8J;WME*RkW{GQdq1IlvgYnPz5YGcz*)006+izyJUMA^8LW000I6 zEC2ui02lxm000APXu90~Fv?Zxj3wxD75QK&Mg*XpfuO2G35jqBkS3b4<@^Fd8Vmt~ zfY8$IdOe_!=%OKi!C_HSdMc&OqwmTzKC0Vjm&yw-r%p50>i{RkXzlx){g&rzvh5~_ ze`6wS4giFOhJ_u8iW3O{A^uN8Z*X~XX=iA3ATls8Fd$-iAX9a2AWdmwa&L2ab97~G zb1Wc9ZeuPWL2PUwQfX&sbaNn5Wpib6c4cHP4GKz3Mj%I0AXa5^ATcg54GI7|RwZ9~ literal 0 HcmV?d00001 diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Find16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Find16.gif new file mode 100644 index 0000000000000000000000000000000000000000..abafbe28cfa5b88476d5b4a5d7fbe5f557b42adc GIT binary patch literal 434 zcmZ?wbhEHb6krfwxcZ*~2>$>7f8fA@!h*u9mp?sv@c+u?PY)mbU%BGSwyh8M?|Zp_ z--|P+znwY#wXSYmUENwo$H?yP-QC^0CQUlv=a)8r{@Il)uf)ZbZrk=SJG-f&VM=fB z!h*uWPoF;Bym@oy&Yf%4tVu~pNls4o_4RddaM0A$l#!9)<>dugObwv;lZBCifr&u} zWEjX#3~V(HjRhV$V*U*d?hF>Xy=Me97@X?nxj1w_v6<=SxmaB0LeWNNTxX z7Fl!fKVS08;)zVvEZ?GrFnGT<&2S?8u<_&)+$}pt2}4J)=ay$iTorA*oU! zxHM0}H#4~?zqqovBsI5KN5L~MSx><+Cr2R&q_9{aD784Xs4O)_kC)5K$4$XKNFgk> NNWoCgfR~HG8UV&KiqHT6 literal 0 HcmV?d00001 diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Help16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Help16.gif new file mode 100644 index 0000000000000000000000000000000000000000..dc5c2d310def06e1a13b61de3724a682dd4002d2 GIT binary patch literal 661 zcmZ?wbhEHb6krfwc=n&+|Ns974jhQ>o>w5@AvTie#NxukG(y%^Ty8WFRx#EeChg&>sOy$J$vV@ae`4)OJsakT-mhJS%+s% z+c$N>_Wte-UG1yeYUkBd `MSuy|QylH!xM_13_`Zz&^i$v8lPGwaKTWv#XP#-NW6<(V35j*Vabfrzb} zGux|jTH93gu)VH?_C8i|5q_z|ZaTutnYc{N^`#Fhhzp5na%*tvTN@shTW-8=y>-b7 ziED`t23#A8L;@XCZY*lw#>6ngW22I*vjitA6NBPEf9L#y%A(Blj1mPS0|Ntvq)LV0 z(mVy<%;ci{;>zNZ)ZAhn1<$->Jq5>{9EBi|!eWJ>)Z)~lveXnkUM?>mHwE_~g|O5j M1w%apUM>b}0ORu61^@s6 literal 0 HcmV?d00001 diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Help24.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Help24.gif new file mode 100644 index 0000000000000000000000000000000000000000..a2848d880e71f5765a874f913863aafc62579871 GIT binary patch literal 1328 zcmd^;`A^yh0L8zkTUo2Awc?zy_3PEt##+2}OE#!?r=7ZH(M($psK=}}f<_{>phy+O zs6i3rs@gEMa||!M01@OX)(R-fT1Bx&bZtys(yU9CeW!oN-p?<2@AHzEl#&<|o9_vD z0)N2(48tmwO1A@PtqUs4oWiU$+tF+OA_hDTs4n9)7d=Cp!88W%5ILL+xXFBfqz%-s(v%b1@!AoEzv|bm-mC@ci)byzq$A#Hg5}m}q=-RAE%i{g`N6bZk*<6{o7I zt4g#a;?8qfqb&Lmy+P7I7LscPwbh(zBAX~)5{vXA;i8bg!0*xaaMj$-*-rKhyItPi zI@-z_VKomo(+BC)ek!GpQYWq>@koRYf)En&wS3+@k2}ZZC^;+{iz#I`J#V5(Xw*I` zrI$h$kV#w;N5Scu?P3fw$b7N|wwV7hn?9Nh9}LUK%lacd^cGU@sg*XR)~=m?JuSD$ zC)Ov%&EpEIV*1te$h;d{{HzZL@tgzJv+aMdH+tF#QT4)E-ZR<3fnmNnd zlwnF~Rw`B%GsYRy8P6VS(1`qS;i7I zb`yTR4OYQtnz|Di${7uaVa%Mzc)`VTsDLnY~l)K4&A@P&c8wfCkst6lEbE~ETt zd-e1*UVmG}7dNTrQ^i7Yva!k7i@J_1yBbErwh0hX#mG*M0_~i2IFWiNAQDTCy&A zt_8Wb#8(u*TMWP@XGf-u9=K{8GO7Mg84xDEp6(MAKgbSz)|lcEO#3t!8CVjD^m3r3 z4ixm4d0n|64Zv1v7^U$;`-Yv1Jr_G<&tw=VW0lcpF29pD<#W@!xkFZT_4+rxRDG$N z3D!i_<4hg0``+MTKSJl~1>BAnkvtF5J`Pg;d$~S-f9jp7;4#MY%VL|;dAvaF&h+uhOLA^V|2Z!3cFt}> zHfe7ZD9Ch1JGR}b$@Kp`7n2{CeI+>q;d(9^dlziT$q+l`0% zWakqvOUu4CvpG) literal 0 HcmV?d00001 diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/History16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/History16.gif new file mode 100644 index 0000000000000000000000000000000000000000..bc278f9ae9b15c27ba6bc9b0541b7836bae74fd5 GIT binary patch literal 677 zcmZ?wbhEHb6krfwc=n$G2>$>7f8fA@34PlaFFZGO^6rNERrPhtr%gT5*1CSy%;OXK zceS;ynK$>;)G7OWd$#s;Z=N=F|DuKGCQsV6VE(E3^G?p0ePrg00~04~+rI7TvZWX1 z%s#wg`Nd^R&(E8CbmNBG>(<^_wes?^rRSC`KD}t+$=S0GY}$Bx?V77wx7=H^`ttT| z_gAhsw|m#)O&f3Q+5LFk+Dkik+&^{lLwozy>guH}EgSm#_jY&hm^g8NN5`hAQxA1_ zZ*6biFk!;3o}R7q=bxE5^T>=Dhv&>WK6UE8<;$-uSa5pQtRssSot-!D#PsR=dwMob zo3?kwic8CuU0AZ@?5b5)_Uw7Ne*MkWtFIh8_GRCuwZcJ zO)%lJatFo%$%OY2Sjf$+DV%ppGyhzJo>tkk? z(C`dma$XkA)T4T9g@>@BA)`YVPv^x6CmkCZ7!?2cJLeZv7GqdHuWrnE=x-xun^SqiaJ!dG7)(a9jF`I*cf|Y zV;kGp^LNirY~MXF24fG54HymwOyof%;8ZyBDvm4bEP_9w_mA&;zkm6>KJQaGCy#z~ zF%^~y`*R((q4o83uh)yYqiP~T%$6>RC}^|HYSs50_StJ??KRcnI<&IBPKCu7Fn6_h zoDtVxK;M$KGQCYCYa_wLYW32nUF0S!iD>4w`8jM~3*AY;>m}l_P%uPkwn`=87P^B< zv67oiB%+bc>ZQ}{3VB2#4hh-=Z5%hF#i3M0q>_+CJR}kZHR^Gt;=V#Y0?O_Q1^uj6 zr$PTvrHm-#VTpJ^(B8-Ac{+?!M#DqB?txY_rcsZIMFGe>W9ry2Ck*-rdRzQDvpLrbb#{ zuR)`gwY4%dT5;=^{N_!NM6zQr`a5?tWU>Q`)nhQax;i{{7j~s!RVz@9TZAubF-b#AK-EWZEb!Q%S)qm zH8nv*qN$-lBN7b@g&~1ph|dp_$rh0)#ODXNTz_k;i^=R^FuKWPNFuq%=lAn?ej3eA zrP@I7zDzbEkqiq2K|bFvlZBALTn@)m zwR%jY8kKM0kPPbe6S@rw+NfGR>U2IcnWl}#NxlAoP8Zc`$2FQ!%f|ho8Ix%$7+ka2 z9_#hvgM)wg{l9uVD-OqeXXl*V{uqL$hKFBtb*MP{{KqvAo&aRku1cy)^FI&$txF{cje~p&YYs3dG~`?re8A0)jlALR@T4~MEnFs?^$He zjm2|N+VH}TqU@2hv}4zijrDBOm@MDF^^I8U@tF5hkB#iC4tySL0M75pT{}yGZ_T3r zR)LDm@W;OeCTz)mCt)&Ux0^Sgzp&?9CdwknARvD6H6p-|(Ifkq722`Mu`dB_8x2{xttGVMpQZR}mi;vD4=Y z&&-=+;Z7`SIPOS_G-iK3BVBp{b^)LF+G(sjoO+4pL%d!hOrI-Cv4hlYk(W5c_JWV+ z5nJL)k{@L*<`k26$rCF=Z||!qJ`vZ=Ky5FKNnVa{5>KNened9`Qf~2Gbc9#3J!Km# z{ok)oT(3Y^UHRe18sHELg#s?2fx;W*!09WOtFBk0t7}THRqq3G$}b-PJ}WB&3O0k) iKtXABX;p1$$$_N!FY`_UrwV}crB%Se1E{2USk`}OG^-Q< literal 0 HcmV?d00001 diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Information16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Information16.gif new file mode 100644 index 0000000000000000000000000000000000000000..5748e325f150438a323e2dfd3c64ebbb31370c8d GIT binary patch literal 661 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 W`M4>#2PuT57AY9&8Srv3SOWl92UWNL literal 0 HcmV?d00001 diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Open24.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Open24.gif new file mode 100644 index 0000000000000000000000000000000000000000..2086bc296307753867ddb03be7f1a1bfc94d43e3 GIT binary patch literal 462 zcmZ?wbhEHblwgoxxcZ;rKM*`W`~Mjbo%#3l^xr3^|2#hR`_ZXi4^RGhaN^s&`x}SeUO)Ky>VX$m_CL9>=h3;{56%kb3A>i`?^x8gV^Qz+ zMZMb=_H3HlwSIQzx>@aOX11-G-nwXF!-5I*^ZM%M_SVkqs!lUDW?*1AaNq!tL<5RH zSr{1@EE#k_;vhdcu+2Cyr@%u;s^4->(MlGJ`3y1(Iu-|pG5VP)WbM(}!n?LpXZF$y zCA)S_l)GB6qSDX)-n$>S1ErRQ21G|`izendTO>&v3#m6UD)SkNb+oxya7E4Jim&aQ zTDoB2qQy%VR#paw6f#6NC$Dt!*|fQKYE7q+pjw}@V8{At3`s%_GyD1UlS1cvGH7!t zHFD`C%sb<``KI@VrFT6X85IBdJLeZv7GwoPk7#DV0y9hrl_L@i#VrFyvHoHu9Y#Xr$ntic|`qh+poMi9i^@_{^mw_veB2b=gA~G2ixdp?40yR1tO0)kMS%bS literal 0 HcmV?d00001 diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Save24.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Save24.gif new file mode 100644 index 0000000000000000000000000000000000000000..bfa98a8df0a1b7634dccb78b9ba0c6bb7e26de5b GIT binary patch literal 266 zcmZ?wbhEHblwgoxSoELa|NsAI&YYP!b7opv8Uq8vfddDCBoHY6WMO1rU}ew&aX@Mv zm}??--MPoYBKT^@;xsLGt^Qq`1yu%Y5l2Lp?L&#cEP4m(zRzdkK;)Yvok@2+DPR>w95 zM+*nG)w6202Uay?bo=*qhE15*%saI$Wi~e_gW^Ab=lp`oqRjM+5(Ogz0|SMmN`>Ik zJO$s(f^Vuhg8;?$zD)D%5lE-xQ91@|C@u+$<2 LLp=jtE(U7=S*BxA literal 0 HcmV?d00001 diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/SaveAs16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/SaveAs16.gif new file mode 100644 index 0000000000000000000000000000000000000000..8d3929c8aa7d56483d4d3b218e840ca56506561a GIT binary patch literal 255 zcmZ?wbhEHb6krfw*!-UX2>$>7f8f9Y1A|0c+q_SoKAk^*{>+&(hYlUuzkh#TUS48i zA}=p5NF5j`{$ycfU|?d<0r5a)Ft9`hobY_j!t+{2i^Dr0#YeCvWTgVz1vU@Q+HS$* zqqCo-@t+o-kYp(HN^RA}wBQLB{8}7Kx`b4`+3&B=tf*sXclmKeaE^!a#tLh}iNblo zrdwU2w|v}`s^7`Lp!m<KEtq$a^`!1JL1WPbB z462%<1q6tK7)Z*@bz!`gXe=~?D%gOvDz6yMw$$-3I^axYDv2L^9yFf1*@Yp#YiTXMq^#6W=eNR3m0D_2s14nxzUR{uNasq{t2@aPD2b!D* z1&lB~zN0-qiQq@B2_5?!nZuDGVLA-1l+uL-(HkIRr~6L@!a zlNFKGj~Ce40ucZq{!c@1aCvfRXJ~XFGB7YOAYyqSQ*~}2O=)9tZ*zHbbY*RGEFej4 uV=f>;Y-}J>X=iA3b0AV>b7gXNWn?Z53Q9~yAV*RlR%LP^F)lC-3IID(yorVY literal 0 HcmV?d00001 diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Zoom16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Zoom16.gif new file mode 100644 index 0000000000000000000000000000000000000000..9e488969a627368b6d64dd45c677ed60a2e08bed GIT binary patch literal 303 zcmZ?wbhEHb6krfwIP#wX2>$>7Z(xvUYnwN5;>vmRw$GTcVd>JnJ9b<+bLQ#Mqj%4o zdGhe#vny9_e)#aYyJu0JE$`N@!cU(*@$&K>IB)=@A1_e+$->CMAi|&nQU$V;fi+S= zwJ#;o?|=&Hvl(VS#+*6UrhJQRno}NI9cj8?%qZd5`q07nu87qk#XucTwf>`<0(4nf zm^DqWE@Dw({$SdqwZ3MGCkvCtWQGZqcl8dP|EVXS-JopRqN2#4_|M-tzo4=xGd-h3 z!N|bCKq0A8A-FV8!8bFxD8IO}xFj{VSVzG#FIi8)F(*eM2&AxBAt<#twWusLMUR)u W%g0T@JxC!ewMfBG&w!VU!5RP^YG*b8 literal 0 HcmV?d00001 diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/ZoomIn16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/ZoomIn16.gif new file mode 100644 index 0000000000000000000000000000000000000000..2329426e4817c9edf7f8db004d72cc096d0888e0 GIT binary patch literal 304 zcmZ?wbhEHb6krfwIP#wX2>$>7Z(xvUYn#{7GN-F+(To`z=FQu-di9b0`>!88diUnd zPe+elc=+(yl`A(NKYli2=K4efhC|cqczJmb95?{dj~6KZWMO1r5Mj^(sRG%_z#6Wg z+Lsc^B%ClU^RdB!4P6eOeOOdjvj2)OxIR*d@ReD)B=LZ?AqUrigBxyqRp{(w+?YL$ zttr#gbTJFd0|tjCE%tj;N>hU5e3d3u#+ICa|5LD_KCM|*k-=J#LGhozbACZ(QD%BZ ziGq=Vfq_C&r9yCNo`P>?a#4P9WpPPrZn2JnXI`?Nf@4mOLJ&w{u|iO4acWUnYKk5& XmzR&5f_socSZa}ip`HOR7lSnb*>7nx literal 0 HcmV?d00001 diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/ZoomIn24.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/ZoomIn24.gif new file mode 100644 index 0000000000000000000000000000000000000000..dbd44778a3db23e9b0cd4754a3980c57eed59b91 GIT binary patch literal 484 zcmZ?wbhEHblwgoxxcZ;r|NsB*-+y}Z=JV@)OCLOVcK`m-B-76J->PL z+08Qtu3!In{rZQ?>!x0~@bbd>mnTm?K6&!d$&*(P9lCw!(78hgZyz{t=D_A<`zMy~ z-hE~Ft}DCex9-|~W%JC2b?c6=Zq8c1{NVEC2No>YxnTaznKL&{DT$gidG(}8YbH%v z-QB&UrDbkInr|8q7&90fr!g=v95`?QND>JYf3h$#Fc>oEfYgKhz>ES99jWdO zPK?KL4!QM+Kk%?UWTV5^!?jw3sj^N`N3N>`RXI4f_lx+N?}}+yc{NgA?Vz@l zfrxsJKzfD&M@p-KfC`TyTX89a{`BdU1`^!SwV?)l3e0-*mo4w~lwuX-@R@JGAFplD zBRFM&6l0^7L2It^jxf>W7J~y554r2N_t#C4s zQR92^)PPxX=~I`>A6*?86#w}<=ND8KWu|A8C>R+S7$_uFDg>A2Dfnh47v&dM7MG;v z7V9W@<|XSXIOgOi1c4M5D+Hw$rxul^rs(lKX8IF<1itjdaLs literal 0 HcmV?d00001 diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/navigation/Down16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/navigation/Down16.gif new file mode 100644 index 0000000000000000000000000000000000000000..39849181f1d0b1e96de5fa17ca2a5ee5c76f9b49 GIT binary patch literal 185 zcmZ?wbhEHb6krfwSoELa|NsAI&itP_^9%z6!+`?_fFuMc{$ycfU|?a;0dYZU8JM*_ zcHQ}BaLV)8=3JINChHp&3TFM_eZ(=#VcN9h*9$UbE^ce#`*bAuz=8=A7#I})`8($q zR2F5XXOt)y85kHSBvmQ|m*y$>W+oTq7grXSq~;duD0t>2>nS+qr`aa%B?Wloe`uq8<DzfNY?w0FbRXrGMpVq5roS zr|5NTTs3F4jOpB?DU&Y7E|}Ky^0?P~&&#X~ivRqb^9w4AGSf3k6pRcE3>1DzfNY?w1dwewrGMq=xBSUG zTi7}q?lDxSv??7fc($_khKAFNm8;&g?v2$so0GZNV#(?qRV(Lze4zm}<)6QEenDkX zW_m`6f{}rNfkINHLU3uGf^TMWQGRh{aY<@!v5tagUb3EoV@{4j5J+LMLQraPYEfBg aiXJbQmyer*dyqm{YLSAWo&hfxgEatqv_7o> literal 0 HcmV?d00001 diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignLeft16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignLeft16.gif new file mode 100644 index 0000000000000000000000000000000000000000..235e780fbca9ba3317319d92952aca81bf5f8776 GIT binary patch literal 165 zcmZ?wbhEHb6krfwnE0RJ|Ns9C3=9Vj8~~DvKUo+V7?>DzfNY?w0FbRbrGMq>hw?KR zw=l774&D~L#I`5gbe7752o1F*tZkRNubBk__5JgA&M&Ae%1qBFQ7|$vFi=RUR0uB3 zQ}E49F3K;iEG|jSE!I)+%uCi&aLmb32m&cARtQQhPAw`+P0{1!^73(0a1T-lOD$3` L)HC4aVz34Pxi~XS literal 0 HcmV?d00001 diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignLeft24.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignLeft24.gif new file mode 100644 index 0000000000000000000000000000000000000000..85631ca5b01512cb6e9593dc86661f5cc1452b25 GIT binary patch literal 178 zcmZ?wbhEHblwgoxnE0RJ|Ns9C3=9Vj8~~DvKUo+V7?>DzfNY?w1dweorGMq=xBSZ7 zTcV^I@5P*6AG7F0$udr_$FJt({aP#jq|88Lv-jV7es<+Cr2R&q_9{aD784Xs4O)_ ZkC)5K$4$XKNFgk>NWoCgfR~HG8UXaLJ#GL1 literal 0 HcmV?d00001 diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignRight16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignRight16.gif new file mode 100644 index 0000000000000000000000000000000000000000..9c06d30c4565704c1c537b07057bd2fc96f91d29 GIT binary patch literal 165 zcmZ?wbhEHb6krfwnE0RJ|Ns9C3=9Vj8~~DvKUo+V7?>DzfNY?w0FbRbrGMpVF@9&^ z1yK!)>R$a?l_T&uvd3cTObfNATQ{7wzPc>{sPCV@bACZ(QD%BZiGq=Vfq_C&r9yCN zo`P>?a#4P9WpPPrZn2JnXI`?Nf@4mOLJ&w{u|iO4acWUnYKk5&mzR&5f_socSZa}i Lp`HOR7lSnb#XU9| literal 0 HcmV?d00001 diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignRight24.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignRight24.gif new file mode 100644 index 0000000000000000000000000000000000000000..25a77d35a8162bba1042ffe4c05cdda1bd3f1030 GIT binary patch literal 178 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�R5 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

$6JqQf&GWaOIbj;5F9Z{`D&1 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

)JH|V@Tm@c35mvVX+?u=t-J~Xx+}0^ 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 From d35e1bbd889ed09c5910b61ba52537ebf9eac1a8 Mon Sep 17 00:00:00 2001 From: Chuck Rasbold Date: Tue, 29 Jul 2008 14:48:25 -0700 Subject: [PATCH 18/52] 6730192: expression stack wrong at deoptimization point Add safepoint before popping expression stack, not after Reviewed-by: kvn --- hotspot/src/share/vm/opto/parse2.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/hotspot/src/share/vm/opto/parse2.cpp b/hotspot/src/share/vm/opto/parse2.cpp index a71c7726a2b..cc1d6b3e430 100644 --- a/hotspot/src/share/vm/opto/parse2.cpp +++ b/hotspot/src/share/vm/opto/parse2.cpp @@ -925,9 +925,6 @@ void Parse::do_ifnull(BoolTest::mask btest, Node *c) { return; } - // If this is a backwards branch in the bytecodes, add Safepoint - maybe_add_safepoint(target_bci); - explicit_null_checks_inserted++; // Generate real control flow @@ -1009,9 +1006,6 @@ void Parse::do_if(BoolTest::mask btest, Node* c) { return; } - // If this is a backwards branch in the bytecodes, add Safepoint - maybe_add_safepoint(target_bci); - // Sanity check the probability value assert(0.0f < prob && prob < 1.0f,"Bad probability in Parser"); @@ -2100,6 +2094,8 @@ void Parse::do_one_bytecode() { case Bytecodes::_ifnull: btest = BoolTest::eq; goto handle_if_null; case Bytecodes::_ifnonnull: btest = BoolTest::ne; goto handle_if_null; handle_if_null: + // If this is a backwards branch in the bytecodes, add Safepoint + maybe_add_safepoint(iter().get_dest()); a = null(); b = pop(); c = _gvn.transform( new (C, 3) CmpPNode(b, a) ); @@ -2109,6 +2105,8 @@ void Parse::do_one_bytecode() { case Bytecodes::_if_acmpeq: btest = BoolTest::eq; goto handle_if_acmp; case Bytecodes::_if_acmpne: btest = BoolTest::ne; goto handle_if_acmp; handle_if_acmp: + // If this is a backwards branch in the bytecodes, add Safepoint + maybe_add_safepoint(iter().get_dest()); a = pop(); b = pop(); c = _gvn.transform( new (C, 3) CmpPNode(b, a) ); @@ -2122,6 +2120,8 @@ void Parse::do_one_bytecode() { case Bytecodes::_ifgt: btest = BoolTest::gt; goto handle_ifxx; case Bytecodes::_ifge: btest = BoolTest::ge; goto handle_ifxx; handle_ifxx: + // If this is a backwards branch in the bytecodes, add Safepoint + maybe_add_safepoint(iter().get_dest()); a = _gvn.intcon(0); b = pop(); c = _gvn.transform( new (C, 3) CmpINode(b, a) ); @@ -2135,6 +2135,8 @@ void Parse::do_one_bytecode() { case Bytecodes::_if_icmpgt: btest = BoolTest::gt; goto handle_if_icmp; case Bytecodes::_if_icmpge: btest = BoolTest::ge; goto handle_if_icmp; handle_if_icmp: + // If this is a backwards branch in the bytecodes, add Safepoint + maybe_add_safepoint(iter().get_dest()); a = pop(); b = pop(); c = _gvn.transform( new (C, 3) CmpINode( b, a ) ); From 74b3de5c3be2f159062972c46929f06b9119eff8 Mon Sep 17 00:00:00 2001 From: Jon Masamitsu Date: Wed, 30 Jul 2008 11:54:00 -0700 Subject: [PATCH 19/52] 6730514: assertion failure in mangling code when expanding by 0 bytes An expansion by 0 bytes was not anticipated when the assertion was composed. Reviewed-by: jjh, jcoomes, apetrusenko --- hotspot/make/windows/makefiles/defs.make | 2 +- .../concurrentMarkSweepGeneration.cpp | 27 ++------- .../concurrentMarkSweepGeneration.hpp | 10 ++-- .../parallelScavenge/psOldGen.cpp | 19 ++++++- .../shared/spaceDecorator.cpp | 3 +- .../share/vm/memory/compactingPermGenGen.cpp | 6 +- .../share/vm/memory/compactingPermGenGen.hpp | 2 +- hotspot/src/share/vm/memory/generation.cpp | 55 +++++++++++++------ hotspot/src/share/vm/memory/generation.hpp | 16 +++++- 9 files changed, 87 insertions(+), 53 deletions(-) diff --git a/hotspot/make/windows/makefiles/defs.make b/hotspot/make/windows/makefiles/defs.make index bfabddff58e..4b2fc14b3e2 100644 --- a/hotspot/make/windows/makefiles/defs.make +++ b/hotspot/make/windows/makefiles/defs.make @@ -107,7 +107,7 @@ ifeq ($(USING_CYGWIN), true) ABS_OUTPUTDIR := $(subst /,\\,$(shell /bin/cygpath -m -a "$(OUTPUTDIR)")) ABS_BOOTDIR := $(subst /,\\,$(shell /bin/cygpath -m -a "$(BOOTDIR)")) ABS_GAMMADIR := $(subst /,\\,$(shell /bin/cygpath -m -a "$(GAMMADIR)")) - ABS_OS_MAKEFILE := $(shell /bin/cygpath -m -a "$(HS_BUILD_DIR)/$(OSNAME)")/build.make + ABS_OS_MAKEFILE := $(shell /bin/cygpath -m -a "$(HS_MAKE_DIR)/$(OSNAME)")/build.make else ABS_OUTPUTDIR := $(subst /,\\,$(shell $(CD) $(OUTPUTDIR);$(PWD))) ABS_BOOTDIR := $(subst /,\\,$(shell $(CD) $(BOOTDIR);$(PWD))) diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp index 83854fe202c..3f70a3ac771 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -3195,31 +3195,16 @@ ConcurrentMarkSweepGeneration::expand_and_allocate(size_t word_size, // YSR: All of this generation expansion/shrinking stuff is an exact copy of // OneContigSpaceCardGeneration, which makes me wonder if we should move this // to CardGeneration and share it... +bool ConcurrentMarkSweepGeneration::expand(size_t bytes, size_t expand_bytes) { + return CardGeneration::expand(bytes, expand_bytes); +} + void ConcurrentMarkSweepGeneration::expand(size_t bytes, size_t expand_bytes, CMSExpansionCause::Cause cause) { - assert_locked_or_safepoint(Heap_lock); - size_t aligned_bytes = ReservedSpace::page_align_size_up(bytes); - size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes); - bool success = false; - if (aligned_expand_bytes > aligned_bytes) { - success = grow_by(aligned_expand_bytes); - } - if (!success) { - success = grow_by(aligned_bytes); - } - if (!success) { - size_t remaining_bytes = _virtual_space.uncommitted_size(); - if (remaining_bytes > 0) { - success = grow_by(remaining_bytes); - } - } - if (GC_locker::is_active()) { - if (PrintGC && Verbose) { - gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead"); - } - } + bool success = expand(bytes, expand_bytes); + // remember why we expanded; this information is used // by shouldConcurrentCollect() when making decisions on whether to start // a new CMS cycle. diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp index dd8956cfd0b..672bb8a8da7 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp @@ -1048,10 +1048,6 @@ class ConcurrentMarkSweepGeneration: public CardGeneration { double _initiating_occupancy; protected: - // Grow generation by specified size (returns false if unable to grow) - bool grow_by(size_t bytes); - // Grow generation to reserved size. - bool grow_to_reserved(); // Shrink generation by specified size (returns false if unable to shrink) virtual void shrink_by(size_t bytes); @@ -1103,6 +1099,11 @@ class ConcurrentMarkSweepGeneration: public CardGeneration { // Override virtual void ref_processor_init(); + // Grow generation by specified size (returns false if unable to grow) + bool grow_by(size_t bytes); + // Grow generation to reserved size. + bool grow_to_reserved(); + void clear_expansion_cause() { _expansion_cause = CMSExpansionCause::_no_expansion; } // Space enquiries @@ -1193,6 +1194,7 @@ class ConcurrentMarkSweepGeneration: public CardGeneration { // Allocation failure void expand(size_t bytes, size_t expand_bytes, CMSExpansionCause::Cause cause); + virtual bool expand(size_t bytes, size_t expand_bytes); void shrink(size_t bytes); HeapWord* expand_and_par_lab_allocate(CMSParGCThreadState* ps, size_t word_sz); bool expand_and_ensure_spooling_space(PromotionInfo* promo); diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp index 89515f945c6..71b80fb3087 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp @@ -215,10 +215,22 @@ HeapWord* PSOldGen::expand_and_cas_allocate(size_t word_size) { } void PSOldGen::expand(size_t bytes) { + if (bytes == 0) { + return; + } MutexLocker x(ExpandHeap_lock); const size_t alignment = virtual_space()->alignment(); size_t aligned_bytes = align_size_up(bytes, alignment); size_t aligned_expand_bytes = align_size_up(MinHeapDeltaBytes, alignment); + if (aligned_bytes == 0){ + // The alignment caused the number of bytes to wrap. An expand_by(0) will + // return true with the implication that and expansion was done when it + // was not. A call to expand implies a best effort to expand by "bytes" + // but not a guarantee. Align down to give a best effort. This is likely + // the most that the generation can expand since it has some capacity to + // start with. + aligned_bytes = align_size_down(bytes, alignment); + } bool success = false; if (aligned_expand_bytes > aligned_bytes) { @@ -231,8 +243,8 @@ void PSOldGen::expand(size_t bytes) { success = expand_to_reserved(); } - if (GC_locker::is_active()) { - if (PrintGC && Verbose) { + if (PrintGC && Verbose) { + if (success && GC_locker::is_active()) { gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead"); } } @@ -241,6 +253,9 @@ void PSOldGen::expand(size_t bytes) { bool PSOldGen::expand_by(size_t bytes) { assert_lock_strong(ExpandHeap_lock); assert_locked_or_safepoint(Heap_lock); + if (bytes == 0) { + return true; // That's what virtual_space()->expand_by(0) would return + } bool result = virtual_space()->expand_by(bytes); if (result) { if (ZapUnusedHeapArea) { diff --git a/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.cpp b/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.cpp index 2d9fc59f675..ccd11c4b6e1 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.cpp @@ -39,7 +39,8 @@ bool SpaceMangler::is_mangled(HeapWord* q) { void SpaceMangler::set_top_for_allocations(HeapWord* v) { if (v < end()) { - assert(is_mangled(v), "The high water mark is not mangled"); + assert(!CheckZapUnusedHeapArea || is_mangled(v), + "The high water mark is not mangled"); } _top_for_allocations = v; } diff --git a/hotspot/src/share/vm/memory/compactingPermGenGen.cpp b/hotspot/src/share/vm/memory/compactingPermGenGen.cpp index 2ba5222cde1..af94649ed89 100644 --- a/hotspot/src/share/vm/memory/compactingPermGenGen.cpp +++ b/hotspot/src/share/vm/memory/compactingPermGenGen.cpp @@ -432,14 +432,16 @@ bool CompactingPermGenGen::grow_by(size_t bytes) { } -void CompactingPermGenGen::grow_to_reserved() { +bool CompactingPermGenGen::grow_to_reserved() { // Don't allow _virtual_size to expand into shared spaces. + bool success = false; if (_virtual_space.uncommitted_size() > _shared_space_size) { size_t remaining_bytes = _virtual_space.uncommitted_size() - _shared_space_size; - bool success = OneContigSpaceCardGeneration::grow_by(remaining_bytes); + success = OneContigSpaceCardGeneration::grow_by(remaining_bytes); DEBUG_ONLY(if (!success) warning("grow to reserved failed");) } + return success; } diff --git a/hotspot/src/share/vm/memory/compactingPermGenGen.hpp b/hotspot/src/share/vm/memory/compactingPermGenGen.hpp index ea0bb185dab..4d76e473bde 100644 --- a/hotspot/src/share/vm/memory/compactingPermGenGen.hpp +++ b/hotspot/src/share/vm/memory/compactingPermGenGen.hpp @@ -184,7 +184,7 @@ public: void post_compact(); size_t contiguous_available() const; bool grow_by(size_t bytes); - void grow_to_reserved(); + virtual bool grow_to_reserved(); void clear_remembered_set(); void invalidate_remembered_set(); diff --git a/hotspot/src/share/vm/memory/generation.cpp b/hotspot/src/share/vm/memory/generation.cpp index 95ad500c871..5167db243b6 100644 --- a/hotspot/src/share/vm/memory/generation.cpp +++ b/hotspot/src/share/vm/memory/generation.cpp @@ -379,6 +379,41 @@ CardGeneration::CardGeneration(ReservedSpace rs, size_t initial_byte_size, } } +bool CardGeneration::expand(size_t bytes, size_t expand_bytes) { + assert_locked_or_safepoint(Heap_lock); + if (bytes == 0) { + return true; // That's what grow_by(0) would return + } + size_t aligned_bytes = ReservedSpace::page_align_size_up(bytes); + if (aligned_bytes == 0){ + // The alignment caused the number of bytes to wrap. An expand_by(0) will + // return true with the implication that an expansion was done when it + // was not. A call to expand implies a best effort to expand by "bytes" + // but not a guarantee. Align down to give a best effort. This is likely + // the most that the generation can expand since it has some capacity to + // start with. + aligned_bytes = ReservedSpace::page_align_size_down(bytes); + } + size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes); + bool success = false; + if (aligned_expand_bytes > aligned_bytes) { + success = grow_by(aligned_expand_bytes); + } + if (!success) { + success = grow_by(aligned_bytes); + } + if (!success) { + success = grow_to_reserved(); + } + if (PrintGC && Verbose) { + if (success && GC_locker::is_active()) { + gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead"); + } + } + + return success; +} + // No young generation references, clear this generation's cards. void CardGeneration::clear_remembered_set() { @@ -441,25 +476,9 @@ OneContigSpaceCardGeneration::expand_and_allocate(size_t word_size, } } -void OneContigSpaceCardGeneration::expand(size_t bytes, size_t expand_bytes) { +bool OneContigSpaceCardGeneration::expand(size_t bytes, size_t expand_bytes) { GCMutexLocker x(ExpandHeap_lock); - size_t aligned_bytes = ReservedSpace::page_align_size_up(bytes); - size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes); - bool success = false; - if (aligned_expand_bytes > aligned_bytes) { - success = grow_by(aligned_expand_bytes); - } - if (!success) { - success = grow_by(aligned_bytes); - } - if (!success) { - grow_to_reserved(); - } - if (GC_locker::is_active()) { - if (PrintGC && Verbose) { - gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead"); - } - } + return CardGeneration::expand(bytes, expand_bytes); } diff --git a/hotspot/src/share/vm/memory/generation.hpp b/hotspot/src/share/vm/memory/generation.hpp index 2847f7f6456..0f0e74e4794 100644 --- a/hotspot/src/share/vm/memory/generation.hpp +++ b/hotspot/src/share/vm/memory/generation.hpp @@ -606,11 +606,21 @@ class CardGeneration: public Generation { public: + // Attempt to expand the generation by "bytes". Expand by at a + // minimum "expand_bytes". Return true if some amount (not + // necessarily the full "bytes") was done. + virtual bool expand(size_t bytes, size_t expand_bytes); + virtual void clear_remembered_set(); virtual void invalidate_remembered_set(); virtual void prepare_for_verify(); + + // Grow generation with specified size (returns false if unable to grow) + virtual bool grow_by(size_t bytes) = 0; + // Grow generation to reserved size. + virtual bool grow_to_reserved() = 0; }; // OneContigSpaceCardGeneration models a heap of old objects contained in a single @@ -631,14 +641,14 @@ class OneContigSpaceCardGeneration: public CardGeneration { // and after last GC. // Grow generation with specified size (returns false if unable to grow) - bool grow_by(size_t bytes); + virtual bool grow_by(size_t bytes); // Grow generation to reserved size. - bool grow_to_reserved(); + virtual bool grow_to_reserved(); // Shrink generation with specified size (returns false if unable to shrink) void shrink_by(size_t bytes); // Allocation failure - void expand(size_t bytes, size_t expand_bytes); + virtual bool expand(size_t bytes, size_t expand_bytes); void shrink(size_t bytes); // Accessing spaces From 5e94e3bf69959f8ab25a3b92fc890474ab8c8f92 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Thu, 31 Jul 2008 15:47:42 -0700 Subject: [PATCH 20/52] 6732312: Switch off executing Escape Analysis by default Switch off executing Escape Analysis by default for now Reviewed-by: rasbold --- hotspot/src/share/vm/opto/c2_globals.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp index 0f09eaf837c..affd56a86e2 100644 --- a/hotspot/src/share/vm/opto/c2_globals.hpp +++ b/hotspot/src/share/vm/opto/c2_globals.hpp @@ -373,7 +373,7 @@ product(intx, AutoBoxCacheMax, 128, \ "Sets max value cached by the java.lang.Integer autobox cache") \ \ - product(bool, DoEscapeAnalysis, true, \ + product(bool, DoEscapeAnalysis, false, \ "Perform escape analysis") \ \ notproduct(bool, PrintEscapeAnalysis, false, \ From bea7a516fb6fed204d8b14b140ead2d60f312180 Mon Sep 17 00:00:00 2001 From: Hiroshi Yamauchi Date: Thu, 31 Jul 2008 18:50:37 -0700 Subject: [PATCH 21/52] 6731726: jmap -permstat reports only 50-60% of permgen memory usage Reviewed-by: swamyv, martin --- .../sun/jvm/hotspot/tools/PermStat.java | 64 ++++++++++--------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PermStat.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PermStat.java index 1808babf2cc..d2346a3186c 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PermStat.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PermStat.java @@ -266,46 +266,52 @@ public class PermStat extends Tool { out.println(); } + private static long objectSize(Oop oop) { + return oop == null ? 0L : oop.getObjectSize(); + } + + // Don't count the shared empty arrays + private static long arraySize(Array arr) { + return arr.getLength() != 0L ? arr.getObjectSize() : 0L; + } + private long computeSize(InstanceKlass k) { long size = 0L; - // InstanceKlass object size + // the InstanceKlass object itself size += k.getObjectSize(); - // add ConstantPool size - size += k.getConstants().getObjectSize(); + // Constant pool + ConstantPool cp = k.getConstants(); + size += cp.getObjectSize(); + size += objectSize(cp.getCache()); + size += objectSize(cp.getTags()); - // add ConstantPoolCache, if any - ConstantPoolCache cpCache = k.getConstants().getCache(); - if (cpCache != null) { - size += cpCache.getObjectSize(); - } + // Interfaces + size += arraySize(k.getLocalInterfaces()); + size += arraySize(k.getTransitiveInterfaces()); - // add interfaces size - ObjArray interfaces = k.getLocalInterfaces(); - size += (interfaces.getLength() != 0L)? interfaces.getObjectSize() : 0L; - ObjArray transitiveInterfaces = k.getTransitiveInterfaces(); - size += (transitiveInterfaces.getLength() != 0L)? transitiveInterfaces.getObjectSize() : 0L; + // Inner classes + size += objectSize(k.getInnerClasses()); - // add inner classes size - TypeArray innerClasses = k.getInnerClasses(); - size += innerClasses.getObjectSize(); + // Fields + size += objectSize(k.getFields()); - // add fields size - size += k.getFields().getObjectSize(); - - // add methods size + // Methods ObjArray methods = k.getMethods(); - size += (methods.getLength() != 0L)? methods.getObjectSize() : 0L; - TypeArray methodOrdering = k.getMethodOrdering(); - size += (methodOrdering.getLength() != 0L)? methodOrdering.getObjectSize() : 0; - - // add each method's size - int numMethods = (int) methods.getLength(); - for (int i = 0; i < numMethods; i++) { - Method m = (Method) methods.getObjAt(i); - size += m.getObjectSize(); + int nmethods = (int) methods.getLength(); + if (nmethods != 0L) { + size += methods.getObjectSize(); + for (int i = 0; i < nmethods; ++i) { + Method m = (Method) methods.getObjAt(i); + size += m.getObjectSize(); + size += objectSize(m.getConstMethod()); + } } + // MethodOrdering - an int array that records the original + // ordering of methods in the class file + size += arraySize(k.getMethodOrdering()); + return size; } } From 3da24841be56bdf693567d487310833d836e1684 Mon Sep 17 00:00:00 2001 From: Xiaobin Lu Date: Fri, 1 Aug 2008 15:12:34 -0700 Subject: [PATCH 22/52] 6719981: Update Hotspot Windows os_win32 for windows XP 64 bit and windows 2008 Reviewed-by: dholmes, kamg --- hotspot/src/os/windows/vm/os_windows.cpp | 102 +++++++++++++++-------- 1 file changed, 68 insertions(+), 34 deletions(-) diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index c77f50b77f5..60e99f67f9d 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -1447,44 +1447,78 @@ void os::print_dll_info(outputStream *st) { enumerate_modules(pid, _print_module, (void *)st); } +// function pointer to Windows API "GetNativeSystemInfo". +typedef void (WINAPI *GetNativeSystemInfo_func_type)(LPSYSTEM_INFO); +static GetNativeSystemInfo_func_type _GetNativeSystemInfo; + void os::print_os_info(outputStream* st) { - st->print("OS:"); + st->print("OS:"); - OSVERSIONINFOEX osvi; - ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + OSVERSIONINFOEX osvi; + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - if (!GetVersionEx((OSVERSIONINFO *)&osvi)) { - st->print_cr("N/A"); - return; - } + if (!GetVersionEx((OSVERSIONINFO *)&osvi)) { + st->print_cr("N/A"); + return; + } - int os_vers = osvi.dwMajorVersion * 1000 + osvi.dwMinorVersion; - - if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) { - switch (os_vers) { - case 3051: st->print(" Windows NT 3.51"); break; - case 4000: st->print(" Windows NT 4.0"); break; - case 5000: st->print(" Windows 2000"); break; - case 5001: st->print(" Windows XP"); break; - case 5002: st->print(" Windows Server 2003 family"); break; - case 6000: st->print(" Windows Vista"); break; - default: // future windows, print out its major and minor versions - st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion); - } - } else { - switch (os_vers) { - case 4000: st->print(" Windows 95"); break; - case 4010: st->print(" Windows 98"); break; - case 4090: st->print(" Windows Me"); break; - default: // future windows, print out its major and minor versions - st->print(" Windows %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion); - } - } - - st->print(" Build %d", osvi.dwBuildNumber); - st->print(" %s", osvi.szCSDVersion); // service pack - st->cr(); + int os_vers = osvi.dwMajorVersion * 1000 + osvi.dwMinorVersion; + if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) { + switch (os_vers) { + case 3051: st->print(" Windows NT 3.51"); break; + case 4000: st->print(" Windows NT 4.0"); break; + case 5000: st->print(" Windows 2000"); break; + case 5001: st->print(" Windows XP"); break; + case 5002: + case 6000: { + // Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could + // find out whether we are running on 64 bit processor or not. + SYSTEM_INFO si; + ZeroMemory(&si, sizeof(SYSTEM_INFO)); + // Check to see if _GetNativeSystemInfo has been initialized. + if (_GetNativeSystemInfo == NULL) { + HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32.dll")); + _GetNativeSystemInfo = + CAST_TO_FN_PTR(GetNativeSystemInfo_func_type, + GetProcAddress(hKernel32, + "GetNativeSystemInfo")); + if (_GetNativeSystemInfo == NULL) + GetSystemInfo(&si); + } else { + _GetNativeSystemInfo(&si); + } + if (os_vers == 5002) { + if (osvi.wProductType == VER_NT_WORKSTATION && + si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) + st->print(" Windows XP x64 Edition"); + else + st->print(" Windows Server 2003 family"); + } else { // os_vers == 6000 + if (osvi.wProductType == VER_NT_WORKSTATION) + st->print(" Windows Vista"); + else + st->print(" Windows Server 2008"); + if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) + st->print(" , 64 bit"); + } + break; + } + default: // future windows, print out its major and minor versions + st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion); + } + } else { + switch (os_vers) { + case 4000: st->print(" Windows 95"); break; + case 4010: st->print(" Windows 98"); break; + case 4090: st->print(" Windows Me"); break; + default: // future windows, print out its major and minor versions + st->print(" Windows %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion); + } + } + st->print(" Build %d", osvi.dwBuildNumber); + st->print(" %s", osvi.szCSDVersion); // service pack + st->cr(); } void os::print_memory_info(outputStream* st) { From 12198cdafdeebb8f99946268d8ce9a4b1d0fb8a8 Mon Sep 17 00:00:00 2001 From: Xiaobin Lu Date: Fri, 1 Aug 2008 15:18:14 -0700 Subject: [PATCH 23/52] 6618886: Anonymous objects can be destructed immediately and so should not be used Reviewed-by: dholmes, kamg --- hotspot/src/os/solaris/vm/osThread_solaris.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/hotspot/src/os/solaris/vm/osThread_solaris.cpp b/hotspot/src/os/solaris/vm/osThread_solaris.cpp index 702e6d4e2d5..ea8b6fb97c1 100644 --- a/hotspot/src/os/solaris/vm/osThread_solaris.cpp +++ b/hotspot/src/os/solaris/vm/osThread_solaris.cpp @@ -69,15 +69,15 @@ void OSThread::pd_destroy() { static intptr_t compare_and_exchange_current_callback ( intptr_t callback, intptr_t *addr, intptr_t compare_value, Mutex *sync) { if (VM_Version::supports_compare_and_exchange()) { - return Atomic::cmpxchg_ptr(callback, addr, compare_value); + return Atomic::cmpxchg_ptr(callback, addr, compare_value); } else { - MutexLockerEx(sync, Mutex::_no_safepoint_check_flag); - if (*addr == compare_value) { - *addr = callback; - return compare_value; - } else { - return callback; - } + MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag); + if (*addr == compare_value) { + *addr = callback; + return compare_value; + } else { + return callback; + } } } @@ -86,7 +86,7 @@ static intptr_t exchange_current_callback(intptr_t callback, intptr_t *addr, Mut if (VM_Version::supports_compare_and_exchange()) { return Atomic::xchg_ptr(callback, addr); } else { - MutexLockerEx(sync, Mutex::_no_safepoint_check_flag); + MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag); intptr_t cb = *addr; *addr = callback; return cb; From 7c754d92684bb72e301cf3b28b414409d088b482 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Fri, 1 Aug 2008 15:23:18 -0700 Subject: [PATCH 24/52] 6627362: javac generates code that uses array.clone, which is not available on JavaCard 6627364: javac needs Float and Double on the bootclasspath even when not directly used 6627366: javac needs Cloneable and Serializable on the classpath even when not directly used Reviewed-by: darcy --- .../com/sun/tools/javac/code/Symtab.java | 60 +++++++- .../com/sun/tools/javac/comp/Lower.java | 73 +++++++++- langtools/test/tools/javac/5045412/Bar.java | 37 ++++- langtools/test/tools/javac/5045412/Foo.java | 6 +- langtools/test/tools/javac/5045412/out | 2 - .../test/tools/javac/6627362/T6627362.java | 133 ++++++++++++++++++ langtools/test/tools/javac/6627362/x/E.java | 26 ++++ .../test/tools/javac/6627362/x/Object.java | 30 ++++ .../test/tools/javac/synthesize/Boolean.java | 41 ++++++ .../test/tools/javac/synthesize/Byte.java | 41 ++++++ .../tools/javac/synthesize/Character.java | 41 ++++++ .../tools/javac/synthesize/Cloneable.java | 27 ++++ .../test/tools/javac/synthesize/Double.java | 18 +++ .../test/tools/javac/synthesize/Float.java | 18 +++ .../test/tools/javac/synthesize/Integer.java | 41 ++++++ .../test/tools/javac/synthesize/Long.java | 41 ++++++ .../test/tools/javac/synthesize/Main.java | 122 ++++++++++++++++ .../test/tools/javac/synthesize/Number.java | 29 ++++ .../test/tools/javac/synthesize/Object.java | 28 ++++ .../tools/javac/synthesize/Serializable.java | 27 ++++ .../test/tools/javac/synthesize/Short.java | 41 ++++++ .../test/tools/javac/synthesize/Test.java | 32 +++++ .../test/tools/javac/synthesize/Void.java | 29 ++++ 23 files changed, 923 insertions(+), 20 deletions(-) delete mode 100644 langtools/test/tools/javac/5045412/out create mode 100644 langtools/test/tools/javac/6627362/T6627362.java create mode 100644 langtools/test/tools/javac/6627362/x/E.java create mode 100644 langtools/test/tools/javac/6627362/x/Object.java create mode 100644 langtools/test/tools/javac/synthesize/Boolean.java create mode 100644 langtools/test/tools/javac/synthesize/Byte.java create mode 100644 langtools/test/tools/javac/synthesize/Character.java create mode 100644 langtools/test/tools/javac/synthesize/Cloneable.java create mode 100644 langtools/test/tools/javac/synthesize/Double.java create mode 100644 langtools/test/tools/javac/synthesize/Float.java create mode 100644 langtools/test/tools/javac/synthesize/Integer.java create mode 100644 langtools/test/tools/javac/synthesize/Long.java create mode 100644 langtools/test/tools/javac/synthesize/Main.java create mode 100644 langtools/test/tools/javac/synthesize/Number.java create mode 100644 langtools/test/tools/javac/synthesize/Object.java create mode 100644 langtools/test/tools/javac/synthesize/Serializable.java create mode 100644 langtools/test/tools/javac/synthesize/Short.java create mode 100644 langtools/test/tools/javac/synthesize/Test.java create mode 100644 langtools/test/tools/javac/synthesize/Void.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java index eb632a69115..9b83ec19e51 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java @@ -75,6 +75,7 @@ public class Symtab { private final Name.Table names; private final ClassReader reader; + private final Target target; /** A symbol for the root package. */ @@ -144,6 +145,7 @@ public class Symtab { public final Type suppressWarningsType; public final Type inheritedType; public final Type proprietaryType; + public final Type systemType; /** The symbol representing the length field of an array. */ @@ -272,6 +274,55 @@ public class Symtab { return reader.enterClass(names.fromString(s)).type; } + public void synthesizeEmptyInterfaceIfMissing(final Type type) { + final Completer completer = type.tsym.completer; + if (completer != null) { + type.tsym.completer = new Completer() { + public void complete(Symbol sym) throws CompletionFailure { + try { + completer.complete(sym); + } catch (CompletionFailure e) { + sym.flags_field |= (PUBLIC | INTERFACE); + ((ClassType) sym.type).supertype_field = objectType; + } + } + }; + } + } + + public void synthesizeBoxTypeIfMissing(final Type type) { + ClassSymbol sym = reader.enterClass(boxedName[type.tag]); + final Completer completer = sym.completer; + if (completer != null) { + sym.completer = new Completer() { + public void complete(Symbol sym) throws CompletionFailure { + try { + completer.complete(sym); + } catch (CompletionFailure e) { + sym.flags_field |= PUBLIC; + ((ClassType) sym.type).supertype_field = objectType; + Name n = target.boxWithConstructors() ? names.init : names.valueOf; + MethodSymbol boxMethod = + new MethodSymbol(PUBLIC | STATIC, + n, + new MethodType(List.of(type), sym.type, + List.nil(), methodClass), + sym); + sym.members().enter(boxMethod); + MethodSymbol unboxMethod = + new MethodSymbol(PUBLIC, + type.tsym.name.append(names.Value), // x.intValue() + new MethodType(List.nil(), type, + List.nil(), methodClass), + sym); + sym.members().enter(unboxMethod); + } + } + }; + } + + } + /** Constructor; enters all predefined identifiers and operators * into symbol table. */ @@ -279,6 +330,7 @@ public class Symtab { context.put(symtabKey, this); names = Name.Table.instance(context); + target = Target.instance(context); // Create the unknown type unknownType = new Type(TypeTags.UNKNOWN, null); @@ -373,7 +425,7 @@ public class Symtab { collectionsType = enterClass("java.util.Collections"); comparableType = enterClass("java.lang.Comparable"); arraysType = enterClass("java.util.Arrays"); - iterableType = Target.instance(context).hasIterable() + iterableType = target.hasIterable() ? enterClass("java.lang.Iterable") : enterClass("java.util.Collection"); iteratorType = enterClass("java.util.Iterator"); @@ -383,6 +435,12 @@ public class Symtab { deprecatedType = enterClass("java.lang.Deprecated"); suppressWarningsType = enterClass("java.lang.SuppressWarnings"); inheritedType = enterClass("java.lang.annotation.Inherited"); + systemType = enterClass("java.lang.System"); + + synthesizeEmptyInterfaceIfMissing(cloneableType); + synthesizeEmptyInterfaceIfMissing(serializableType); + synthesizeBoxTypeIfMissing(doubleType); + synthesizeBoxTypeIfMissing(floatType); // Enter a synthetic class that is used to mark Sun // proprietary classes in ct.sym. This class does not have a diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java index 24318c5b13b..f7ec6827c6d 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java @@ -2110,16 +2110,64 @@ public class Lower extends TreeTranslator { Symbol valuesSym = lookupMethod(tree.pos(), names.values, tree.type, List.nil()); - JCTypeCast valuesResult = - make.TypeCast(valuesSym.type.getReturnType(), - make.App(make.Select(make.Ident(valuesVar), - syms.arrayCloneMethod))); + List valuesBody; + if (useClone()) { + // return (T[]) $VALUES.clone(); + JCTypeCast valuesResult = + make.TypeCast(valuesSym.type.getReturnType(), + make.App(make.Select(make.Ident(valuesVar), + syms.arrayCloneMethod))); + valuesBody = List.of(make.Return(valuesResult)); + } else { + // template: T[] $result = new T[$values.length]; + Name resultName = names.fromString(target.syntheticNameChar() + "result"); + while (tree.sym.members().lookup(resultName).scope != null) // avoid name clash + resultName = names.fromString(resultName + "" + target.syntheticNameChar()); + VarSymbol resultVar = new VarSymbol(FINAL|SYNTHETIC, + resultName, + arrayType, + valuesSym); + JCNewArray resultArray = make.NewArray(make.Type(types.erasure(tree.type)), + List.of(make.Select(make.Ident(valuesVar), syms.lengthVar)), + null); + resultArray.type = arrayType; + JCVariableDecl decl = make.VarDef(resultVar, resultArray); + + // template: System.arraycopy($VALUES, 0, $result, 0, $VALUES.length); + if (systemArraycopyMethod == null) { + systemArraycopyMethod = + new MethodSymbol(PUBLIC | STATIC, + names.fromString("arraycopy"), + new MethodType(List.of(syms.objectType, + syms.intType, + syms.objectType, + syms.intType, + syms.intType), + syms.voidType, + List.nil(), + syms.methodClass), + syms.systemType.tsym); + } + JCStatement copy = + make.Exec(make.App(make.Select(make.Ident(syms.systemType.tsym), + systemArraycopyMethod), + List.of(make.Ident(valuesVar), make.Literal(0), + make.Ident(resultVar), make.Literal(0), + make.Select(make.Ident(valuesVar), syms.lengthVar)))); + + // template: return $result; + JCStatement ret = make.Return(make.Ident(resultVar)); + valuesBody = List.of(decl, copy, ret); + } + JCMethodDecl valuesDef = - make.MethodDef((MethodSymbol)valuesSym, - make.Block(0, List.nil() - .prepend(make.Return(valuesResult)))); + make.MethodDef((MethodSymbol)valuesSym, make.Block(0, valuesBody)); + enumDefs.append(valuesDef); + if (debugLower) + System.err.println(tree.sym + ".valuesDef = " + valuesDef); + /** The template for the following code is: * * public static E valueOf(String name) { @@ -2155,6 +2203,17 @@ public class Lower extends TreeTranslator { addEnumCompatibleMembers(tree); } } + // where + private MethodSymbol systemArraycopyMethod; + private boolean useClone() { + try { + Scope.Entry e = syms.objectType.tsym.members().lookup(names.clone); + return (e.sym != null); + } + catch (CompletionFailure e) { + return false; + } + } /** Translate an enumeration constant and its initializer. */ private void visitEnumConstantDef(JCVariableDecl var, int ordinal) { diff --git a/langtools/test/tools/javac/5045412/Bar.java b/langtools/test/tools/javac/5045412/Bar.java index 80744329f72..6976dcd086d 100644 --- a/langtools/test/tools/javac/5045412/Bar.java +++ b/langtools/test/tools/javac/5045412/Bar.java @@ -1,13 +1,36 @@ -/** - * @test /nodynamiccopyright/ - * @bug 5045412 - * @compile/fail/ref=out -XDstdout -XDrawDiagnostics -Xlint:serial -XDfailcomplete=java.io.Serializable Bar.java +/* + * Copyright 2005-2006 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. */ /** - * @test /nodynamiccopyright/ - * @bug 5045412 - * @compile/fail/ref=out -XDstdout -XDrawDiagnostics -Xlint:serial -XDfailcomplete=java.io.Serializable Bar.java Foo.java + * @test + * @bug 5045412 6627366 + * @compile -Xlint:serial -XDfailcomplete=java.io.Serializable Bar.java + */ + +/** + * @test + * @bug 5045412 6627366 + * @compile -Xlint:serial -XDfailcomplete=java.io.Serializable Bar.java Foo.java */ class Bar implements java.io.Serializable { } diff --git a/langtools/test/tools/javac/5045412/Foo.java b/langtools/test/tools/javac/5045412/Foo.java index 515cd65a205..34fc285bda1 100644 --- a/langtools/test/tools/javac/5045412/Foo.java +++ b/langtools/test/tools/javac/5045412/Foo.java @@ -23,14 +23,14 @@ /** * @test - * @bug 5045412 + * @bug 5045412 6627366 * @compile -Xlint:serial -XDfailcomplete=java.io.Serializable Foo.java */ /** * @test - * @bug 5045412 - * @compile/fail/ref=out -XDstdout -XDrawDiagnostics -Xlint:serial -XDfailcomplete=java.io.Serializable Foo.java Bar.java + * @bug 5045412 6627366 + * @compile -Xlint:serial -XDfailcomplete=java.io.Serializable Foo.java Bar.java */ class Foo { } diff --git a/langtools/test/tools/javac/5045412/out b/langtools/test/tools/javac/5045412/out deleted file mode 100644 index 17cafef2624..00000000000 --- a/langtools/test/tools/javac/5045412/out +++ /dev/null @@ -1,2 +0,0 @@ -Bar.java:13:29: compiler.err.cant.resolve.location: kindname.class, Serializable, , , kindname.package, java.io -1 error diff --git a/langtools/test/tools/javac/6627362/T6627362.java b/langtools/test/tools/javac/6627362/T6627362.java new file mode 100644 index 00000000000..7230501b40f --- /dev/null +++ b/langtools/test/tools/javac/6627362/T6627362.java @@ -0,0 +1,133 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6627362 + * @summary javac generates code that uses array.clone, + * which is not available on JavaCard + */ + +import java.io.*; +import java.lang.reflect.*; +import java.net.*; +import java.util.*; + +public class T6627362 { + static String testSrc = System.getProperty("test.src", "."); + + public static void main(String... args) throws Exception { + new T6627362().run(); + } + + public void run() throws Exception { + testStandard(); + testNoClone(); + if (errors > 0) + throw new Error(errors + " test cases failed"); + } + + void testStandard() throws Exception { + // compile and disassemble E.java, check for reference to Object.clone() + File x = new File(testSrc, "x"); + String[] jcArgs = { "-d", ".", + new File(x, "E.java").getPath() }; + compile(jcArgs); + + String[] jpArgs = { "-classpath", ".", "-c", "E" }; + + StringWriter sw = new StringWriter(); + javap(new PrintWriter(sw, true), jpArgs); + check(sw.toString(), "Method \"[LE;\".clone:()Ljava/lang/Object;"); + callValues(); + } + + void testNoClone() throws Exception { + // compile and disassemble E.java, using modified Object.java, + // check for reference to System.arraycopy + File x = new File(testSrc, "x"); + String[] jcArgs = { "-d", ".", + new File(x, "E.java").getPath(), + new File(x, "Object.java").getPath()}; + compile(jcArgs); + + String[] jpArgs = { "-classpath", ".", "-c", "E" }; + + StringWriter sw = new StringWriter(); + javap(new PrintWriter(sw, true), jpArgs); + check(sw.toString(), "//Method java/lang/System.arraycopy:(Ljava/lang/Object;ILjava/lang/Object;II)V"); + callValues(); + } + + void compile(String... args) { + int rc = com.sun.tools.javac.Main.compile(args); + if (rc != 0) + throw new Error("javac failed: " + Arrays.asList(args) + ": " + rc); + } + + void javap(PrintWriter out, String... args) throws Exception { + // for now, we have to exec javap + File javaHome = new File(System.getProperty("java.home")); + if (javaHome.getName().equals("jre")) + javaHome = javaHome.getParentFile(); + File javap = new File(new File(javaHome, "bin"), "javap"); + String[] cmd = new String[args.length + 1]; + cmd[0] = javap.getPath(); + System.arraycopy(args, 0, cmd, 1, args.length); + Process p = new ProcessBuilder(cmd).redirectErrorStream(true).start(); + p.getOutputStream().close(); + BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream())); + String line; + while ((line = in.readLine()) != null) + out.println(line); + int rc = p.waitFor(); + if (rc != 0) + throw new Error("javap failed: " + Arrays.asList(args) + ": " + rc); + } + + void check(String s, String require) { + if (s.indexOf(require) == -1) { + System.err.println("Can't find " + require); + errors++; + } + } + + void callValues() { + try { + File dot = new File(System.getProperty("user.dir")); + ClassLoader cl = new URLClassLoader(new URL[] { dot.toURL() }); + Class e_class = cl.loadClass("E"); + Method m = e_class.getMethod("values", new Class[] { }); + //System.err.println(m); + Object o = m.invoke(null, (Object[]) null); + List v = Arrays.asList((Object[]) o); + if (!v.toString().equals("[a, b, c]")) + throw new Error("unexpected result for E.values(): " + v); + } catch (Exception e) { + throw new Error(e); + } + } + + int errors; +} + diff --git a/langtools/test/tools/javac/6627362/x/E.java b/langtools/test/tools/javac/6627362/x/E.java new file mode 100644 index 00000000000..0ca1ee8d16c --- /dev/null +++ b/langtools/test/tools/javac/6627362/x/E.java @@ -0,0 +1,26 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +public enum E { + a, b, c +} diff --git a/langtools/test/tools/javac/6627362/x/Object.java b/langtools/test/tools/javac/6627362/x/Object.java new file mode 100644 index 00000000000..f618a222ee8 --- /dev/null +++ b/langtools/test/tools/javac/6627362/x/Object.java @@ -0,0 +1,30 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.lang; + +/* + * Object, without clone() + */ +public class Object { +} diff --git a/langtools/test/tools/javac/synthesize/Boolean.java b/langtools/test/tools/javac/synthesize/Boolean.java new file mode 100644 index 00000000000..12427a09764 --- /dev/null +++ b/langtools/test/tools/javac/synthesize/Boolean.java @@ -0,0 +1,41 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.lang; + +public class Boolean +{ + public static Boolean valueOf(boolean v) { + return new Boolean(v); + } + + public Boolean(boolean v) { + value = v; + } + + public boolean booleanValue() { + return value; + } + + private boolean value; +} diff --git a/langtools/test/tools/javac/synthesize/Byte.java b/langtools/test/tools/javac/synthesize/Byte.java new file mode 100644 index 00000000000..4b7600c9ea8 --- /dev/null +++ b/langtools/test/tools/javac/synthesize/Byte.java @@ -0,0 +1,41 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.lang; + +public class Byte +{ + public static Byte valueOf(byte v) { + return new Byte(v); + } + + public Byte(byte v) { + value = v; + } + + public byte byteValue() { + return value; + } + + private byte value; +} diff --git a/langtools/test/tools/javac/synthesize/Character.java b/langtools/test/tools/javac/synthesize/Character.java new file mode 100644 index 00000000000..9eefdb21683 --- /dev/null +++ b/langtools/test/tools/javac/synthesize/Character.java @@ -0,0 +1,41 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.lang; + +public class Character +{ + public static Character valueOf(char v) { + return new Character(v); + } + + public Character(char v) { + value = v; + } + + public char characterValue() { + return value; + } + + private char value; +} diff --git a/langtools/test/tools/javac/synthesize/Cloneable.java b/langtools/test/tools/javac/synthesize/Cloneable.java new file mode 100644 index 00000000000..018159a8eb1 --- /dev/null +++ b/langtools/test/tools/javac/synthesize/Cloneable.java @@ -0,0 +1,27 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.lang; + +public interface Cloneable { +} diff --git a/langtools/test/tools/javac/synthesize/Double.java b/langtools/test/tools/javac/synthesize/Double.java new file mode 100644 index 00000000000..7ae620e85c8 --- /dev/null +++ b/langtools/test/tools/javac/synthesize/Double.java @@ -0,0 +1,18 @@ +package java.lang; + +public class Double extends Number +{ + public static Double valueOf(double v) { + return new Double(v); + } + + public Double(double v) { + value = v; + } + + public double doubleValue() { + return value; + } + + private double value; +} diff --git a/langtools/test/tools/javac/synthesize/Float.java b/langtools/test/tools/javac/synthesize/Float.java new file mode 100644 index 00000000000..afbef38bebc --- /dev/null +++ b/langtools/test/tools/javac/synthesize/Float.java @@ -0,0 +1,18 @@ +package java.lang; + +public class Float extends Number +{ + public static Float valueOf(float v) { + return new Float(v); + } + + public Float(float v) { + value = v; + } + + public float floatValue() { + return value; + } + + private float value; +} diff --git a/langtools/test/tools/javac/synthesize/Integer.java b/langtools/test/tools/javac/synthesize/Integer.java new file mode 100644 index 00000000000..52c47226eb3 --- /dev/null +++ b/langtools/test/tools/javac/synthesize/Integer.java @@ -0,0 +1,41 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.lang; + +public class Integer extends Number +{ + public static Integer valueOf(int v) { + return new Integer(v); + } + + public Integer(int v) { + value = v; + } + + public int integerValue() { + return value; + } + + private int value; +} diff --git a/langtools/test/tools/javac/synthesize/Long.java b/langtools/test/tools/javac/synthesize/Long.java new file mode 100644 index 00000000000..748b421185c --- /dev/null +++ b/langtools/test/tools/javac/synthesize/Long.java @@ -0,0 +1,41 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.lang; + +public class Long extends Number +{ + public static Long valueOf(long v) { + return new Long(v); + } + + public Long(long v) { + value = v; + } + + public long longValue() { + return value; + } + + private long value; +} diff --git a/langtools/test/tools/javac/synthesize/Main.java b/langtools/test/tools/javac/synthesize/Main.java new file mode 100644 index 00000000000..33b75a1c703 --- /dev/null +++ b/langtools/test/tools/javac/synthesize/Main.java @@ -0,0 +1,122 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6627364 6627366 + * @summary Synthesize important classes if they are missing from the (boot)classpath + */ + +import java.io.*; +import java.util.*; + +public class Main +{ + File testSrc = new File(System.getProperty("test.src")); + + public static void main(String[] args) throws Exception { + new Main().run(); + } + + public void run() throws Exception { + + // compile with standard bootclasspath + compile(true, "Test.java"); + + // compile with various missing system classes + + List base_files = Arrays.asList( + "Boolean.java", + "Byte.java", + "Character.java", + "Integer.java", + "Long.java", + "Number.java", + "Object.java", + "Short.java", + "Void.java" + ); + + List extra_files = Arrays.asList( + "Double.java", + "Float.java", + "Cloneable.java", + "Serializable.java" + ); + + List files = new ArrayList(); + files.addAll(base_files); + files.add("Test.java"); + + compile(false, files); + + for (String f: extra_files) { + files = new ArrayList(); + files.addAll(base_files); + files.addAll(extra_files); + files.remove(f); + files.add("Test.java"); + compile(false, files); + } + + if (errors > 0) + throw new Exception(errors + " errors occurred"); + } + + void compile(boolean stdBootClassPath, String... files) { + compile(stdBootClassPath, Arrays.asList(files)); + } + + void compile(boolean stdBootClassPath, List files) { + File empty = new File("empty"); + empty.mkdirs(); + + List args = new ArrayList(); + args.add("-classpath"); + args.add("empty"); + + if (!stdBootClassPath) { + args.add("-bootclasspath"); + args.add("empty"); + } + args.add("-d"); + args.add("."); + for (String f: files) + args.add(new File(testSrc, f).getPath()); + + System.out.println("Compile: " + args); + StringWriter out = new StringWriter(); + int rc = com.sun.tools.javac.Main.compile(args.toArray(new String[args.size()]), + new PrintWriter(out)); + System.out.println(out.toString()); + System.out.println("result: " + rc); + System.out.println(); + + if (rc != 0) + errors++; + } + + private int errors; +} + + diff --git a/langtools/test/tools/javac/synthesize/Number.java b/langtools/test/tools/javac/synthesize/Number.java new file mode 100644 index 00000000000..efef7926413 --- /dev/null +++ b/langtools/test/tools/javac/synthesize/Number.java @@ -0,0 +1,29 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.lang; + +public class Number +{ + +} diff --git a/langtools/test/tools/javac/synthesize/Object.java b/langtools/test/tools/javac/synthesize/Object.java new file mode 100644 index 00000000000..c52acf952f2 --- /dev/null +++ b/langtools/test/tools/javac/synthesize/Object.java @@ -0,0 +1,28 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.lang; + +public class Object +{ +} diff --git a/langtools/test/tools/javac/synthesize/Serializable.java b/langtools/test/tools/javac/synthesize/Serializable.java new file mode 100644 index 00000000000..b5b761e21d8 --- /dev/null +++ b/langtools/test/tools/javac/synthesize/Serializable.java @@ -0,0 +1,27 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.io; + +public interface Serializable { +} diff --git a/langtools/test/tools/javac/synthesize/Short.java b/langtools/test/tools/javac/synthesize/Short.java new file mode 100644 index 00000000000..3d674c2e496 --- /dev/null +++ b/langtools/test/tools/javac/synthesize/Short.java @@ -0,0 +1,41 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.lang; + +public class Short extends Number +{ + public static Short valueOf(short v) { + return new Short(v); + } + + public Short(short v) { + value = v; + } + + public short shortValue() { + return value; + } + + private short value; +} diff --git a/langtools/test/tools/javac/synthesize/Test.java b/langtools/test/tools/javac/synthesize/Test.java new file mode 100644 index 00000000000..fc873189f88 --- /dev/null +++ b/langtools/test/tools/javac/synthesize/Test.java @@ -0,0 +1,32 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +// This code (indirectly) requires the presence of +// Cloneable and Serializable (supertypes for Java arrays) +// Double and Float (for boxing/unboxing) +public class Test +{ + Object f(boolean b, int[] array) { + return b ? array : 2; + } +} diff --git a/langtools/test/tools/javac/synthesize/Void.java b/langtools/test/tools/javac/synthesize/Void.java new file mode 100644 index 00000000000..18415a49ce8 --- /dev/null +++ b/langtools/test/tools/javac/synthesize/Void.java @@ -0,0 +1,29 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.lang; + +public class Void +{ + +} From 44444bd9c0980b60d97f98ef2a2568f1f4674118 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 4 Aug 2008 15:09:02 -0700 Subject: [PATCH 25/52] 4111861: static final field contents are not displayed Reviewed-by: ksrini --- .../com/sun/tools/javap/ClassWriter.java | 84 +++++++++++++++ .../com/sun/tools/javap/JavapTask.java | 6 ++ .../classes/com/sun/tools/javap/Options.java | 1 + .../tools/javap/resources/javap.properties | 4 + langtools/test/tools/javap/4111861/A.java | 14 +++ .../test/tools/javap/4111861/T4111861.java | 101 ++++++++++++++++++ 6 files changed, 210 insertions(+) create mode 100644 langtools/test/tools/javap/4111861/A.java create mode 100644 langtools/test/tools/javap/4111861/T4111861.java diff --git a/langtools/src/share/classes/com/sun/tools/javap/ClassWriter.java b/langtools/src/share/classes/com/sun/tools/javap/ClassWriter.java index d1c5707a8d8..83362913c61 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/ClassWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javap/ClassWriter.java @@ -35,6 +35,7 @@ import com.sun.tools.classfile.ClassFile; import com.sun.tools.classfile.Code_attribute; import com.sun.tools.classfile.ConstantPool; import com.sun.tools.classfile.ConstantPoolException; +import com.sun.tools.classfile.ConstantValue_attribute; import com.sun.tools.classfile.Descriptor; import com.sun.tools.classfile.DescriptorException; import com.sun.tools.classfile.Exceptions_attribute; @@ -185,6 +186,14 @@ public class ClassWriter extends BasicWriter { } print(" "); print(getFieldName(f)); + if (options.showConstants && !options.compat) { // BUG 4111861 print static final field contents + Attribute a = f.attributes.get(Attribute.ConstantValue); + if (a instanceof ConstantValue_attribute) { + print(" = "); + ConstantValue_attribute cv = (ConstantValue_attribute) a; + print(getConstantValue(f.descriptor, cv.constantvalue_index)); + } + } print(";"); println(); @@ -481,6 +490,81 @@ public class ClassWriter extends BasicWriter { } } + /** + * Get the value of an entry in the constant pool as a Java constant. + * Characters and booleans are represented by CONSTANT_Intgere entries. + * Character and string values are processed to escape characters outside + * the basic printable ASCII set. + * @param d the descriptor, giving the expected type of the constant + * @param index the index of the value in the constant pool + * @return a printable string containing the value of the constant. + */ + String getConstantValue(Descriptor d, int index) { + try { + ConstantPool.CPInfo cpInfo = constant_pool.get(index); + + switch (cpInfo.getTag()) { + case ConstantPool.CONSTANT_Integer: { + ConstantPool.CONSTANT_Integer_info info = + (ConstantPool.CONSTANT_Integer_info) cpInfo; + String t = d.getValue(constant_pool); + if (t.equals("C")) { // character + return getConstantCharValue((char) info.value); + } else if (t.equals("Z")) { // boolean + return String.valueOf(info.value == 1); + } else { // other: assume integer + return String.valueOf(info.value); + } + } + + case ConstantPool.CONSTANT_String: { + ConstantPool.CONSTANT_String_info info = + (ConstantPool.CONSTANT_String_info) cpInfo; + return getConstantStringValue(info.getString()); + } + + default: + return constantWriter.stringValue(cpInfo); + } + } catch (ConstantPoolException e) { + return "#" + index; + } + } + + private String getConstantCharValue(char c) { + StringBuilder sb = new StringBuilder(); + sb.append('\''); + sb.append(esc(c, '\'')); + sb.append('\''); + return sb.toString(); + } + + private String getConstantStringValue(String s) { + StringBuilder sb = new StringBuilder(); + sb.append("\""); + for (int i = 0; i < s.length(); i++) { + sb.append(esc(s.charAt(i), '"')); + } + sb.append("\""); + return sb.toString(); + } + + private String esc(char c, char quote) { + if (32 <= c && c <= 126 && c != quote) + return String.valueOf(c); + else switch (c) { + case '\b': return "\\b"; + case '\n': return "\\n"; + case '\t': return "\\t"; + case '\f': return "\\f"; + case '\r': return "\\r"; + case '\\': return "\\\\"; + case '\'': return "\\'"; + case '\"': return "\\\""; + default: return String.format("\\u%04x", (int) c); + } + } + private Options options; private AttributeWriter attrWriter; private CodeWriter codeWriter; diff --git a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java index 1fc2886385c..9aa755d2bd5 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java +++ b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java @@ -229,6 +229,12 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask { void process(JavapTask task, String opt, String arg) { task.options.ignoreSymbolFile = true; } + }, + + new Option(false, "-constants") { + void process(JavapTask task, String opt, String arg) { + task.options.showConstants = true; + } } }; diff --git a/langtools/src/share/classes/com/sun/tools/javap/Options.java b/langtools/src/share/classes/com/sun/tools/javap/Options.java index fcbfc0211d8..3b3f7766e4e 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/Options.java +++ b/langtools/src/share/classes/com/sun/tools/javap/Options.java @@ -80,6 +80,7 @@ public class Options { public boolean showDisassembled; public boolean showInternalSignatures; public boolean showAllAttrs; + public boolean showConstants; public boolean compat; // bug-for-bug compatibility mode with old javap public boolean jsr277; diff --git a/langtools/src/share/classes/com/sun/tools/javap/resources/javap.properties b/langtools/src/share/classes/com/sun/tools/javap/resources/javap.properties index 8f50abb94bd..fe07df95830 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/resources/javap.properties +++ b/langtools/src/share/classes/com/sun/tools/javap/resources/javap.properties @@ -63,5 +63,9 @@ main.opt.classpath=\ main.opt.bootclasspath=\ \ -bootclasspath Override location of bootstrap class files +main.opt.constants=\ +\ -constants Show static final constants + + diff --git a/langtools/test/tools/javap/4111861/A.java b/langtools/test/tools/javap/4111861/A.java new file mode 100644 index 00000000000..32cc86a8f07 --- /dev/null +++ b/langtools/test/tools/javap/4111861/A.java @@ -0,0 +1,14 @@ +class A { + public static final int i = 42; + public static final boolean b = true; + public static final float f = 1.0f; + public static final double d = 1.0d; + public static final short s = 1; + public static final long l = 1l; + public static final char cA = 'A'; + public static final char c0 = '\u0000'; + public static final char cn = '\n'; + public static final char cq1 = '\''; + public static final char cq2 = '"'; + public static final java.lang.String t1 = "abc \u0000 \f\n\r\t'\""; +} diff --git a/langtools/test/tools/javap/4111861/T4111861.java b/langtools/test/tools/javap/4111861/T4111861.java new file mode 100644 index 00000000000..b722d80b41a --- /dev/null +++ b/langtools/test/tools/javap/4111861/T4111861.java @@ -0,0 +1,101 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import java.io.*; + +/* + * @test + * @bug 4111861 + * @summary static final field contents are not displayed + */ +public class T4111861 { + public static void main(String... args) throws Exception { + new T4111861().run(); + } + + void run() throws Exception { + File testSrc = new File(System.getProperty("test.src", ".")); + File a_java = new File(testSrc, "A.java"); + javac("-d", ".", a_java.getPath()); + + String out = javap("-classpath", ".", "-constants", "A"); + + String a = read(a_java); + + if (!filter(out).equals(filter(read(a_java)))) { + System.out.println(out); + throw new Exception("unexpected output"); + } + } + + String javac(String... args) throws Exception { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + int rc = com.sun.tools.javac.Main.compile(args, pw); + if (rc != 0) + throw new Exception("javac failed, rc=" + rc); + return sw.toString(); + } + + String javap(String... args) throws Exception { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + int rc = com.sun.tools.javap.Main.run(args, pw); + if (rc != 0) + throw new Exception("javap failed, rc=" + rc); + return sw.toString(); + } + + String read(File f) throws IOException { + StringBuilder sb = new StringBuilder(); + BufferedReader in = new BufferedReader(new FileReader(f)); + try { + String line; + while ((line = in.readLine()) != null) { + sb.append(line); + sb.append('\n'); + } + } finally { + in.close(); + } + return sb.toString(); + } + + // return those lines beginning "public static final" + String filter(String s) throws IOException { + StringBuilder sb = new StringBuilder(); + BufferedReader in = new BufferedReader(new StringReader(s)); + try { + String line; + while ((line = in.readLine()) != null) { + if (line.indexOf("public static final") > 0) { + sb.append(line); + sb.append('\n'); + } + } + } finally { + in.close(); + } + return sb.toString(); + } +} From b6dbc8cf63a5800fce2da9d62e432b789d8bb662 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 4 Aug 2008 17:54:15 -0700 Subject: [PATCH 26/52] 4884240: additional option required for javap Reviewed-by: ksrini --- .../com/sun/tools/javap/ClassWriter.java | 51 ++++++++++++++++ .../com/sun/tools/javap/JavapTask.java | 58 ++++++++++++++++++- .../classes/com/sun/tools/javap/Options.java | 1 + .../tools/javap/resources/javap.properties | 5 +- langtools/test/tools/javap/T4884240.java | 56 ++++++++++++++++++ langtools/test/tools/javap/T6622260.java | 4 ++ 6 files changed, 172 insertions(+), 3 deletions(-) create mode 100644 langtools/test/tools/javap/T4884240.java diff --git a/langtools/src/share/classes/com/sun/tools/javap/ClassWriter.java b/langtools/src/share/classes/com/sun/tools/javap/ClassWriter.java index 83362913c61..aaf3b000a63 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/ClassWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javap/ClassWriter.java @@ -25,6 +25,7 @@ package com.sun.tools.javap; +import java.net.URI; import java.util.Collection; import java.util.List; @@ -46,6 +47,8 @@ import com.sun.tools.classfile.Signature_attribute; import com.sun.tools.classfile.SourceFile_attribute; import com.sun.tools.classfile.Type; +import java.text.DateFormat; +import java.util.Date; import static com.sun.tools.classfile.AccessFlags.*; /* @@ -73,6 +76,23 @@ public class ClassWriter extends BasicWriter { constantWriter = ConstantWriter.instance(context); } + void setDigest(String name, byte[] digest) { + this.digestName = name; + this.digest = digest; + } + + void setFile(URI uri) { + this.uri = uri; + } + + void setFileSize(int size) { + this.size = size; + } + + void setLastModified(long lastModified) { + this.lastModified = lastModified; + } + ClassFile getClassFile() { return classFile; } @@ -85,6 +105,32 @@ public class ClassWriter extends BasicWriter { classFile = cf; constant_pool = classFile.constant_pool; + if ((options.sysInfo || options.verbose) && !options.compat) { + if (uri != null) { + if (uri.getScheme().equals("file")) + println("Classfile " + uri.getPath()); + else + println("Classfile " + uri); + } + if (lastModified != -1) { + Date lm = new Date(lastModified); + DateFormat df = DateFormat.getDateInstance(); + if (size > 0) { + println("Last modified " + df.format(lm) + "; size " + size + " bytes"); + } else { + println("Last modified " + df.format(lm)); + } + } else if (size > 0) { + println("Size " + size + " bytes"); + } + if (digestName != null && digest != null) { + StringBuilder sb = new StringBuilder(); + for (byte b: digest) + sb.append(String.format("%02x", b)); + println(digestName + " checksum " + sb); + } + } + Attribute sfa = cf.getAttribute(Attribute.SourceFile); if (sfa instanceof SourceFile_attribute) { println("Compiled from \"" + getSourceFile((SourceFile_attribute) sfa) + "\""); @@ -570,6 +616,11 @@ public class ClassWriter extends BasicWriter { private CodeWriter codeWriter; private ConstantWriter constantWriter; private ClassFile classFile; + private URI uri; + private long lastModified; + private String digestName; + private byte[] digest; + private int size; private ConstantPool constant_pool; private Method method; private static final String NEWLINE = System.getProperty("line.separator", "\n"); diff --git a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java index 9aa755d2bd5..10f34846e53 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java +++ b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java @@ -27,11 +27,15 @@ package com.sun.tools.javap; import java.io.EOFException; import java.io.FileNotFoundException; +import java.io.FilterInputStream; +import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; +import java.security.DigestInputStream; +import java.security.MessageDigest; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; @@ -199,6 +203,12 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask { } }, + new Option(false, "-sysinfo") { + void process(JavapTask task, String opt, String arg) { + task.options.sysInfo = true; + } + }, + new Option(false, "-Xold") { void process(JavapTask task, String opt, String arg) throws BadArgs { // -Xold is only supported as first arg when invoked from @@ -494,8 +504,27 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask { Attribute.Factory attributeFactory = new Attribute.Factory(); attributeFactory.setCompat(options.compat); attributeFactory.setJSR277(options.jsr277); - ClassFile cf = ClassFile.read(fo.openInputStream(), attributeFactory); + + InputStream in = fo.openInputStream(); + SizeInputStream sizeIn = null; + MessageDigest md = null; + if (options.sysInfo || options.verbose) { + md = MessageDigest.getInstance("MD5"); + in = new DigestInputStream(in, md); + in = sizeIn = new SizeInputStream(in); + } + + ClassFile cf = ClassFile.read(in, attributeFactory); + + if (options.sysInfo || options.verbose) { + classWriter.setFile(fo.toUri()); + classWriter.setLastModified(fo.getLastModified()); + classWriter.setDigest("MD5", md.digest()); + classWriter.setFileSize(sizeIn.size()); + } + classWriter.write(cf); + } catch (ConstantPoolException e) { diagnosticListener.report(createDiagnostic("err.bad.constant.pool", className, e.getLocalizedMessage())); ok = false; @@ -665,4 +694,31 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask { Map bundles; private static final String progname = "javap"; + + private static class SizeInputStream extends FilterInputStream { + SizeInputStream(InputStream in) { + super(in); + } + + int size() { + return size; + } + + @Override + public int read(byte[] buf, int offset, int length) throws IOException { + int n = super.read(buf, offset, length); + if (n > 0) + size += n; + return n; + } + + @Override + public int read() throws IOException { + int b = super.read(); + size += 1; + return b; + } + + private int size; + } } diff --git a/langtools/src/share/classes/com/sun/tools/javap/Options.java b/langtools/src/share/classes/com/sun/tools/javap/Options.java index 3b3f7766e4e..332fc1f28cc 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/Options.java +++ b/langtools/src/share/classes/com/sun/tools/javap/Options.java @@ -81,6 +81,7 @@ public class Options { public boolean showInternalSignatures; public boolean showAllAttrs; public boolean showConstants; + public boolean sysInfo; public boolean compat; // bug-for-bug compatibility mode with old javap public boolean jsr277; diff --git a/langtools/src/share/classes/com/sun/tools/javap/resources/javap.properties b/langtools/src/share/classes/com/sun/tools/javap/resources/javap.properties index fe07df95830..afbb06368f4 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/resources/javap.properties +++ b/langtools/src/share/classes/com/sun/tools/javap/resources/javap.properties @@ -67,5 +67,6 @@ main.opt.constants=\ \ -constants Show static final constants - - +main.opt.sysinfo=\ +\ -sysinfo Show system info (path, size, date, MD5 hash)\n\ +\ of class being processed diff --git a/langtools/test/tools/javap/T4884240.java b/langtools/test/tools/javap/T4884240.java new file mode 100644 index 00000000000..93d4cc9361c --- /dev/null +++ b/langtools/test/tools/javap/T4884240.java @@ -0,0 +1,56 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * 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-15301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 4884240 + * @summary additional option required for javap + */ + +import java.io.*; + +public class T4884240 { + public static void main(String... args) throws Exception { + new T4884240().run(); + } + + public void run() throws Exception { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + String[] args = { "-sysinfo", "java.lang.Object" }; + int rc = com.sun.tools.javap.Main.run(args, pw); + if (rc != 0) + throw new Exception("unexpected return code: " + rc); + pw.close(); + String[] lines = sw.toString().split("\n"); + if (lines.length < 3 + || !lines[0].startsWith("Classfile") + || !lines[1].startsWith("Last modified") + || !lines[2].startsWith("MD5")) { + System.out.println(sw); + throw new Exception("unexpected output"); + } + } +} diff --git a/langtools/test/tools/javap/T6622260.java b/langtools/test/tools/javap/T6622260.java index be70657e844..d0b5694d030 100644 --- a/langtools/test/tools/javap/T6622260.java +++ b/langtools/test/tools/javap/T6622260.java @@ -189,6 +189,10 @@ public class T6622260 { void verify(String output) { System.out.println(output); + if (output.startsWith("Classfile")) { + // make sure to ignore filename + output = output.substring(output.indexOf('\n')); + } if (output.indexOf("-") >= 0) throw new Error("- found in output"); if (output.indexOf("FFFFFF") >= 0) From ad5fef1fce7a5951d01c0f8d8361930fdb3cac34 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Tue, 5 Aug 2008 12:54:40 +0100 Subject: [PATCH 27/52] 6730423: Diagnostic formatter should be an instance field of JCDiagnostic JCDiagnostic.fragment should be deprecated and the diagnostic factory should be used instead Reviewed-by: jjg --- .../com/sun/tools/javac/comp/Attr.java | 4 +- .../com/sun/tools/javac/comp/Check.java | 38 +++++++------ .../com/sun/tools/javac/comp/Infer.java | 25 ++++++--- .../com/sun/tools/javac/comp/MemberEnter.java | 6 +- .../com/sun/tools/javac/comp/Resolve.java | 8 ++- .../sun/tools/javac/util/JCDiagnostic.java | 55 ++++++++++--------- 6 files changed, 76 insertions(+), 60 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index de1453e8ea9..bb999149cc6 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -79,6 +79,7 @@ public class Attr extends JCTree.Visitor { final Enter enter; final Target target; final Types types; + final JCDiagnostic.Factory diags; final Annotate annotate; public static Attr instance(Context context) { @@ -102,6 +103,7 @@ public class Attr extends JCTree.Visitor { cfolder = ConstFold.instance(context); target = Target.instance(context); types = Types.instance(context); + diags = JCDiagnostic.Factory.instance(context); annotate = Annotate.instance(context); Options options = Options.instance(context); @@ -2419,7 +2421,7 @@ public class Attr extends JCTree.Visitor { if (false) { // TODO: make assertConvertible work - chk.typeError(tree.pos(), JCDiagnostic.fragment("incompatible.types"), actual, formal); + chk.typeError(tree.pos(), diags.fragment("incompatible.types"), actual, formal); throw new AssertionError("Tree: " + tree + " actual:" + actual + " formal: " + formal); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index 80477fce9ce..7335c32774d 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -63,6 +63,7 @@ public class Check { private final Target target; private final Source source; private final Types types; + private final JCDiagnostic.Factory diags; private final boolean skipAnnotations; private final TreeInfo treeinfo; @@ -86,6 +87,7 @@ public class Check { syms = Symtab.instance(context); infer = Infer.instance(context); this.types = Types.instance(context); + diags = JCDiagnostic.Factory.instance(context); Options options = Options.instance(context); target = Target.instance(context); source = Source.instance(context); @@ -343,7 +345,7 @@ public class Check { if (types.isAssignable(found, req, convertWarner(pos, found, req))) return found; if (found.tag <= DOUBLE && req.tag <= DOUBLE) - return typeError(pos, JCDiagnostic.fragment("possible.loss.of.precision"), found, req); + return typeError(pos, diags.fragment("possible.loss.of.precision"), found, req); if (found.isSuperBound()) { log.error(pos, "assignment.from.super-bound", found); return syms.errType; @@ -352,7 +354,7 @@ public class Check { log.error(pos, "assignment.to.extends-bound", req); return syms.errType; } - return typeError(pos, JCDiagnostic.fragment("incompatible.types"), found, req); + return typeError(pos, diags.fragment("incompatible.types"), found, req); } /** Instantiate polymorphic type to some prototype, unless @@ -380,7 +382,7 @@ public class Check { } else { JCDiagnostic d = ex.getDiagnostic(); return typeError(pos, - JCDiagnostic.fragment("incompatible.types" + (d!=null ? ".1" : ""), d), + diags.fragment("incompatible.types" + (d!=null ? ".1" : ""), d), t, pt); } } @@ -401,7 +403,7 @@ public class Check { return req; } else { return typeError(pos, - JCDiagnostic.fragment("inconvertible.types"), + diags.fragment("inconvertible.types"), found, req); } } @@ -480,9 +482,9 @@ public class Check { Type checkClassType(DiagnosticPosition pos, Type t) { if (t.tag != CLASS && t.tag != ERROR) return typeTagError(pos, - JCDiagnostic.fragment("type.req.class"), + diags.fragment("type.req.class"), (t.tag == TYPEVAR) - ? JCDiagnostic.fragment("type.parameter", t) + ? diags.fragment("type.parameter", t) : t); else return t; @@ -515,7 +517,7 @@ public class Check { Type checkReifiableReferenceType(DiagnosticPosition pos, Type t) { if (t.tag != CLASS && t.tag != ARRAY && t.tag != ERROR) { return typeTagError(pos, - JCDiagnostic.fragment("type.req.class.array"), + diags.fragment("type.req.class.array"), t); } else if (!types.isReifiable(t)) { log.error(pos, "illegal.generic.type.for.instof"); @@ -540,7 +542,7 @@ public class Check { return t; default: return typeTagError(pos, - JCDiagnostic.fragment("type.req.ref"), + diags.fragment("type.req.ref"), t); } } @@ -560,7 +562,7 @@ public class Check { return t; default: return typeTagError(pos, - JCDiagnostic.fragment("type.req.ref"), + diags.fragment("type.req.ref"), t); } } @@ -1028,7 +1030,7 @@ public class Check { * @param other The overridden method. * @return An internationalized string. */ - static Object cannotOverride(MethodSymbol m, MethodSymbol other) { + Object cannotOverride(MethodSymbol m, MethodSymbol other) { String key; if ((other.owner.flags() & INTERFACE) == 0) key = "cant.override"; @@ -1036,7 +1038,7 @@ public class Check { key = "cant.implement"; else key = "clashes.with"; - return JCDiagnostic.fragment(key, m, m.location(), other, other.location()); + return diags.fragment(key, m, m.location(), other, other.location()); } /** A customized "override" warning message. @@ -1044,7 +1046,7 @@ public class Check { * @param other The overridden method. * @return An internationalized string. */ - static Object uncheckedOverrides(MethodSymbol m, MethodSymbol other) { + Object uncheckedOverrides(MethodSymbol m, MethodSymbol other) { String key; if ((other.owner.flags() & INTERFACE) == 0) key = "unchecked.override"; @@ -1052,7 +1054,7 @@ public class Check { key = "unchecked.implement"; else key = "unchecked.clash.with"; - return JCDiagnostic.fragment(key, m, m.location(), other, other.location()); + return diags.fragment(key, m, m.location(), other, other.location()); } /** A customized "override" warning message. @@ -1060,7 +1062,7 @@ public class Check { * @param other The overridden method. * @return An internationalized string. */ - static Object varargsOverrides(MethodSymbol m, MethodSymbol other) { + Object varargsOverrides(MethodSymbol m, MethodSymbol other) { String key; if ((other.owner.flags() & INTERFACE) == 0) key = "varargs.override"; @@ -1068,7 +1070,7 @@ public class Check { key = "varargs.implement"; else key = "varargs.clash.with"; - return JCDiagnostic.fragment(key, m, m.location(), other, other.location()); + return diags.fragment(key, m, m.location(), other, other.location()); } /** Check that this method conforms with overridden method 'other'. @@ -1157,7 +1159,7 @@ public class Check { // allow limited interoperability with covariant returns } else { typeError(TreeInfo.diagnosticPositionFor(m, tree), - JCDiagnostic.fragment("override.incompatible.ret", + diags.fragment("override.incompatible.ret", cannotOverride(m, other)), mtres, otres); return; @@ -1165,7 +1167,7 @@ public class Check { } else if (overrideWarner.warned) { warnUnchecked(TreeInfo.diagnosticPositionFor(m, tree), "prob.found.req", - JCDiagnostic.fragment("override.unchecked.ret", + diags.fragment("override.unchecked.ret", uncheckedOverrides(m, other)), mtres, otres); } @@ -2170,7 +2172,7 @@ public class Check { boolean warned = this.warned; super.warnUnchecked(); if (warned) return; // suppress redundant diagnostics - Object problem = JCDiagnostic.fragment(key); + Object problem = diags.fragment(key); Check.this.warnUnchecked(pos(), "prob.found.req", problem, found, expected); } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java index 64b0bbcc7a5..013b3b10981 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java @@ -29,6 +29,7 @@ import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.List; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Type.*; +import com.sun.tools.javac.util.JCDiagnostic; import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Kinds.*; @@ -50,6 +51,7 @@ public class Infer { Symtab syms; Types types; + JCDiagnostic.Factory diags; public static Infer instance(Context context) { Infer instance = context.get(inferKey); @@ -62,6 +64,11 @@ public class Infer { context.put(inferKey, this); syms = Symtab.instance(context); types = Types.instance(context); + diags = JCDiagnostic.Factory.instance(context); + ambiguousNoInstanceException = + new NoInstanceException(true, diags); + unambiguousNoInstanceException = + new NoInstanceException(false, diags); } public static class NoInstanceException extends RuntimeException { @@ -70,35 +77,35 @@ public class Infer { boolean isAmbiguous; // exist several incomparable best instances? JCDiagnostic diagnostic; + JCDiagnostic.Factory diags; - NoInstanceException(boolean isAmbiguous) { + NoInstanceException(boolean isAmbiguous, JCDiagnostic.Factory diags) { this.diagnostic = null; this.isAmbiguous = isAmbiguous; + this.diags = diags; } NoInstanceException setMessage(String key) { - this.diagnostic = JCDiagnostic.fragment(key); + this.diagnostic = diags.fragment(key); return this; } NoInstanceException setMessage(String key, Object arg1) { - this.diagnostic = JCDiagnostic.fragment(key, arg1); + this.diagnostic = diags.fragment(key, arg1); return this; } NoInstanceException setMessage(String key, Object arg1, Object arg2) { - this.diagnostic = JCDiagnostic.fragment(key, arg1, arg2); + this.diagnostic = diags.fragment(key, arg1, arg2); return this; } NoInstanceException setMessage(String key, Object arg1, Object arg2, Object arg3) { - this.diagnostic = JCDiagnostic.fragment(key, arg1, arg2, arg3); + this.diagnostic = diags.fragment(key, arg1, arg2, arg3); return this; } public JCDiagnostic getDiagnostic() { return diagnostic; } } - private final NoInstanceException ambiguousNoInstanceException = - new NoInstanceException(true); - private final NoInstanceException unambiguousNoInstanceException = - new NoInstanceException(false); + private final NoInstanceException ambiguousNoInstanceException; + private final NoInstanceException unambiguousNoInstanceException; /*************************************************************************** * Auxiliary type values and classes diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java index b391d8fa226..cc3336872d9 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -72,6 +72,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { private final Todo todo; private final Annotate annotate; private final Types types; + private final JCDiagnostic.Factory diags; private final Target target; private final boolean skipAnnotations; @@ -96,6 +97,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { todo = Todo.instance(context); annotate = Annotate.instance(context); types = Types.instance(context); + diags = JCDiagnostic.Factory.instance(context); target = Target.instance(context); skipAnnotations = Options.instance(context).get("skipAnnotations") != null; @@ -133,7 +135,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { if (tsym.kind == PCK && tsym.members().elems == null && !tsym.exists()) { // If we can't find java.lang, exit immediately. if (((PackageSymbol)tsym).fullname.equals(names.java_lang)) { - JCDiagnostic msg = JCDiagnostic.fragment("fatal.err.no.java.lang"); + JCDiagnostic msg = diags.fragment("fatal.err.no.java.lang"); throw new FatalError(msg); } else { log.error(pos, "doesnt.exist", tsym); @@ -319,7 +321,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { log.error(pos, "cant.resolve.location", KindName.STATIC, name, List.nil(), List.nil(), - typeKindName(tsym.type), + Kinds.typeKindName(tsym.type), tsym.type); } } finally { diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java index 42beff18e96..edf1c20210d 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -59,6 +59,7 @@ public class Resolve { ClassReader reader; TreeInfo treeinfo; Types types; + JCDiagnostic.Factory diags; public final boolean boxingEnabled; // = source.allowBoxing(); public final boolean varargsEnabled; // = source.allowVarargs(); private final boolean debugResolve; @@ -92,6 +93,7 @@ public class Resolve { reader = ClassReader.instance(context); treeinfo = TreeInfo.instance(context); types = Types.instance(context); + diags = JCDiagnostic.Factory.instance(context); Source source = Source.instance(context); boxingEnabled = source.allowBoxing(); varargsEnabled = source.allowVarargs(); @@ -449,7 +451,7 @@ public class Resolve { Symbol sym = findField(env, site, name, site.tsym); if (sym.kind == VAR) return (VarSymbol)sym; else throw new FatalError( - JCDiagnostic.fragment("fatal.err.cant.locate.field", + diags.fragment("fatal.err.cant.locate.field", name)); } @@ -1248,7 +1250,7 @@ public class Resolve { pos, env, site, name, argtypes, typeargtypes); if (sym.kind == MTH) return (MethodSymbol)sym; else throw new FatalError( - JCDiagnostic.fragment("fatal.err.cant.locate.meth", + diags.fragment("fatal.err.cant.locate.meth", name)); } @@ -1320,7 +1322,7 @@ public class Resolve { pos, env, site, argtypes, typeargtypes); if (sym.kind == MTH) return (MethodSymbol)sym; else throw new FatalError( - JCDiagnostic.fragment("fatal.err.cant.locate.ctor", site)); + diags.fragment("fatal.err.cant.locate.ctor", site)); } /** Resolve operator. diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java b/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java index 9b7ccaf17c1..acc2328a5cf 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java @@ -59,20 +59,19 @@ public class JCDiagnostic implements Diagnostic { return instance; } - final Messages messages; + DiagnosticFormatter formatter; final String prefix; /** Create a new diagnostic factory. */ protected Factory(Context context) { + this(Messages.instance(context), "compiler"); context.put(diagnosticFactoryKey, this); - messages = Messages.instance(context); - prefix = "compiler"; } /** Create a new diagnostic factory. */ public Factory(Messages messages, String prefix) { - this.messages = messages; this.prefix = prefix; + this.formatter = new BasicDiagnosticFormatter(messages); } /** @@ -84,7 +83,7 @@ public class JCDiagnostic implements Diagnostic { */ public JCDiagnostic error( DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) { - return new JCDiagnostic(messages, ERROR, true, source, pos, qualify(ERROR, key), args); + return new JCDiagnostic(formatter, ERROR, true, source, pos, qualify(ERROR, key), args); } /** @@ -97,7 +96,7 @@ public class JCDiagnostic implements Diagnostic { */ public JCDiagnostic mandatoryWarning( DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) { - return new JCDiagnostic(messages, WARNING, true, source, pos, qualify(WARNING, key), args); + return new JCDiagnostic(formatter, WARNING, true, source, pos, qualify(WARNING, key), args); } /** @@ -109,7 +108,7 @@ public class JCDiagnostic implements Diagnostic { */ public JCDiagnostic warning( DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) { - return new JCDiagnostic(messages, WARNING, false, source, pos, qualify(WARNING, key), args); + return new JCDiagnostic(formatter, WARNING, false, source, pos, qualify(WARNING, key), args); } /** @@ -119,7 +118,7 @@ public class JCDiagnostic implements Diagnostic { * @see MandatoryWarningHandler */ public JCDiagnostic mandatoryNote(DiagnosticSource source, String key, Object... args) { - return new JCDiagnostic(messages, NOTE, true, source, null, qualify(NOTE, key), args); + return new JCDiagnostic(formatter, NOTE, true, source, null, qualify(NOTE, key), args); } /** @@ -140,7 +139,7 @@ public class JCDiagnostic implements Diagnostic { */ public JCDiagnostic note( DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) { - return new JCDiagnostic(messages, NOTE, false, source, pos, qualify(NOTE, key), args); + return new JCDiagnostic(formatter, NOTE, false, source, pos, qualify(NOTE, key), args); } /** @@ -149,7 +148,7 @@ public class JCDiagnostic implements Diagnostic { * @param args Fields of the error message. */ public JCDiagnostic fragment(String key, Object... args) { - return new JCDiagnostic(messages, FRAGMENT, false, null, null, qualify(FRAGMENT, key), args); + return new JCDiagnostic(formatter, FRAGMENT, false, null, null, qualify(FRAGMENT, key), args); } protected String qualify(DiagnosticType t, String key) { @@ -163,10 +162,11 @@ public class JCDiagnostic implements Diagnostic { * Create a fragment diagnostic, for use as an argument in other diagnostics * @param key The key for the localized error message. * @param args Fields of the error message. + * */ - // should be deprecated + @Deprecated public static JCDiagnostic fragment(String key, Object... args) { - return new JCDiagnostic(Messages.getDefaultMessages(), + return new JCDiagnostic(getFragmentFormatter(), FRAGMENT, false, null, @@ -174,6 +174,14 @@ public class JCDiagnostic implements Diagnostic { "compiler." + FRAGMENT.key + "." + key, args); } + //where + @Deprecated + public static DiagnosticFormatter getFragmentFormatter() { + if (fragmentFormatter == null) { + fragmentFormatter = new BasicDiagnosticFormatter(Messages.getDefaultMessages()); + } + return fragmentFormatter; + } /** * A DiagnosticType defines the type of the diagnostic. @@ -247,7 +255,6 @@ public class JCDiagnostic implements Diagnostic { private final int pos; } - private final Messages messages; private final DiagnosticType type; private final DiagnosticSource source; private final DiagnosticPosition position; @@ -266,7 +273,7 @@ public class JCDiagnostic implements Diagnostic { * @param key a resource key to identify the text of the diagnostic * @param args arguments to be included in the text of the diagnostic */ - protected JCDiagnostic(Messages messages, + protected JCDiagnostic(DiagnosticFormatter formatter, DiagnosticType dt, boolean mandatory, DiagnosticSource source, @@ -276,7 +283,7 @@ public class JCDiagnostic implements Diagnostic { if (source == null && pos != null && pos.getPreferredPosition() != Position.NOPOS) throw new IllegalArgumentException(); - this.messages = messages; + this.defaultFormatter = formatter; this.type = dt; this.mandatory = mandatory; this.source = source; @@ -398,25 +405,19 @@ public class JCDiagnostic implements Diagnostic { * @return the prefix string associated with a particular type of diagnostic */ public String getPrefix(DiagnosticType dt) { - return getFormatter().formatKind(this, Locale.getDefault()); + return defaultFormatter.formatKind(this, Locale.getDefault()); } - private DiagnosticFormatter getFormatter() { - if (defaultFormatter == null) { - defaultFormatter = new BasicDiagnosticFormatter(messages); - } - return defaultFormatter; - } - - /** * Return the standard presentation of this diagnostic. */ public String toString() { - return getFormatter().format(this,Locale.getDefault()); + return defaultFormatter.format(this,Locale.getDefault()); } - private static DiagnosticFormatter defaultFormatter; + private DiagnosticFormatter defaultFormatter; + @Deprecated + private static DiagnosticFormatter fragmentFormatter; // Methods for javax.tools.Diagnostic @@ -440,6 +441,6 @@ public class JCDiagnostic implements Diagnostic { public String getMessage(Locale locale) { // RFE 6406133: JCDiagnostic.getMessage ignores locale argument - return getFormatter().formatMessage(this, locale); + return defaultFormatter.formatMessage(this, locale); } } From 1788cb3419ab308b0f732e8d6d4c072ea0a794ad Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Tue, 5 Aug 2008 17:07:13 -0700 Subject: [PATCH 28/52] 6733995: legal notice repair on langtools/src/share/classes/com/sun/tools/javap/JavapTask.java Reviewed-by: ksrini --- langtools/src/share/classes/com/sun/tools/javap/JavapTask.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java index 10f34846e53..781eaba566d 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java +++ b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java @@ -16,7 +16,7 @@ * * 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-15301 USA. + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or From b267c3b746281432a910c12e55627139238abe6a Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Fri, 8 Aug 2008 15:16:25 +0100 Subject: [PATCH 29/52] 6695838: javac does not detect cyclic inheritance involving static inner classes after import clause Javac fails to detect some errors due to the order in which a class' static imports are entered Reviewed-by: jjg --- .../com/sun/tools/javac/comp/MemberEnter.java | 6 ++-- .../javac/staticImport/6695838/T6695838.java | 31 +++++++++++++++++++ .../javac/staticImport/6695838/a/Foo.java | 29 +++++++++++++++++ .../staticImport/6695838/a/FooInterface.java | 29 +++++++++++++++++ 4 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 langtools/test/tools/javac/staticImport/6695838/T6695838.java create mode 100644 langtools/test/tools/javac/staticImport/6695838/a/Foo.java create mode 100644 langtools/test/tools/javac/staticImport/6695838/a/FooInterface.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java index cc3336872d9..b9e73fa1821 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -828,6 +828,9 @@ public class MemberEnter extends JCTree.Visitor implements Completer { // Save class environment for later member enter (2) processing. halfcompleted.append(env); + // Mark class as not yet attributed. + c.flags_field |= UNATTRIBUTED; + // If this is a toplevel-class, make sure any preceding import // clauses have been seen. if (c.owner.kind == PCK) { @@ -835,9 +838,6 @@ public class MemberEnter extends JCTree.Visitor implements Completer { todo.append(env); } - // Mark class as not yet attributed. - c.flags_field |= UNATTRIBUTED; - if (c.owner.kind == TYP) c.owner.complete(); diff --git a/langtools/test/tools/javac/staticImport/6695838/T6695838.java b/langtools/test/tools/javac/staticImport/6695838/T6695838.java new file mode 100644 index 00000000000..6fe824c4bfa --- /dev/null +++ b/langtools/test/tools/javac/staticImport/6695838/T6695838.java @@ -0,0 +1,31 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6695838 + * @summary javac does not detect cyclic inheritance involving static inner classes after import clause + * @author Maurizio Cimadamore + * + * @compile/fail a/FooInterface.java + */ diff --git a/langtools/test/tools/javac/staticImport/6695838/a/Foo.java b/langtools/test/tools/javac/staticImport/6695838/a/Foo.java new file mode 100644 index 00000000000..f021bef9d9e --- /dev/null +++ b/langtools/test/tools/javac/staticImport/6695838/a/Foo.java @@ -0,0 +1,29 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package a; + +class Foo implements FooInterface { + public static interface InnerInterface {} +} + diff --git a/langtools/test/tools/javac/staticImport/6695838/a/FooInterface.java b/langtools/test/tools/javac/staticImport/6695838/a/FooInterface.java new file mode 100644 index 00000000000..a01efe610c4 --- /dev/null +++ b/langtools/test/tools/javac/staticImport/6695838/a/FooInterface.java @@ -0,0 +1,29 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package a; + +import a.Foo.InnerInterface; + +public interface FooInterface extends Foo.InnerInterface {} + From fe12031643d78d2fa1e1e330b6ac7df820c601c0 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Fri, 8 Aug 2008 17:38:20 +0100 Subject: [PATCH 30/52] 6718364: inference fails when a generic method is invoked with raw arguments Bug in the implementation of Types.isSubtypeUnchecked Reviewed-by: jjg --- .../com/sun/tools/javac/code/Types.java | 5 +++ .../generics/inference/6718364/T6718364.java | 38 +++++++++++++++++++ .../generics/inference/6718364/T6718364.out | 3 ++ 3 files changed, 46 insertions(+) create mode 100644 langtools/test/tools/javac/generics/inference/6718364/T6718364.java create mode 100644 langtools/test/tools/javac/generics/inference/6718364/T6718364.out diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java index 36a605d5eb1..95a94f567da 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java @@ -305,6 +305,11 @@ public class Types { else if (t.tag == TYPEVAR) { return isSubtypeUnchecked(t.getUpperBound(), s, warn); } + else if (s.tag == UNDETVAR) { + UndetVar uv = (UndetVar)s; + if (uv.inst != null) + return isSubtypeUnchecked(t, uv.inst, warn); + } else if (!s.isRaw()) { Type t2 = asSuper(t, s.tsym); if (t2 != null && t2.isRaw()) { diff --git a/langtools/test/tools/javac/generics/inference/6718364/T6718364.java b/langtools/test/tools/javac/generics/inference/6718364/T6718364.java new file mode 100644 index 00000000000..7f275ce76a7 --- /dev/null +++ b/langtools/test/tools/javac/generics/inference/6718364/T6718364.java @@ -0,0 +1,38 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6718364 + * @summary inference fails when a generic method is invoked with raw arguments + * @compile/ref=T6718364.out -XDstdout -XDrawDiagnostics -Xlint:unchecked T6718364.java + */ +class T6718364 { + class X {} + + public void m(X x, T t) {} + + public void test() { + m(new X>(), new X()); + } +} diff --git a/langtools/test/tools/javac/generics/inference/6718364/T6718364.out b/langtools/test/tools/javac/generics/inference/6718364/T6718364.out new file mode 100644 index 00000000000..4453ec98ec7 --- /dev/null +++ b/langtools/test/tools/javac/generics/inference/6718364/T6718364.out @@ -0,0 +1,3 @@ +T6718364.java:36:32: compiler.warn.prob.found.req: (- compiler.misc.unchecked.assign), T6718364.X, T6718364.X +T6718364.java:36:10: compiler.warn.unchecked.meth.invocation.applied: m(T6718364.X,T), T6718364, , T6718364.X>,T6718364.X +2 warnings \ No newline at end of file From a7cdf3468537cc6ce8dbbf4be099b3f8c5e8cb37 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Fri, 8 Aug 2008 17:43:24 +0100 Subject: [PATCH 31/52] 6676362: Spurious forward reference error with final var + instance variable initializer Some javac forward reference errors aren't compliant with the JLS Reviewed-by: jjg --- .../com/sun/tools/javac/code/Symbol.java | 7 ---- .../com/sun/tools/javac/comp/Attr.java | 12 +++---- .../com/sun/tools/javac/comp/AttrContext.java | 6 ++++ .../com/sun/tools/javac/comp/MemberEnter.java | 7 ++-- .../tools/javac/resources/compiler.properties | 4 +++ .../javac/ForwardReference/T6676362a.java | 36 +++++++++++++++++++ .../javac/ForwardReference/T6676362b.java | 36 +++++++++++++++++++ .../tools/javac/enum/forwardRef/T6425594.out | 2 +- 8 files changed, 94 insertions(+), 16 deletions(-) create mode 100644 langtools/test/tools/javac/ForwardReference/T6676362a.java create mode 100644 langtools/test/tools/javac/ForwardReference/T6676362b.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java index d3e3c0f2433..fdd58b6ee4a 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java @@ -923,14 +923,7 @@ public abstract class Symbol implements Element { public Object call() { JavaFileObject source = log.useSource(env.toplevel.sourcefile); try { - // In order to catch self-references, we set - // the variable's declaration position to - // maximal possible value, effectively marking - // the variable as undefined. - int pos = VarSymbol.this.pos; - VarSymbol.this.pos = Position.MAXPOS; Type itype = attr.attribExpr(initializer, env, type); - VarSymbol.this.pos = pos; if (itype.constValue() != null) return attr.coerce(itype, type).constValue(); else diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index bb999149cc6..5ed19598a00 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -730,9 +730,8 @@ public class Attr extends JCTree.Visitor { // In order to catch self-references, we set the variable's // declaration position to maximal possible value, effectively // marking the variable as undefined. - v.pos = Position.MAXPOS; + initEnv.info.enclVar = v; attribExpr(tree.init, initEnv, v.type); - v.pos = tree.pos; } } result = tree.type = v.type; @@ -2198,18 +2197,19 @@ public class Attr extends JCTree.Visitor { // This check applies only to class and instance // variables. Local variables follow different scope rules, // and are subject to definite assignment checking. - if (v.pos > tree.pos && + if ((env.info.enclVar == v || v.pos > tree.pos) && v.owner.kind == TYP && canOwnInitializer(env.info.scope.owner) && v.owner == env.info.scope.owner.enclClass() && ((v.flags() & STATIC) != 0) == Resolve.isStatic(env) && (env.tree.getTag() != JCTree.ASSIGN || TreeInfo.skipParens(((JCAssign) env.tree).lhs) != tree)) { - + String suffix = (env.info.enclVar == v) ? + "self.ref" : "forward.ref"; if (!onlyWarning || isStaticEnumField(v)) { - log.error(tree.pos(), "illegal.forward.ref"); + log.error(tree.pos(), "illegal." + suffix); } else if (useBeforeDeclarationWarning) { - log.warning(tree.pos(), "forward.ref", v); + log.warning(tree.pos(), suffix, v); } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java b/langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java index 2f6b013aef0..84a13aeaa83 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java @@ -66,6 +66,11 @@ public class AttrContext { */ Lint lint; + /** The variable whose initializer is being attributed + * useful for detecting self-references in variable initializers + */ + Symbol enclVar = null; + /** Duplicate this context, replacing scope field and copying all others. */ AttrContext dup(Scope scope) { @@ -77,6 +82,7 @@ public class AttrContext { info.varArgs = varArgs; info.tvars = tvars; info.lint = lint; + info.enclVar = enclVar; return info; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java index b9e73fa1821..5cc3b792a07 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -627,8 +627,11 @@ public class MemberEnter extends JCTree.Visitor implements Completer { tree.sym = v; if (tree.init != null) { v.flags_field |= HASINIT; - if ((v.flags_field & FINAL) != 0 && tree.init.getTag() != JCTree.NEWCLASS) - v.setLazyConstValue(initEnv(tree, env), log, attr, tree.init); + if ((v.flags_field & FINAL) != 0 && tree.init.getTag() != JCTree.NEWCLASS) { + Env initEnv = getInitEnv(tree, env); + initEnv.info.enclVar = v; + v.setLazyConstValue(initEnv(tree, initEnv), log, attr, tree.init); + } } if (chk.checkUnique(tree.pos(), v, enclScope)) { chk.checkTransparentVar(tree.pos(), v, enclScope); diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties index 1d631592c81..a80253a681f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -200,6 +200,10 @@ compiler.err.illegal.forward.ref=\ illegal forward reference compiler.warn.forward.ref=\ reference to variable ''{0}'' before it has been initialized +compiler.err.illegal.self.ref=\ + self-reference in initializer +compiler.warn.self.ref=\ + self-reference in initializer of variable ''{0}'' compiler.err.illegal.generic.type.for.instof=\ illegal generic type for instanceof compiler.err.illegal.initializer.for.type=\ diff --git a/langtools/test/tools/javac/ForwardReference/T6676362a.java b/langtools/test/tools/javac/ForwardReference/T6676362a.java new file mode 100644 index 00000000000..674acb45785 --- /dev/null +++ b/langtools/test/tools/javac/ForwardReference/T6676362a.java @@ -0,0 +1,36 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6676362 + * @summary Spurious forward reference error with final var + instance variable initializer + * @author Maurizio Cimadamore + * + * @compile T6676362a.java + */ + +public class T6676362a { + Object o = new Object() {Object m() {return o2;}}; + final Object o2 = o; +} diff --git a/langtools/test/tools/javac/ForwardReference/T6676362b.java b/langtools/test/tools/javac/ForwardReference/T6676362b.java new file mode 100644 index 00000000000..df0deb4feb9 --- /dev/null +++ b/langtools/test/tools/javac/ForwardReference/T6676362b.java @@ -0,0 +1,36 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6676362 + * @summary Spurious forward reference error with final var + instance variable initializer + * @author Maurizio Cimadamore + * + * @compile T6676362b.java + */ + +public class T6676362b { + static final int i1 = T6676362b.i2; //legal - usage is not via simple name + static final int i2 = i1; +} diff --git a/langtools/test/tools/javac/enum/forwardRef/T6425594.out b/langtools/test/tools/javac/enum/forwardRef/T6425594.out index cd3ccb7e3f5..554493e0cd3 100644 --- a/langtools/test/tools/javac/enum/forwardRef/T6425594.out +++ b/langtools/test/tools/javac/enum/forwardRef/T6425594.out @@ -1,4 +1,4 @@ -T6425594.java:10:28: compiler.warn.forward.ref: x +T6425594.java:10:28: compiler.warn.self.ref: x T6425594.java:11:26: compiler.err.illegal.forward.ref 1 error 1 warning From 054a64704adf508cfae55863b4c07c93b8812d15 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Fri, 8 Aug 2008 17:48:04 +0100 Subject: [PATCH 32/52] 6734819: Javac performs flows analysis on already translated classes Regression in JavaCompiler.desugar introduced in 6726015 Reviewed-by: jjg --- .../sun/tools/javac/main/JavaCompiler.java | 14 +++++-- .../test/tools/javac/6734819/T6734819a.java | 39 ++++++++++++++++++ .../test/tools/javac/6734819/T6734819a.out | 12 ++++++ .../test/tools/javac/6734819/T6734819b.java | 35 ++++++++++++++++ .../test/tools/javac/6734819/T6734819b.out | 9 +++++ .../test/tools/javac/6734819/T6734819c.java | 40 +++++++++++++++++++ .../test/tools/javac/6734819/T6734819c.out | 8 ++++ 7 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 langtools/test/tools/javac/6734819/T6734819a.java create mode 100644 langtools/test/tools/javac/6734819/T6734819a.out create mode 100644 langtools/test/tools/javac/6734819/T6734819b.java create mode 100644 langtools/test/tools/javac/6734819/T6734819b.out create mode 100644 langtools/test/tools/javac/6734819/T6734819c.java create mode 100644 langtools/test/tools/javac/6734819/T6734819c.out diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java index 1ab7c1096e0..b116981ce09 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java +++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java @@ -27,6 +27,7 @@ package com.sun.tools.javac.main; import java.io.*; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.LinkedHashMap; import java.util.Map; import java.util.MissingResourceException; @@ -1185,14 +1186,16 @@ public class JavaCompiler implements ClassReader.SourceCompleter { * are processed through attribute and flow before subtypes are translated. */ class ScanNested extends TreeScanner { - Set> dependencies = new HashSet>(); + Set> dependencies = new LinkedHashSet>(); public void visitClassDef(JCClassDecl node) { Type st = types.supertype(node.sym.type); if (st.tag == TypeTags.CLASS) { ClassSymbol c = st.tsym.outermostClass(); Env stEnv = enter.getEnv(c); - if (stEnv != null && env != stEnv) - dependencies.add(stEnv); + if (stEnv != null && env != stEnv) { + if (dependencies.add(stEnv)) + scan(stEnv.tree); + } } super.visitClassDef(node); } @@ -1204,6 +1207,11 @@ public class JavaCompiler implements ClassReader.SourceCompleter { flow(attribute(dep)); } + //We need to check for error another time as more classes might + //have been attributed and analyzed at this stage + if (errorCount() > 0) + return; + if (verboseCompilePolicy) log.printLines(log.noticeWriter, "[desugar " + env.enclClass.sym + "]"); diff --git a/langtools/test/tools/javac/6734819/T6734819a.java b/langtools/test/tools/javac/6734819/T6734819a.java new file mode 100644 index 00000000000..f0df5a6b230 --- /dev/null +++ b/langtools/test/tools/javac/6734819/T6734819a.java @@ -0,0 +1,39 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6734819 + * @summary Javac performs flows analysis on already translated classes + * @author Maurizio Cimadamore + * + * @compile/ref=T6734819a.out -XDrawDiagnostics -Xlint:all -XDverboseCompilePolicy T6734819a.java + */ +class Y extends W {} +class W extends Z {} + +class Z { + void m(Z z) { + W w = (W)z; + } +} diff --git a/langtools/test/tools/javac/6734819/T6734819a.out b/langtools/test/tools/javac/6734819/T6734819a.out new file mode 100644 index 00000000000..73437aee829 --- /dev/null +++ b/langtools/test/tools/javac/6734819/T6734819a.out @@ -0,0 +1,12 @@ +[attribute Y] +[flow Y] +[attribute W] +[flow W] +[attribute Z] +[flow Z] +[desugar Y] +[generate code Y] +[desugar W] +[generate code W] +[desugar Z] +[generate code Z] diff --git a/langtools/test/tools/javac/6734819/T6734819b.java b/langtools/test/tools/javac/6734819/T6734819b.java new file mode 100644 index 00000000000..706375d503e --- /dev/null +++ b/langtools/test/tools/javac/6734819/T6734819b.java @@ -0,0 +1,35 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6734819 + * @summary Javac performs flows analysis on already translated classes + * @author Maurizio Cimadamore + * + * @compile/ref=T6734819b.out -XDrawDiagnostics -Xlint:all -XDverboseCompilePolicy T6734819b.java + */ +class A extends B {} +class B { + class C extends B {} +} diff --git a/langtools/test/tools/javac/6734819/T6734819b.out b/langtools/test/tools/javac/6734819/T6734819b.out new file mode 100644 index 00000000000..4b25a08e3d1 --- /dev/null +++ b/langtools/test/tools/javac/6734819/T6734819b.out @@ -0,0 +1,9 @@ +[attribute A] +[flow A] +[attribute B] +[flow B] +[desugar A] +[generate code A] +[desugar B] +[generate code B] +[generate code B] diff --git a/langtools/test/tools/javac/6734819/T6734819c.java b/langtools/test/tools/javac/6734819/T6734819c.java new file mode 100644 index 00000000000..c6a990bd3ee --- /dev/null +++ b/langtools/test/tools/javac/6734819/T6734819c.java @@ -0,0 +1,40 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6734819 + * @summary Javac performs flows analysis on already translated classes + * @author Maurizio Cimadamore + * + * @compile/fail/ref=T6734819c.out -XDrawDiagnostics -Xlint:all -XDverboseCompilePolicy T6734819c.java + */ +class Y extends W {} +class W extends Z {} + +class Z { + void m(Z z) { + return; + W w = (W)z; + } +} diff --git a/langtools/test/tools/javac/6734819/T6734819c.out b/langtools/test/tools/javac/6734819/T6734819c.out new file mode 100644 index 00000000000..92a10219774 --- /dev/null +++ b/langtools/test/tools/javac/6734819/T6734819c.out @@ -0,0 +1,8 @@ +[attribute Y] +[flow Y] +[attribute W] +[flow W] +[attribute Z] +[flow Z] +T6734819c.java:38:11: compiler.err.unreachable.stmt +1 error From c448d362ba7936750e761722fcb273c7e35daea7 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Fri, 8 Aug 2008 17:52:02 +0100 Subject: [PATCH 33/52] 6732461: broken message file for annotation processing Regression in sqe test introduced in 6720185 Reviewed-by: jjg --- langtools/src/share/classes/com/sun/tools/apt/util/Bark.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langtools/src/share/classes/com/sun/tools/apt/util/Bark.java b/langtools/src/share/classes/com/sun/tools/apt/util/Bark.java index 14dfa83633f..4246072d4ea 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/util/Bark.java +++ b/langtools/src/share/classes/com/sun/tools/apt/util/Bark.java @@ -87,7 +87,7 @@ public class Bark extends Log { context.put(barkKey, this); // register additional resource bundle for APT messages. - Messages aptMessages = new Messages(Messages.getDefaultBundle()); + Messages aptMessages = Messages.instance(context); aptMessages.add("com.sun.tools.apt.resources.apt"); aptDiags = new JCDiagnostic.Factory(aptMessages, "apt"); From 6144fe8e3ebd8d5696eff3a2087c17ee65ea4a97 Mon Sep 17 00:00:00 2001 From: Erik Trimble Date: Sun, 10 Aug 2008 21:58:54 -0700 Subject: [PATCH 34/52] 6735720: Bump the HS14 build number to 03 Update Hotspot 14 build number to 03 Reviewed-by: jcoomes --- hotspot/make/hotspot_version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version index b30abbb8928..4ec4a92ff7a 100644 --- a/hotspot/make/hotspot_version +++ b/hotspot/make/hotspot_version @@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2008 HS_MAJOR_VER=14 HS_MINOR_VER=0 -HS_BUILD_NUMBER=01 +HS_BUILD_NUMBER=03 JDK_MAJOR_VER=1 JDK_MINOR_VER=7 From 14b6adc7829e8b7f81cc093686c268229fad5a9e Mon Sep 17 00:00:00 2001 From: Swamy Venkataramanappa Date: Tue, 12 Aug 2008 12:44:22 -0700 Subject: [PATCH 35/52] 6718125: SA: jmap prints negative size for MaxNewHeap Fixed printing of negative value for MaxNewHeap. Reviewed-by: jjh --- .../share/classes/sun/jvm/hotspot/tools/HeapSummary.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java index 039fc37e027..e50b6b2d089 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java @@ -193,8 +193,12 @@ public class HeapSummary extends Tool { private static final double FACTOR = 1024*1024; private void printValMB(String title, long value) { - double mb = value / FACTOR; - System.out.println(alignment + title + value + " (" + mb + "MB)"); + if (value < 0) { + System.out.println(alignment + title + (value >>> 20) + " MB"); + } else { + double mb = value/FACTOR; + System.out.println(alignment + title + value + " (" + mb + "MB)"); + } } private void printValue(String title, long value) { From f60907fd0a77825d0ff76f59069ab892d29a094d Mon Sep 17 00:00:00 2001 From: Keith McGuigan Date: Wed, 13 Aug 2008 08:56:44 -0400 Subject: [PATCH 36/52] 6736718: more copyright headers wrong Changed license headers to GPL Reviewed-by: tonyp, rasbold --- hotspot/make/hotspot_distro | 24 +++++++++++++++--- hotspot/test/compiler/6646019/Test.java | 32 ++++++++++++------------ hotspot/test/compiler/6689060/Test.java | 33 ++++++++++++------------- hotspot/test/compiler/6695810/Test.java | 33 ++++++++++++------------- 4 files changed, 69 insertions(+), 53 deletions(-) diff --git a/hotspot/make/hotspot_distro b/hotspot/make/hotspot_distro index bae47300e58..ab698d37c4e 100644 --- a/hotspot/make/hotspot_distro +++ b/hotspot/make/hotspot_distro @@ -1,6 +1,24 @@ -# -# Copyright 2006-2008 Sun Microsystems, Inc. All rights reserved. -# SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. +# +# Copyright 2006-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. # # diff --git a/hotspot/test/compiler/6646019/Test.java b/hotspot/test/compiler/6646019/Test.java index e724394ff57..f28d0a05036 100644 --- a/hotspot/test/compiler/6646019/Test.java +++ b/hotspot/test/compiler/6646019/Test.java @@ -1,24 +1,24 @@ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. */ /* diff --git a/hotspot/test/compiler/6689060/Test.java b/hotspot/test/compiler/6689060/Test.java index f6361aee067..ba42667a815 100644 --- a/hotspot/test/compiler/6689060/Test.java +++ b/hotspot/test/compiler/6689060/Test.java @@ -1,25 +1,24 @@ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. */ /* diff --git a/hotspot/test/compiler/6695810/Test.java b/hotspot/test/compiler/6695810/Test.java index 77297671082..a8f2ea0c80e 100644 --- a/hotspot/test/compiler/6695810/Test.java +++ b/hotspot/test/compiler/6695810/Test.java @@ -1,25 +1,24 @@ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. */ /* From 109504ddc4cb9ba1cc540e95dd5d04e07f1fddd3 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 14 Aug 2008 09:26:18 -0700 Subject: [PATCH 37/52] Added tag jdk7-b33 for changeset 05b15a2aeaaf --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 68910f18724..f3da47b8cc1 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -7,3 +7,4 @@ cbc8ad9dd0e085a607427ea35411990982f19a36 jdk7-b25 2dab2f712e1832c92acfa63ec0337048b9422c20 jdk7-b30 3300a35a0bd56d695b92fe0b34f03ebbfc939064 jdk7-b31 64da805be725721bf2004e7409a0d7a16fc8ddbc jdk7-b32 +bb1ef4ee3d2c8cbf43a37d372325a7952be590b9 jdk7-b33 From 948cea9d3fda503c4f882bbfe9b872566ad708a3 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 14 Aug 2008 09:26:19 -0700 Subject: [PATCH 38/52] Added tag jdk7-b33 for changeset d958f883b42a --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index 69c0bcdfe96..88de55dd33b 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -7,3 +7,4 @@ e84e9018bebbf3e5bafc5706e7882a15cb1c7d99 jdk7-b27 c0252adbb2abbfdd6c35595429ac6fbdd98e20ac jdk7-b30 ef6af34d75a7b44e77083f1d4ee47631fa09d3b4 jdk7-b31 80a0f46a6203e727012bd579fe38a609b83decce jdk7-b32 +6a5b9d2f8b20de54e3bfe33cd12bd0793caedc4e jdk7-b33 From 932d8f3242a00e04b42f0865c97c1fe7f80133aa Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 14 Aug 2008 09:26:23 -0700 Subject: [PATCH 39/52] Added tag jdk7-b33 for changeset 58918025243a --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 9bcabb24f88..fbe09df39c2 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -7,3 +7,4 @@ c14dab40ed9bf45ad21150bd70c9c80cdf655415 jdk7-b28 d1605aabd0a15ecf93787c47de63073c33fba52d jdk7-b30 9c2ecc2ffb125f14fab3857fe7689598956348a0 jdk7-b31 b727c32788a906c04839516ae7443a085185a300 jdk7-b32 +585535ec8a14adafa6bfea65d6975e29094c8cec jdk7-b33 From 6b67fc83409437c80bc9cb3e987cc4304990f4ab Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 14 Aug 2008 09:26:27 -0700 Subject: [PATCH 40/52] Added tag jdk7-b33 for changeset f0165b195228 --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index 6cedbe49ef7..3773ca1e2d4 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -7,3 +7,4 @@ b996318955c0ad8e9fa0ffb56c74f626786e863f jdk7-b28 2d94a238a1641d074e6032dcdceed461d6f85d6a jdk7-b30 255d64ee287e926e8629dd80bc67690e65eeba30 jdk7-b31 400a5ee432cc2db9031e06852ddde9264a192b48 jdk7-b32 +95375835527f0bf06124ce984266e2ad5de8a6dc jdk7-b33 From 1e09fae226efa55c062f67bff2744f7fbf0efc6f Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 14 Aug 2008 09:26:29 -0700 Subject: [PATCH 41/52] Added tag jdk7-b33 for changeset 31ff14943017 --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 38c456579f0..db69f05ef33 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -7,3 +7,4 @@ eefcd5204500a11d6aa802dca9f961cf10ab64c2 jdk7-b28 7f2466f8cc7009702e548d1a763254f546024d7e jdk7-b30 f978623825364a2ad9c6f51d02fc9424a8b0bc86 jdk7-b31 e6daca2eced9d84b01255cabcfcc49164c26405e jdk7-b32 +6dcbcfb9551aaa2a80906c28ab48c9a8564e0e64 jdk7-b33 From 2a6a483ba0eba7f0fc1c0603fff9a301fed9bab9 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 14 Aug 2008 09:26:42 -0700 Subject: [PATCH 42/52] Added tag jdk7-b33 for changeset e1305f648e12 --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index a8bc8a95dca..7f30f314bd3 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -7,3 +7,4 @@ dec081837b01d509dcc2b9de86a4299c1ec17e04 jdk7-b29 eaf608c64fecf70f955dc9f29f94c055b183aeec jdk7-b30 07c916ecfc71f6bf432e4ff09bfbfb6290b5703c jdk7-b31 13aee98cc0d8e24a084b62ad1d48d2a49792416c jdk7-b32 +0a5f04fb72825302a80a67c636a7ddc410ead266 jdk7-b33 From 0e04930c24e8f74e546a92249cdf872ffeb6fe23 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Thu, 14 Aug 2008 11:18:53 -0700 Subject: [PATCH 43/52] 6724668: Hotspot: Official change to Sun Studio 12 compilers on Solaris Moving to SS12. Builds with SS11 still work, the compiler comes from your PATH when building hotspot. Reviewed-by: tbell --- hotspot/make/jprt.config | 4 +--- hotspot/make/solaris/makefiles/sparcWorks.make | 7 ++----- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/hotspot/make/jprt.config b/hotspot/make/jprt.config index dd9940763c2..02fdbc0c51b 100644 --- a/hotspot/make/jprt.config +++ b/hotspot/make/jprt.config @@ -77,9 +77,7 @@ if [ "${osname}" = SunOS ] ; then # All jdk6 builds use SS11 compiler_name=SS11 else - # FIXUP: Change to SS12 once it has been validated. - #compiler_name=SS12 - compiler_name=SS11 + compiler_name=SS12 fi fi diff --git a/hotspot/make/solaris/makefiles/sparcWorks.make b/hotspot/make/solaris/makefiles/sparcWorks.make index 83ef29612ee..5bbe70f9f10 100644 --- a/hotspot/make/solaris/makefiles/sparcWorks.make +++ b/hotspot/make/solaris/makefiles/sparcWorks.make @@ -51,12 +51,9 @@ ifeq ($(JDK_MINOR_VERSION),6) VALIDATED_COMPILER_REV := 5.8 VALIDATED_C_COMPILER_REV := 5.8 else - # FIXUP: Change to SS12 (5.9) once it has been validated. # Validated compiler for JDK7 is SS12 (5.9) - #VALIDATED_COMPILER_REV := 5.9 - #VALIDATED_C_COMPILER_REV := 5.9 - VALIDATED_COMPILER_REV := 5.8 - VALIDATED_C_COMPILER_REV := 5.8 + VALIDATED_COMPILER_REV := 5.9 + VALIDATED_C_COMPILER_REV := 5.9 endif # Warning messages about not using the above validated version From 27a4da4686d39b1a22fd2a7b624f99b9cdd414eb Mon Sep 17 00:00:00 2001 From: Tomas Hurka Date: Thu, 14 Aug 2008 21:05:51 +0200 Subject: [PATCH 44/52] 6625846: Export system property java.version via jvmstat Java.version added to property_counters_ss array Reviewed-by: swamyv --- hotspot/src/share/vm/runtime/statSampler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/src/share/vm/runtime/statSampler.cpp b/hotspot/src/share/vm/runtime/statSampler.cpp index f7205b9e189..d5c4a5f4ffb 100644 --- a/hotspot/src/share/vm/runtime/statSampler.cpp +++ b/hotspot/src/share/vm/runtime/statSampler.cpp @@ -217,6 +217,7 @@ static const char* property_counters_ss[] = { "java.class.path", "java.endorsed.dirs", "java.ext.dirs", + "java.version", "java.home", NULL }; From 6ec4c76bb764d2e52d6ae9aa540af5fb76aaadde Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Thu, 14 Aug 2008 13:33:08 -0700 Subject: [PATCH 45/52] 6674227: Missing LICENSE file during build Just a JPRT usage issue. The top level files (like LICENSE) are needed to create the jdk image (j2sdk-image directory). Reviewed-by: tbell --- jdk/make/jprt.properties | 1 - 1 file changed, 1 deletion(-) diff --git a/jdk/make/jprt.properties b/jdk/make/jprt.properties index 06abef8c8e6..e6666cb1d6c 100644 --- a/jdk/make/jprt.properties +++ b/jdk/make/jprt.properties @@ -55,6 +55,5 @@ jprt.solaris_x64.build.platform.match32=solaris_i586_5.10 jprt.test.targets=*-*-*-jvm98 # Directories needed to build -jprt.bundle.src.dirs=make src jprt.bundle.exclude.src.dirs=build From 57dabb4fcbf70df6853069c45bdc19b7c85dee86 Mon Sep 17 00:00:00 2001 From: "Y. Srinivas Ramakrishna" Date: Thu, 14 Aug 2008 17:58:35 -0700 Subject: [PATCH 46/52] 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning When an object array overflows during precleaning, we should have been marking the entire array dirty, not just its first card. Reviewed-by: jmasa, poonam, tonyp --- .../concurrentMarkSweepGeneration.cpp | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp index 3f70a3ac771..697ce756825 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -6867,11 +6867,9 @@ void MarkFromRootsClosure::do_bit(size_t offset) { // during the preclean or remark phase. (CMSCleanOnEnter) if (CMSCleanOnEnter) { size_t sz = _collector->block_size_using_printezis_bits(addr); - HeapWord* start_card_addr = (HeapWord*)round_down( - (intptr_t)addr, CardTableModRefBS::card_size); HeapWord* end_card_addr = (HeapWord*)round_to( (intptr_t)(addr+sz), CardTableModRefBS::card_size); - MemRegion redirty_range = MemRegion(start_card_addr, end_card_addr); + MemRegion redirty_range = MemRegion(addr, end_card_addr); assert(!redirty_range.is_empty(), "Arithmetical tautology"); // Bump _threshold to end_card_addr; note that // _threshold cannot possibly exceed end_card_addr, anyhow. @@ -7460,12 +7458,25 @@ void PushAndMarkClosure::do_oop(oop obj) { ) if (simulate_overflow || !_mark_stack->push(obj)) { if (_concurrent_precleaning) { - // During precleaning we can just dirty the appropriate card + // During precleaning we can just dirty the appropriate card(s) // in the mod union table, thus ensuring that the object remains - // in the grey set and continue. Note that no one can be intefering - // with us in this action of dirtying the mod union table, so - // no locking is required. - _mod_union_table->mark(addr); + // in the grey set and continue. In the case of object arrays + // we need to dirty all of the cards that the object spans, + // since the rescan of object arrays will be limited to the + // dirty cards. + // Note that no one can be intefering with us in this action + // of dirtying the mod union table, so no locking or atomics + // are required. + if (obj->is_objArray()) { + size_t sz = obj->size(); + HeapWord* end_card_addr = (HeapWord*)round_to( + (intptr_t)(addr+sz), CardTableModRefBS::card_size); + MemRegion redirty_range = MemRegion(addr, end_card_addr); + assert(!redirty_range.is_empty(), "Arithmetical tautology"); + _mod_union_table->mark_range(redirty_range); + } else { + _mod_union_table->mark(addr); + } _collector->_ser_pmc_preclean_ovflw++; } else { // During the remark phase, we need to remember this oop From bf2763ee4e149581a996c0d18e5d0242750aeff5 Mon Sep 17 00:00:00 2001 From: Xiaobin Lu Date: Fri, 15 Aug 2008 10:08:20 -0700 Subject: [PATCH 47/52] 6608862: segv in JvmtiEnvBase::check_for_periodic_clean_up() Reviewed-by: dholmes, dcubed, jcoomes --- hotspot/src/share/vm/runtime/thread.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index 85919814bee..5a09f774b62 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -2756,7 +2756,13 @@ void Threads::threads_do(ThreadClosure* tc) { // For now, just manually iterate through them. tc->do_thread(VMThread::vm_thread()); Universe::heap()->gc_threads_do(tc); - tc->do_thread(WatcherThread::watcher_thread()); + { + // Grab the Terminator_lock to prevent watcher_thread from being terminated. + MutexLockerEx mu(Terminator_lock, Mutex::_no_safepoint_check_flag); + WatcherThread *wt = WatcherThread::watcher_thread(); + if (wt != NULL) + tc->do_thread(wt); + } // If CompilerThreads ever become non-JavaThreads, add them here } From 179908ef64bf185bdddd4cfafd0b18af3af7d073 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Sun, 17 Aug 2008 09:56:25 -0700 Subject: [PATCH 48/52] 6737659: debug bundles are empty Build order issue with debug build, caused final debug bundle to be empty. Reviewed-by: tbell --- Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4181e29b9c4..54e5a256873 100644 --- a/Makefile +++ b/Makefile @@ -74,7 +74,7 @@ include ./make/deploy-rules.gmk all:: @$(START_ECHO) -all:: openjdk_check sanity all_product_build +all:: openjdk_check sanity ifeq ($(SKIP_FASTDEBUG_BUILD), false) all:: fastdebug_build @@ -88,6 +88,8 @@ ifneq ($(SKIP_OPENJDK_BUILD), true) all:: openjdk_build endif +all:: all_product_build + all:: @$(FINISH_ECHO) From cf5e518affdb0f026ee30f6f02d2e7a8b4ae0267 Mon Sep 17 00:00:00 2001 From: Xiaobin Lu Date: Mon, 18 Aug 2008 14:53:36 -0700 Subject: [PATCH 49/52] 6459085: naked pointer subtractions in class data sharing code Reviewed-by: jcoomes --- hotspot/make/linux/makefiles/vm.make | 2 +- hotspot/src/share/vm/memory/dump.cpp | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/hotspot/make/linux/makefiles/vm.make b/hotspot/make/linux/makefiles/vm.make index 73caaf9a534..dc09e17b6ca 100644 --- a/hotspot/make/linux/makefiles/vm.make +++ b/hotspot/make/linux/makefiles/vm.make @@ -195,7 +195,7 @@ $(LIBJVM): $(LIBJVM.o) $(LIBJVM_MAPFILE) $(LD_SCRIPT) if [ $$? = 0 ] ; then \ /usr/bin/chcon -t textrel_shlib_t $@; \ if [ $$? != 0 ]; then \ - echo "ERROR: Cannot chcon $@"; exit 1; \ + echo "ERROR: Cannot chcon $@"; \ fi \ fi \ fi \ diff --git a/hotspot/src/share/vm/memory/dump.cpp b/hotspot/src/share/vm/memory/dump.cpp index 0b088528270..a3d066df7dd 100644 --- a/hotspot/src/share/vm/memory/dump.cpp +++ b/hotspot/src/share/vm/memory/dump.cpp @@ -1200,10 +1200,12 @@ public: mapinfo->write_space(CompactingPermGenGen::rw, _rw_space, false); _rw_space->set_saved_mark(); mapinfo->write_region(CompactingPermGenGen::md, _md_vs->low(), - md_top - _md_vs->low(), SharedMiscDataSize, + pointer_delta(md_top, _md_vs->low(), sizeof(char)), + SharedMiscDataSize, false, false); mapinfo->write_region(CompactingPermGenGen::mc, _mc_vs->low(), - mc_top - _mc_vs->low(), SharedMiscCodeSize, + pointer_delta(mc_top, _mc_vs->low(), sizeof(char)), + SharedMiscCodeSize, true, true); // Pass 2 - write data. @@ -1212,10 +1214,12 @@ public: mapinfo->write_space(CompactingPermGenGen::ro, _ro_space, true); mapinfo->write_space(CompactingPermGenGen::rw, _rw_space, false); mapinfo->write_region(CompactingPermGenGen::md, _md_vs->low(), - md_top - _md_vs->low(), SharedMiscDataSize, + pointer_delta(md_top, _md_vs->low(), sizeof(char)), + SharedMiscDataSize, false, false); mapinfo->write_region(CompactingPermGenGen::mc, _mc_vs->low(), - mc_top - _mc_vs->low(), SharedMiscCodeSize, + pointer_delta(mc_top, _mc_vs->low(), sizeof(char)), + SharedMiscCodeSize, true, true); mapinfo->close(); From 731dd43ab4324229228e889c8e15e3652ac37423 Mon Sep 17 00:00:00 2001 From: Kumar Srinivasan Date: Tue, 19 Aug 2008 07:50:03 -0700 Subject: [PATCH 50/52] 6614210: JPRT Windows 32bit msival2 build failure when building 'install' workspace Suppresses wscript's modal dialog on error and no msi validation for jprt. Reviewed-by: ohair, jmelvin --- jdk/make/common/shared/Defs-windows.gmk | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/jdk/make/common/shared/Defs-windows.gmk b/jdk/make/common/shared/Defs-windows.gmk index 250604136bc..d0be243d8e1 100644 --- a/jdk/make/common/shared/Defs-windows.gmk +++ b/jdk/make/common/shared/Defs-windows.gmk @@ -539,6 +539,8 @@ else WSCRIPT :=$(call FileExists,$(_WSCRIPT1),$(_WSCRIPT2)) endif WSCRIPT:=$(call AltCheckSpaces,WSCRIPT) +# batch mode no modal dialogs on errors, please. +WSCRIPT += -B # CSCRIPT: path to cscript.exe (used in creating install bundles) ifdef ALT_CSCRIPT @@ -561,6 +563,10 @@ else MSIVAL2 :=$(call FileExists,$(_MSIVAL2_1),$(_MSIVAL2_2)) endif MSIVAL2:=$(call AltCheckSpaces,MSIVAL2) +# suppress msival2 checks, as it hangs jprt builds +ifdef SKIP_MSIVAL2 + MSIVAL2 := $(ECHO) +endif # LOGOCUB: path to cub file for (used in validating install msi files) ifdef ALT_LOGOCUB From 99ff6e5eb220dcd496f2b9b74cededd5993508c7 Mon Sep 17 00:00:00 2001 From: John Coomes Date: Wed, 27 Aug 2008 15:41:58 -0700 Subject: [PATCH 51/52] 6742207: jdk7 32-bit windows build failed running pack200 6730514 inadvertently disabled perm gen expansion; reenable Reviewed-by: ysr --- .../share/vm/memory/compactingPermGenGen.cpp | 24 ------------------- .../share/vm/memory/compactingPermGenGen.hpp | 2 -- 2 files changed, 26 deletions(-) diff --git a/hotspot/src/share/vm/memory/compactingPermGenGen.cpp b/hotspot/src/share/vm/memory/compactingPermGenGen.cpp index af94649ed89..e1de54e38e8 100644 --- a/hotspot/src/share/vm/memory/compactingPermGenGen.cpp +++ b/hotspot/src/share/vm/memory/compactingPermGenGen.cpp @@ -421,30 +421,6 @@ size_t CompactingPermGenGen::max_capacity() const { } - -bool CompactingPermGenGen::grow_by(size_t bytes) { - // Don't allow _virtual_size to expand into shared spaces. - size_t max_bytes = _virtual_space.uncommitted_size() - _shared_space_size; - if (bytes > _shared_space_size) { - bytes = _shared_space_size; - } - return OneContigSpaceCardGeneration::grow_by(bytes); -} - - -bool CompactingPermGenGen::grow_to_reserved() { - // Don't allow _virtual_size to expand into shared spaces. - bool success = false; - if (_virtual_space.uncommitted_size() > _shared_space_size) { - size_t remaining_bytes = - _virtual_space.uncommitted_size() - _shared_space_size; - success = OneContigSpaceCardGeneration::grow_by(remaining_bytes); - DEBUG_ONLY(if (!success) warning("grow to reserved failed");) - } - return success; -} - - // No young generation references, clear this generation's main space's // card table entries. Do NOT clear the card table entries for the // read-only space (always clear) or the read-write space (valuable diff --git a/hotspot/src/share/vm/memory/compactingPermGenGen.hpp b/hotspot/src/share/vm/memory/compactingPermGenGen.hpp index 4d76e473bde..3a12a8848de 100644 --- a/hotspot/src/share/vm/memory/compactingPermGenGen.hpp +++ b/hotspot/src/share/vm/memory/compactingPermGenGen.hpp @@ -183,8 +183,6 @@ public: void compact(); void post_compact(); size_t contiguous_available() const; - bool grow_by(size_t bytes); - virtual bool grow_to_reserved(); void clear_remembered_set(); void invalidate_remembered_set(); From 35b925db8ceffa684dd73ea9a2384af98875f06f Mon Sep 17 00:00:00 2001 From: "J. Duke" Date: Wed, 5 Jul 2017 16:39:59 +0200 Subject: [PATCH 52/52] Added tag jdk7-b33 for changeset 6838c1a3296a --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 8d69e26cb9f..14b040b0551 100644 --- a/.hgtags +++ b/.hgtags @@ -7,3 +7,4 @@ bfe4572fd301a6fcd120373cdb2eff5d2da0c72c jdk7-b29 bee4731164a06ddece1297ae58db24aca6a1c626 jdk7-b30 cd8b8f500face60d1566d850857a7fccadbd383a jdk7-b31 a9f1805e3ba9ca520cad199d522c84af5433e85a jdk7-b32 +6838c1a3296aaa3572364d2ce7d70826cee96286 jdk7-b33