From 696e17c0ba6b44d02c806a89ff537f09f4b7f925 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Thu, 3 Jul 2008 18:02:47 -0700 Subject: [PATCH 01/95] 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/95] 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/95] 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/95] 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/95] 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/95] 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/95] 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/95] 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/95] 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/95] 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/95] 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/95] 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/95] 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/95] 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/95] 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/95] 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/95] 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 zcmZ?wbhEHb6krfwxcZ;r|Ns974jlOY@&AeiJ8xfkIi+{$^a(4rtvk7J)~1ECHr~4Y z>dn)?_iwyUjxFwKo3m}*sS^k8Et|h%+xnB6*Bslt=IFc`>kjO?aAe<=*H8XVoiumO zv~{zltlqWx+_C+)kM6s*cKQA_%l0i_xa0oK4^QuZTfAURes=ANgZGZ^yS;Y#fi=ta zAJ}#E=B4-hc3fJs{J_!ux66v#wr}4a930Hc%gaCnS=tSM2bkeFE)6%A|*u4>>`879$85po!vP?3!R)77tQoAG-Ebo zn98HCCm^Sj;AEuCtSQXP#H*&R!`{YdB%vuH)5|M6Nn?r;ODykfULkqON}o7h?RC5w zf?0`EwPcs<5EPx_#NeT#!>=nD?8abV=xLbk&B$>6!j`j_866p{@%aSP{p|A_7@L|~ zTAO@2I=ea<+CAKz9G&@icx`RueR>&vJdM2A)RdHzS%m~=wL2MDuqv^#s&WXjteoR* zA)wAK!K%W+qP@+>PC!r6WS=6djOk$qJ+r+kr?pK*58LZXXzybc7vYyW?4~2UoQccS zTwnUIg1C^FCbtHszO~_Dx#h;|)?1gXkhqrUV8FGZNF>lP<;J4+ZA=U^JT@x1I!kb} zGBGIr^LNfKs4U7%&nQtaGB7YuNUBr_F3nT$%}g%JFRm;uNzEClI$x#Rb lDJ)h9N-a(;Doah#ra|z0L32^Em~2?W@fE1uUoUt#TqnSrme|T+Ja`CO1q{m%+w1`tJO}NDNWOK ziYQL-QoO*tR#1G!77(R^!Yio7W+L zEj z#jPAke}|@(GX(c)9ZUP>XD>}p-NqT0%dx#`+sed-#qt2+EyJQYL}{19MxDwwGwIN&tZvut+Ukx(IM>lKrd2vdhD>sJ zUaPcgRf}%d-uj{Ie6{A>;c~gf#l=`G7W}XOWPymk(I@~=AnJ&A^a+6R0B=kfS=uvI zg$|0O-o~sZRTHAF;E1`tA=MzvKLPF1wc!FKr;^H^vVI_*z=x{{sM_XtLUX+CWH60@ z7nG?=|2>h&?G7cF_7=|rBa`rTWn6}CAmBtOhLNJ5{)L|$`B~PrT~J9LNZ&idaLr;L z^r7PJq42SOez7s1Vsx+b*_o$5mzGFS$;s?fH_w(&HImZ(&(II3Z0~ALFRvztX*K8j zR6U8Y?PfdCsrX=05JyI-PGv?@?|Mzju3dUJI6S!~C7CvJJpLYX18EYa@$e*=*>B3P zt9`$yb~8{RGGKzDLKEx-16=%CnqV_rNUE#(DER0*dIIO9b^4g1(9aYR zd;SmeKcN*0^8M=*iJ&F`)Zp5K4c`7?$i5@O>t{SV@GPz}$(Oc`=uti&$KmduoLFTR zAzv*Z$1nwC9HPx3aug^vt#G^qSD=H6jHM8)oqdvhcb~X6=puxE>sm=?Tj5P(w zp#%`T8&hvnK6vk&#B5^bhvWO^m5uwdK8pWk{b;r6&FL4 jqaYok(CD$>7f8fA@Ti5^GzVYYOi8trYd^mgh{h3qmZr}WS^ZM`8 zC*NJW^7H!DU%PibJbL8K@ndff9(cBY-;;fNA0IjV^6;VO=g)n)a{0%li{EbD{CocV z|8?uGZQ68m)@WtW7uP$8pHh;mXg^SLtTyMA8?ixE~nbiW%6%GQz>t*J`Ih+}CM0wabnGB}rPIV6AWn-Q>or$rRk&R1)DJ#f(rmxfV`3s#xHciCesc&dl=2#_Pw$>c+(B&CBr2%J0j`?#jsR z)zkRX(e~Nb{Mgp}*VX#AwcNbB;<~xuxwzlN!|TGq=)Jt-#l-8tzvarw@X5&U$j9x( z!|Be=^TovJ(a`qH%kas_?8wLK)ztaY(e}{K^v%rh%E|54)%n`l{n*$0*Vg*l+5Fem z`JSH0sHoDz!}71M*|M_St*zC#xZ$_A;IgvXv9Z{%uhz7*+q1LUzP{$TxZk(8-N3-- zzrW_bzU92UwpP3`I0E~`}kcxr;0dHJBw2G8)WI#npOiCysvYm;YLuhSlP$5?*6B5mdlxJ*e zPfjcmTQ4*Vi~);vQb;CED=AtQJ_|Yt&WDsoR3s`8FlO+;z~IJ*T8BE77!dxq%L6{7ZNyVXfS{QAppVxT*yJ7M}h`81i%#FY-gcP zATr!DAfv`4oxwI0q9pOgjtW{{CN(+Hfdv~?bf%*eX=wlj1zNaxFhx+Nq?LZ!dF1FQ zOrM4nFk#Xu;M69#k_O!^sWh*lz5)UP03rTQLvL_-a%pF1bRaS?Ffbruc_34DZXiu* zV{&hEd2@7SZF4LjNp52qNFOwm)DL zUM5f|DAMG)`M?5!8MjshY0h2MsCcKyI-XnYHYZ=p(kDk{gOnH)|M@%T7gQEyre~BW z7#SECC?r)X1efM1_+};-nM2UCF?0T=Hw^@ffN=i1f>?I7L}!@=<#xS 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 zcmZ?wbhEHblwgoxnE0RJ|Ns9C3=9Vj8~~DvKUo+V7?>DzfNY?w1dweorGMq=xBSUG zTcV^I@5P+fk6Co0WEp4E<5zR?W~~!{Qf8pC+57LkioDE^7W)8J;WME*RkW{GQdq1Ilv00|IKvfPS5n6 zn_`_>wF=Iv+Ryvja`rhdk|H3WNI;OUKaXLPBtZZ0Kze;G_C=PPLP(sSN{m}vi2sX> zETtHKwu(SymSV+C}Hxdk=YC=@g>$Pv1Tx&x9p16$tHvZJ%qqd{(RvbJ!PA|v7W zvy-3=Z7Y>T&PJ>eR`oJxa-Pv-0brMLi}CK%L#7%3VVAKVv&q6qZn@P-?~Woo6R?Z_G1n4bnSXe0hGd zXbm|n_;lOsf6`d;$paN;Ig{4732P#$>gb9HW5STnp>=uU^%Lp9pza}(R#I^RqZWHg z?KR^<_}|rRKaDlZ;AU}!xG?&?oKEAZ(c48TfA)(5(F-^)C$ddiT4^9;2{ji!Dleuq z%UZjUzBz?bEi8B^0tykhn@^N+qC#VGu!u+TKuAc~)E`f0?<~?Z-Jr?L8oG_M`m zLT=&%dmMc;XYbb?KxpLHLHvk?{^Qah4nyk@sr#E-IIOrd(5A>fILISE3Giu|+= zqn)55l}pcIqwr+umg3W{itd6w$B57t4H(~bcKmKJPp`4>*MV{d9y0-3AZyGWuwGId zd+O)LwjZ<2F~wKG1u{!D6tYhJu3S=C_^lwWywcR>Sxu|M#A4_e4idZc`|6Y;kE+9h zNkrKN^HV9X)>_k5mYmE>q(KgNc+j+o?*mE-znHHL?w92~qkFMx zeY`#6YW`|(@fF?94VG>FE4i@FjFVEna*6|7H)^hrf@=8AVbe9KzFCgbu2Ei_EY;bClF=vfBJ%AtwGZcA1-tJV~o7=ZlsDFiFInI1iRUGu_ z%ueB?+KD>39C=2c*ze>v?yg+;Cg9zKb#)3ari%p`4Pk!1K_uY054m)3FU|0+`0XY$zYz_Y9n_~%R3s+?I#+yluE!-xQOju2R2H=avwGHBBg1UhPiu>@8CO16 zKzeD_ovBxB*%?OK+!n;id_26zHYAQ=_wHXsy?UgDoO?pP)1TB`F&Q!PI_LQl3K!h7 zz&;5g0}vaZ$)eg|{JPjg_tIkBL(Z8e)F~Ucur?M-T(E^W#m8*mVV+AaK$;;Z+0Lv< z5QU|f&F=TQ02rkKD-zGiF2GFF34U+$#kx*Ix9BsA`cx{`wA@#ZR|}1IOWUm)2o2?M zn=$6GY{EOn!Ezrt;*&QYG@lrGLHVQAt(1ob_K^odFc`uNB(LP)cD-)Z=@X>rT!C?v zHluj(q?YMWM3j3`xhXkxH{eclTLIH3 zc7J0D+{Sq#<(p_bp0&m+7Q&~KcX$Ks>jx`Kc^@`H8dtlI<(57q2(2qDH5MDHJbnE% z0IzYS{=7}YN`Gj66w3$2=bgf_@09vkdAf^|OqmMTJ*N=M6|)N~k+wR|DnmH;ZF9P~ zB5?-?UgGT7Hr*GH$2+M)U-l)+j%US@(4@fQI`~CrpQ754TS&dsk*Ca^w0HnlkIex2 zBKR^)Sexp@N&5`SB}+JmgTGhD^>E(W+fod(+FI*oY{$`+w#WUs5{m`*t8K52UM^U1 zF z?FP`h)ro2+#}Ay#zHzF8r$AO!44VyMY^GAS^O1ZAEirHOL886>U^7X5{7G!irIg?j zv0k_E{SZ?W_e}QizWriNCs0tO+lge?2QW6}2uIF%!ZF&D@Xgpn^|Ji(zF=lfW_0%m znwofps)Og0_^_*Qp4g51g9+J^bv;|XyMq~g3m7nTeftp!b)=O_**FQIkH*OdZm?n!7d zx8GsP#N6r{WM|(xV&{0Qe_NY{riujXoR(0ORz7!R=A2>^+CMK#Y<9O4Ih)iR>@6#- z%2)KySuqlia;a$MgzIO8JwIJSAZc}5OGHSk#$vV(($o>!&Q_2}i#R&eKh>xwtPAj= zmoXiCOP;NGq!mtH6{%=DZRQkK_dEdb6rkSzvVvyTqnc2)2#RUKpx8mZWmMTR0crGj z?g|ToXFf?Gl|UV6o_Rb@w8-2uHc`rBz`pbJdFBBA_LDK*9=V>mosN-0SgAt-@ereB zmSPX?axzsCxf7|w2AtS!=z%e2SYMtGt-`V`OLKU3t0ZwciqMRvu$TD=YdEu!qZI!D zw?iyi;moB%bI?X!(7=Z`oS%CEiv24e?FQwyPv}jpnY78366GvfzE4bFI;<_Irpr2X zy811dCbU6|0EQ^W-b6a(YkUs7(p)hJ{doUwW4BoX(RC^cKQritb=X&f zaK^LODr8v%#7c_!WngisY7UjEAY78T7`v=uplkePmruTCrP_`|t zae$BTFyi$ytDhNtEknFZ3A?uLi=7R7zbDT4$h<=bT^Qh`st=&%_aH7nQs|&9ZZrIF(zfvi_*CSfG~uSRy0VGfL9eE~G)9-k zpdoF|+Ku?y=L>KvE1}Hp!2*r6mbVQ@3~FF2JDHJ(^7!MM=+9?G!SAsFQS*kuYT5;q znLMqiZdA!|Wc-Bg#3o$*k-TIhKv0&_`S9cTGxOC11!4R?B2rMh~OM2|2^$SNe7^syR{28k@$GO<<3 zgpZck4_|<2YGLp6@la4eNrIOnl-G+UL|(h&T$Hc5+GELR;rJcq=JwPX{GrS!G%VY) zCS%nHUO@#sb*}|>&|2S4jYLKqPCx;KO`dH0Vc0|bX0yE+B-4WV$?+2SgxV9#Q8<2Q zKG7|m-}@Mp9_=rF&Z5bFeZzS&eHU`FB`+1H$oXMNRA3G~g?MDvyS4*GGMoK(QkEGP z(h@Gq8t_QZUx3=qhmXW{R(STSk@vV|k**qo_)CcTuiIuq2hK#m60<6FX!*~o&@1MI zqB8JfaQdE(N)6DIvE9xaSbF?6IcSsl16Xk<6Q(+r+G5I^aje|&QMsUpA#RQF;h|@U zK#)b)k=;gG=Unxg8B?xw1mCf>6Q8+kp6k!tD1utz>_pW{$@|qC4e<#$#*4G$CwMwpNQzN`o1gH zQ`{&#bM{EQs8E)D!Yn9p(ZsMwW_jbcJ3zc)xUOW_Ru@|g|J16`U zv7@g})*f*do^n!@yA^r|Mj+a{U?}g3E9aVm^-SVPppb#^-W#}H(I{dCO zOS|8*>!ubMQ2Q3vF%qjhfS*n2t~1Q8-kKPyKN`l#bNRt zl1g3x0uBAXQk;fC2j?Cb8dtQKBsOMP^WklWQAFrl6$*jf=c|WH4`hP-*YyXsQ_ACgAxq zR73*+c<0F1)ExyH8fh&@9R8SHO}CAj6`xj%*{3um{J3TSS0nU?RF2%_Bz4mkr!!7a zpaESq@YmFsgZSO0`)3l^veZ@`oBXV%HvsuVTS2C6d^QU=@45<;Q=gM-3MSd4VJ~)S z_LZ9jxi~h3VN|V6;l5b)(OQo-bxV=V^U#^9?8;*78h&ej&F$b2b03&PZdlYD4KC>? zLzVTQuRM<4Y{i+(d)7=aVIE4HCQsOBZ#dl^_i9JPJi3T>w}=DT%W_f*#4;>q0-lJ+ zpxikZPoBQU+0*qzK%x>#ZhzWkra0M2`c41=5>IFS?xZU-Qm3yB^^_wRB41$=tzrh` zbd{S-5_p)s0<#EC?xW8^p$)B;S4>G!2lS!Z8L)DDbvz^5a73S9WAt{HC{Z$0PGdIs zlO4trSvsgib(v%+X2%|Q#EDj)WXq2qCV&6dV zF4{9eks#gMaMj*Cu`WJC|aRm{5Y5*yBgzou|PipY7;m$y1D za>uv%UpdDVLebVx0`1=2|&&X+LJF-m1Dbl5GKG`EmE z&259~B#gk+$xy5sYUk?=QV9ysk1lPUn>d|GpdsdUDWX{_iAv99w8x~n_B2wpI7KsB ztk`|%0Y&Bez6XQU*iq;E2)m>%JkKMcNQHK2)BMnl)aWND>oGCEJk1pe=I^X)!$RDx zCbDW1bo1r5!10rcV*qVYf(o@d^63K9o)v!3M%c5!`8Edx9ZHB`NPO?MdJ29v&!tFZ zb)s!8&KEcDzBK_Io`*rWG#j z>o5?fZE8YR{Wh;|ygxZofA*FcrdMqriq-TL`V8AMxXA?8u0nzZ6HOdMWnR#;3`-== zAica{<3&*H(;RpGT)_tAzQwGqj9bAzLx3i;ME8}W52MrU;i@^;zx10xd;7EiYT)IC zLGS`Dcy9k%qtbiEaD?%cfJ8YB20ryZrPWo{K*M?Zma6@soBrBHIOj zRb3&@N$t9M#5I2%K0V_}GjChzC?4)&{u-D=My^nOeIRoI3~Oa$%9OkANYY_aaR&U= z+Y#J=)VY(b1)^~L8Ad`6LtazMq)_+L+G}HcGb%!1+aUPNFRnv%sO7^6?rymE!%6J) zV^2VIO0d-!rurp0|8kTZxZrHoM+yoZYph?b7bVpDrj!2-)M!%4aP#n$c=Tl8y2H#kPl5Sv+m^K%31oNJ!RgmI{^jh&0QsxOpIXj zO$%x}(_&Rk9qe>MEAhabFb+k8Df}lY0a9HTzSjr98)b3ibfDN^RlW(#LYmJ)!TL)=jaXP`d_N zRMt+ek?9A0a-8YAFCda45RfQXhSJr@KtN*xKtPiJf7=%*{Euzl_y5@T73LQIB1u`eDzQ4T z!u0NYo!5Piw*NlHr_0_%7xr>l>apIygtoC~adbfn`p61cd{NYSTBLz*%+YwjD|uM` z&H{LRdA_FdcnZOgJ?C`COw4Hl#b$-$l{sxpAHFDC{ceTrz+FGy*o1RMnR;;-zTqKp zxfKBa*lWSpMHE(&2D>a-MB7I2Mcf-@S>16ntuzMaoXvD9r_dXLMCF5lEtHDfJ6qN4 zNY74?{A4=9Rcwuc=ULzpF&UxHJa4*ONRj29cc=tKiM$tbtqL!jZ6#F4gh&Ut zFCy zEo}%s*3pE2*$SV2vaMAbFznX!y8nsEY@INSeh`UACg1>xqv@SGMH(q5W!`cX7Z|jR zd#1H$$~y`0d?^)?ix zUK33cD{kC5;(g{t9&dLvTvOXf0t3~%5GL+u@_?Oe07>dbg;8N04uka=jT9(-BpLO6 ztopkSkzF5jDWe`(>oxGXIu5@295v4lM5==7&Y7(!$CHID#v7g&L*j+GR+Q)K$AlV+ zOKLQZC@S1qy-J{B!qHi7b0vIO1gJ|Ze7oq#QgLsI@25)8%f~H-TLXa2THG6uPj)s6 z=Ky0{240U`;s!_%rb!e9ZhY zjdd1pM<+6MPAktM=`38`r-1wl(fu|Ymmc!QdIWrPi8-ZE9jX#$Nw*q7>T<9OA41?g zodHUpk@k+X`ckvP%*;Z7ePa5+e3I?_u2fQ`H*|p>)})1L+_mdlutlmMY2GYg`gA!X zTs)x3VQshX%(;33S)yy-)+V#Dy6~dkxPm?gems_7F@G$LUKKBa!y^N39H{$F5kTLJ+HhDJn^t zLRWjbNX%|uS#5gLy=8gEgYy>Do{50!SX!g-&L4>@pR(|ejU}OdmB(lacYn7JyddD?G9lR46D4a@b#N?8)_J-DmY8>BBcL5$bg)0{ zeYlm0L+dfwrvChJ`0`N=#BRO?XZdDNZJq_;rD z$|f;dYPJQnCgzcck)=x{ms>=ob; zuc$65)l)#Gx*E9f(UZmmJ}EF$4t|0uS=!?X?-{Gn7nVNQ|Kvf&YT2oGFcaZwrnyq_ zjzI*Jw={*`D8>o}tg5g7BMWcdBvbhW;^Fp72;m##xf&0`_wweN{;BM4hle405O;dY zz>zJhZ%hJJ7$Bk3@0QhFrdU)6e1l^dv(E;FPlTy5zP@#;siJDXn%! z2=C%EGL4dj>@q&~>2Pkny<<6irj1tGnvMux%ZDC9sqI*&TQ-_uU5_U5&R1DU+d&}2 zd`8)hwoBo&FBHcJpDfMjc7TXKXD@B9Rjg;1)?rkMuxX-;R@6@RJ0HK%tTQ2di9mvN ze1k=HP<$|h_I?Dbf2Tze5t9em(UhI3!k<_T#wkLbNI1+{NrvKpKuDtq>NYSLO+&$# zbK`QangAh_fAC5Zz;zo8PGgt!TQPIPSOicILG4J_bnx&8Csv2A7ad zMW?cEVPlg4R2%~sbrepDj>_LBa}s=*F1KN4(33#Gx?38(qh8vk+DKh=@3r{#!15oY z@jg7(T-oP>egUA!fDDXumPw{7w=!*0JApe;v+)rv;mtLbBydhu-F1AHTbw#aM6*Y> z!9-q^`II;RPV*hUoUMCr*kEwOB~?J6)mu1)3Op(UiMp}|`K}?`%jDtix|@k66{=*D z0||{#?t58SIqoSfa$Cro4$-{%o^-7~Uy>HZaks}Sy2Y5a#WMIovei{M7GXIzhY`Bt z7Gj^bhu>z`A7V4Tf&}wY5(dF~(K9*BHxPuHhi%!8@|@jzk5zoFaYx*wFY`C+#m%L7 zA{4A7-y@ukx~qgaJ35!r!SH{9S6*1iLQ3VaSl!5)5%wwmav<+idJK=`PDKDc4-beD zhE2tS<-wYF*Pi0Ne6W9d?fABrdmu<3?sRo;n(|+JB{W%So^5c9jyQW?ru2FnS^I0K zVU^@&#vs8`ZSD)wa^$zyUf0b+rB)q)HyPx$P|u6c4Fh-SA)=prBV#=)ZGD2S-%4VQ zhgW?^8I{#bIv=qJg#iV#P^RSC+%S14d>O0shJwH;56mjE!iYsI-WC7sezc0W6bS+6)||L~Gwir&H=?j; z8uiRlTdCDm+8AwmNjFl0o-Nz4b#ecjPXXP`5Bup#=MOLs9g2u@I6Jy&TI=n2k2Af1 zVxYK68ws@7)DW^Cx>A^vR@i@NmdJ5P$n)=#}%5e zsETf`Fqcz~`veDtw%5#en{p2^6NY{RTu=a2p4U0O*Ci8koV(2krzb%Ff zfeqiB$$eJYVQ;F3m!adi$L(tRLG*T4(S-XWQ(d7n@w&o_wzNJyjyI2iV>1V~kln@n zu+zeudL@hmk?Kv!UL_`W#hgK>+_v}ej&8vkd5BEPy$Og1>u=BJu*f~PvuUxmfEC@SSh4gz z&SbjP_4`Q^5>YK|267{)h7v~nn+g1V?6dT_Lpc}BZ|;Xs8I&e?Uc8^Rn+)^$os6G`L$!;9mG7mZPsD!9skAA9IR8B;Oom%*|fLa00 zHr({qe0N1(ByFEPWu)|MhiwHuGrS~sLmtZ(&ymFAR5d7^mQ=Eo<4Y2^#oU{HlS zW&zl?wJLeFOG#6c0MU^%c~J%*`hb0>O4ecvV4v4!CPbzR&oKX%v=+nh@WzsyUhl=^ z`dNcCU=UM6u|Ds8q8EkAjbxbsY2>!ZSSK8m)Z*;|i-r%>5+{bybsw`0kByNpl40eh zSfVY%O@+JrLw{ylI(a@LW*799=W5sNkU7g@Wb;IA9V5RQXXNLz0$)?Oq{nNF`9Vpl zTUb*hQ%JeJC%}U|AgKtL&|oCY%=DS(@KKU2(7?Iw;etRp{X7NmM66rDk%b!H5C|L< z_D(!$q*^|A4=Q39Q}0BmqVBTXzZYMwoH3RNw_(kox^eE-Sv~FA*MRhTF7_;o32q{s z?QBtIYlSEdrb~FSdEV~c94j4;Ve#rh?gsE4`B2Og=ior!oN&$q1jIFpJN?X31oUik z;9)#@5j^JN9yxJp#QwAt{)`MAv>?6naT~?-gE958c0$v!5L^vkcWCdd;3=632vjb^ zb^kR3y+B`wnUy1IfiOAFZ4VUC4WbIj050|pf#1Nlvh1ikOIzG;#HTisxqS{SYO73d zB;8%8BR1C?B*-l4vEUQq7^Dwf3*M>w~rQmQYupgi>UP zuq(WI$#rWF4#_%m;ub@L%g zgSDH1Vg>uQU*0Rcv8c{@)TXAFqJd#;2+zp3uq8FSigac_d5rqTx$CB>KGYZ`T)$t1 z7#wzr!WVCc#4nL+`ZTeRN(s)^X;vhKJ)Z3=`&4m!nevG+Bh&EgPMz_9m>*=Sy0oK? z;xk`XskI7j%9UrB;wsm>=aJ7ZTbNwusx!%munlBrMNmpwD1n~rD32Y*efXT`u$IXF z`Wrc*EzU)kL>bqXQ5}l}B5J42=&YC!Ykb}e1|M0nyT%K}ameAf*jpNQC>D$MW}b@H z&?Tz|wZ$2h%0$O;@BkD8N2AaeTEqs&zE`BoH&5@D$-H^Zn-k{cSEl04J+lTG)M;3s ztvDXsD4-mHbcVb;Lpch7BIIuBnC*Db45l(URxr(uIWi0vx82AgWX_B#4A|)CaI7&H ze3bSKKWJ951!K)BBCD0|CLBZ?Ah(D>d-={}_nK}`p-m?<8P)pwCSQ+rkEl?TSH^o( zaQS?*WoAP#&ttq`6JziS`i`C+BHvnmbG9XXxs%=|>SkuWm7%XsyWRoLyh_)qF7@b+ zFUAEnX3mUdXA2Wbs52p@PJ3HHHo!o=nykxVMQO8da>S6sGEPF$V|wnSf?((%uOOjy zt$CDYiqejUY{S?D#mU%Ad4+Ncg~S{Ycf>B<<~ca(wRfIF6dPb2Sqfq3B_uPj-8IE< zIJr+b&>l%2K-!aN@qJ=c4U#NTV2wB;5!AZ-W*y!W^=`l8x-1R4-XTt1xN@oG$h0C( zuG({Evz#g&IWKEz!t71<8yahfxoDa?QP~$!1ItDnVAo3bx8T(9pq)8F^Wi97thikn z?}ls~zPVfg!1M31tGpRO!9F#=J;{i8Ta`B~qlbm#gDo+S**PmQ1|>cdP-f;DIDUHn zeZ#yyjSq6)3b0n{IC>3j2v#5{bTl;jD34K_mB`XDZ*a@EkG){;cIN|3=osA?9+Be= zA3KM5R-%<+$)?naXRmO?`vOVgwGq@sW5CdYYkVZ@GJr0j#|;0(@=?9<(F7kM>G|#3 zq9f@E*wY$A$b;|=H|m^cyj$+875k?`xnW2sUV*pAPZaUD;=Ri|99#$emVUG7*Thp$ z^i$~Gq~%3akajB_z7{?C;l>+;W(T*txD)l(4AkH$I^-v3gQ+~yqi_wP7;M>i|FHK0z1pd ziX@1gXRFf0j)*H$@YXPNJt*JM8)Z8>Yr;`tT4^K~IW5l~-g7%m^n~qFc324N9>;gJdL|rcgFwpM#o<{JQ z?(uyj_V~LCwp9*A^s#YTZi;Rmz|iW)NAo~rbZ)ztdD3J?2s%i^OXmUCxJ{m5wPTTj zNK|NI(zyPd4aX#*Q?zpH+r!21w?aT~&p#X38$5ZvU6P*B5)EViddIpGc0O1OQP5V} zOWoX074F>&&8TgJZ-z(P>tZusJXd#r?)AwLbS5N3_C%tub6b3SO2p7;T#$P7?zIP; z+`8QNo~425c+j%KUu_|P*cc9wa`WQK2E``SNzg^vLf$pJL3-Mu1%;$8eS|=8NYzP9 z0RnU+z$jMQ1JRMd+FP(kK6Qkzd zDH8@8783%xxvE885fuP^Gb9S~t*NTz;ju#2T4QswGC!6WqsIay77kGmTTV@T{gZQq zYYPS#)b5UoajmG}>e=#?m3g#`%CWsJ?t#hJ&DJ!DB>a$8=E@MMHH$+M1?`s%v6FkV zPVQ2wwb4Dqru?lj|DD~EBEBZ66g-V|MRi7j^E;eT_v)`Z1Qg4cURF^bsE8qN`M?*l z#(L`kR84qbNt7cb0$b+A_T-skfgL!X!5-308?TQeJX-O<;5DrH4bf4!>uE^J{S}np zz5DQS<>>?69eJTv+TF(D-h7*<#wI2WQMoM77-`?PVl7$iTThKKpHM$3)-%ZsB#Sct znqQY6wy?A`<$wdqW~OOy`GINvW-Lz^v&(dY5mv9zfwrLqwYqhK|O414j7g9x$H_H=Ut& zx&G#q@ulJ8$Y9?{ReI2u-q+z1^mROP(K9+sE-4~GC^)v=6Eh>wiW{-A<#p6>BTkAC zp+H+dIR(EF` za{#l?yQ|K(+gs!k$(1fTM8X86dPd&(C9Z?T9R}ly_ zIsXTN)co?V>lSX7S*H1s`eSaT%+406Y%fH0?0q}U(4AV$kN##}#t9|maKc`#1ZFM- z?#G-Dc5&^sla;(SC5+09eTiEh!Xk62>~xy@QTLY`WwOvD*cYqK7Z0t+z27|)12{Qr zv=c};2Tyk_;vxpH^=V<>ha)5zUKL+mvK)6EDxY$a(uj;S@3lK73&m(T^KiB1(cUJA zMcXq_I4^fR;qmN{^%R zB26#$aL1Y-EYGYgQ60jJ9@RjwrqF6cgHRCTx}&>A0P(;5@B`wL^^Z|No}HW(KR_Vz3G~b z*-QDl$IpGJu{!R7?T~mrjAL-(J&aX^j3aO$4^SVtzXgul-)w%7;8aVCwcj6moVBtJ zY3Sw{sBO6kuWFLC0d!YZvgF#o+-0}UZ0U*mAF9WE94Q*rOz-^I@etg+EqjnkXRUBs zyqubf*6cc6#3+g%oZW35^zc&9vShSZH<;YoyoKmcp|vUJ(<9QRsy8;rmM-)zQA5g_ zf&6m?ZP^~?-kV7tgGikbeF89sr2c12`#`LbVvP~Jk&l_GR)=C!De!ca&(ut0$ACEv zXMKFs*Nqei$leGtC}a>IAWqPK+*o0fvHin&`nN!!e?L$EJOBg)^4sJeC+^?;czS*O z*p-3$?bV{J)gLCKyuNFxWvXXutH)z!YinUHV6A0oXryC9_4hf4|HB+x3ky?iE$e?d z2S)mjUlQ~6bN=T!wt9}XzkS&6cMCxLG?DnvCkokWnHuTP(o-53>D%1eR+fpzXhv$r z-=(d;yu28UBx`AEGFh&9Zb+c;gM;gXV}FPP{y5sEOP}kpy@Ar{MoK~-_Bs6#_~xo6!)l||9ZF^C~SLq|g+ z`6%}ZG;W9VPM-*M8&v@%?)whPA&KJ-;UOv0&K3!%7ZM5?Xf{eNN^Ew{-nq5YeI02X z1gUQ}3MtwF`k6J2;_sKLF|dER`qj>=*YWoaG{~Pw5dJv{9t%_5f58C;1_lBS3n(g> zQ|a|v$D`SLnu15NfkaQoJjdp)UU2R(Fu!*mtF=C7?e|5`n3ayxE4zlIIwq%{-!?f^ z#VdP}(7p&odL$`^6Z^97ub0%_*z~QEmgM=;VT3A=d_Z)RM2ec0np#q@K=$>}h|Jlr zDCGcE2|1tk;)Nz?sfrUV|;XJ&@t{@~XQ#hu@s|3xpK)VWDjox>dJgd0jL{|l7AGkB9K z%*=0g`yQoAX1&^+{omXD7j>}xyWLc&mD};01w`r6K3UOd3T{Xrn$fP}i!$U|XZL}6IC7(fJ5y@bq!Uj`;Eu9F<0 z!kDm2tVLE0VwJ`tqo(YZzgueg%?vY!%wRQZR($d0K2K}4ap%^P(s$+$^8V`O<;5eN z&0}el>TRKKE#+>dXC-88ULNjkpk9&cts@@J^G;B!oJZ2w%2-OtI2ea2E-oU;+a;1m z(fF%(Mk+8Bs?X=&#Bh;edzkZTTi*YP_5Y-Y->iS3GZ>+!rp98jD)$yQZLxmFv6M9)RYA5o+fKZD#awEN@Z&5YHFrO%I3dQP0U?ON>Gi_ zP*qZmN>nMzT1$v4%3X_(&UyzbtyuIfMmbqo_FH0R@8I_KX3iSU_jlivziZ|hv<-G^ z!v2P4D%<;_^A$_`pQ8B>qUAqn;`glaucAXw%=3s3^eOHc<&=!dqSK9La?S@{kvrdn z6S50^TL<u=YBBli zZ~r6;aGM$#nDgqH+v-{WMYA`4nCk?rIs@qfMt7Siu!rvp{&sY0DxBZ`@z@O`V{r9Xud}*q6Xj<1RnKDseTeUVnuz-mn zP9T+W+N8@4)|-sw_aU-F z+b?};V=A*^3W;5vk_wj*?Dm6S*%Uq)FFS}jCAi6Nv5&ML>Rs6@gNpwX4u8=Zew0Ur zxC5h_OC4P`%#JE&2#cwflS-cu@#&|&mDQ*nwCJONPTh{KGPkBzkkGMb@wNB0wQ=F) zOXJniOSCi6)swW=Rn&d_T&pP1PDiCA(N04wfCu@#Oc9TynyEUE{PUNHxWU0*v37Pr zJo0M6cF9rCxR7>?-z;BHs7?Rj41cVSepUe4>tFo4Kp<^oU}*clFg>^XF2xU(?=yLU z%e9GIc-w9tPDnl-#Z;>KvgORfK@CuP%dZiChGOk+ao~@p|GdKbk4^vIssA+${H}gw zPW|zqD7|E{2#w+Xq-t@1P=eQh{%Py&rwdw6NXH=mXZ8OKg5p2W zfUup7t&zUdUqmtf{|AElZ3-uyQHy1HqS`!_<1ZmRHQ5fu(4i}}+{^PHFWqMvF@xmn zVQ^WL`8<07zotGWqTI^+5eELaX#6i={6&|T_$?Y-Fw&U?87tDCx?osn9nJP|gnYkA zgN~we=x5Qm)z|%1HK1GlfX0t#@cniCy;1RV?*QvxD?v-!RPP_U4xm3}l0R{#-)2f% zIPmGcc1`qtR*>S=Z=DA^gH##@ah>0q4?rL=B+t59uLZEy7_b$WF?M_j0E9SsIzp ze^ui`6{&FW>J{?c-!8-NEu5cW(*2vuz-wV@XJ#&BZlh;y%dP)fr2Vg;BC^{r-|y;l z#8=a&U$%`pgicDQh*c8B(Ndx)%}Z+8&aDe4E+i#hUe1;`6v$V`n=4+;@!}gpt->H) zu90caR-yzD>QTa}$-7RASe}A<+}4Iq7(BH?->Wso1NOfcP4%X6ZaV!smT-X(+lQ~D zPXCl8{a;|oqo;3S{l8Nv;;TaId$%(3CD)fLW@9wYFh)PZGOh!42GA*pU2ZWSAsT#t z%F%z>M<%XLgs(Kj@HZ&#+Y4=^&evJ=HlS584*_4L3Ar_TP@Su=Ld9);RO{U{N*zFP zzubA`c+xz-xqfW^mi()hNg9qemiw=uPW}`n^}j*+>f`@6nzZY%vE!*21nxz(#()7% z;Ggw_QO7i*2@x>2N>C^_w;FkLkzQ}s8z4mq8Lc-lZccL0`V#c5RA2TkW>7-nB^p`> zN@a3jVBd*y@8oN!NU+hUj0+KmqgnYr*x=~Pc>6EoD7ARbaPUg$kCFuYDOS?_ryTza zJ#M}_H*@b$dV{e=SHfmvcDx)rytSwjAgpuOd;F8#u6NZL&^H*pQYFm!3fxcFw5;?= zv$TuG?m#jIt?5ho$8_4GHyo6?_CI^L$FCYuL^BqK5wH7<~pt>r9~uN4*6 z!bnT-?~1*2F*)#V^pMf`#d53YiNtzI)KD#b(f2Y65pI#Gsv!`GJ%zX|p?eLNUcB98RJD4S=qQgSH1*ZEv|F zD)AhfWq&vvlUMA7`Ub@;0fYLp;=oq=jcq5YhHSzw+bdLK3Dj77h4#ms{PW7^uhlkx zPVa}u{u{wH{_t2AiVawYCJPifdk0)f6` z(nOv;*=8|;T+N%2Xm;tFD|@DzWcADp;j{5;dX9SH^>{yA_5W2bP_M6F4;lQFCh%V0 z`=2{+=34ef23od87Uuu3;0F3>I_ZBhUC#1n-hW$e8;k(bm@i>KKstY9WzD~NHuMkA zmL6;?+AcpF;q;LSW@N7EBE?t^x*u^CNDp50#-p&wJo2Uxk{(}_8?H=y<}Bk1`ueM~ zZ4G76?2i_9-Rt;!5eWPfhkqUM{sAM8mX68KYvj6z-x?1Rsn0HeyVK5qR@|i*r`wg= z#oE@Tru+S!VT0LHk2>q^5kZ>~=>67i%?^8jb-o#k;kp%#BW$33i9!rAjuY-N8PC-;OovG-sQfSoMb& z*mQb&NM&Zklj{m<9h4MiH)?9`DJX1`l6L4BMvM*PjZBk!+S)AF+JM0`y?#HA!TTfO zZxKV(c!SVEvDtoqQ2UsO0w&)>LycqwR$HXiELFimXwoR-t5Tq|)dE3;SGk0;Y_Hy6 ztEYQ;f?$G)&MO1I0yyA9VeTo|87WaM&GCjRo;Y~>?8UwkJ4s6%Gm@CBOg1+wGg>%Q z?Z{AwZ<6F*%l+6?l6(Rx@T+$555^J}!hwN+a$d)Od71ev9L)cBflR1Q~>XD>2Rw~e|xdiPHD5CK|Q!l?J;%eiU9sTG~*8lg4|AFFX z#XH{ouK2VkkBh6-&0Y^2j)$kU_R>dq_m$S$&6DO+hZFZkx81{H6%F$hfa~Q>B_<<> zTI=)qLN&ZXX-lK){qeSl1*Mv++xf;JG^%e7=l?c(SAI(cDvK zz$q4+Zwwd;cbUsBMSK(v&VCIy-n?CYO~$W&@i38X)?XjuO~X zdva5wgvBZP#W|)hFR%3<#W649@4Z7y?H|2EtBtmmg|(@vrHO@^gTBIaqEubBTKSn^v~J7`(! z{_h-Vzx*(Kb+g$!M4N}H0CgqFMAoL4-o!{qMj2#MWgh@rO37YTr%n1Y+8*@FmT5X^ zCJaAzJ!=2pM*j_q-#rPq0$A)>K!~4-Sqlva4QToW==I3l&d$sB_VeZ@V14~@ZS{U- z`F45vc5(4~aq((?{$hT9XLjanYU*TS;&5zie{6JrczAbkaJ#>Mv$uDxt81m>^`AVo z4Yjt-H@D0-Hcr*oPuA9sRacKzRgF|u4waSlmz4At6?GRBbmrx?=jOI&XSZf$HD_ft zWu!NxXEday)+HxbCni>Y`&JqgQydYI7Z#Qi7?|PjpXTk86t)Br~e9~t*!0# z`KJfoJ?N`un1Oz5iN9Ke2E+yK+Lml7NRAP~r>g%gNY1j4U__GE7lsk&gK-xHB{qpe zawoSutPDXTVP(G*P19n6pZhP5t}5v+oRH!wDEfOA-Qn7WsZ% zdYmN_8a1+8iuZeR-~W%cs{pDp{oW{L0E#pSVgSY^3ep{yknRR)2|*<^3{auM=**1GeVQ~S6bAvVa0`$I74kJfVSq<0PACO3A*7|ELB0mVe#!$u!=@c51pZfZfbZwm z<8S8@|N3sULF#Scv1(n7v>i3W3`TF3L|aa@_e)$iF?GP=3_x{|h8(z!aeB}YUsSXe zDt`R@ukXg+OfJs{n6s4X2Ek#e?e5TuJn-JPZwKwo4P%ZPDcV?A?AZ;bDuWnJ^gvA8 z#iATcHm9f5>j?nS!`=0X5)YIJcB}QBN|!x~sO)XJ2n8*N0ZDy0>yT#4FoXW!z9*XW_BQ3(s?z5H zNK&r)3;ChL*;$B)h$(KECL=?e-gkMH-nTs11^zS--t>o+hg64OzJZ^7e7_LGHB=5N z%3%}M(9)r``bBb4zvpGt)@KP`@|w%N(hB&1pG{AkM&XY8!Zg-AlTDL&;p_5d zEzB&;`?h5se6bXzc^DZox00$YMU+sjOu$ebO`H}bug+S3nZ(o>KU+?WxF-ovBp$Kc zS{a>MZHT_0vMw$)+andY2I=2jh4a$pwDV2DSsXURg;c5$>n6-rN!JFAxbY0)oAL zSK^vd*7*GLz=2llV4=}OHvDy83S|e)&KPywUIm4+{i+nnxnL?zh-Rx>PilLnoVmf? zro>X8vJzyoWoM4d8H)K6{eY#kyjK&`X&@ylh=CS=M|J!{APMOXEFvPx{svWn=Z05 zoHsCVVO3LKK4p$OaI|s%&GDYU;$M!x=8(YgCS`>7eLLQOM)m};Ax_89iFhGVst`x3 z)o|G6;0UFHt?m!C^;nb~#cF#C`MOkTa@H0H1w&y>N{SV$pWE;)k&tfb>q9p;XWiVT zYHJv3Y8f#xS_Orcn%Y*|o5Nnpv88@g<&_`W@9kxjl!UUeGxv5=%&&~dDOXr+PII=l zHj{{rjtoFD^37-B1lVnDm*d-4sM0wVm0^`mH1g)DcA!SuUg;2ibM=@sDL zg|QefwSW&aTl(qk_g4Xn0y?W!JIhD8nk(`-)6-RM^_UbabdJXp)=-qz2wS7Ja9DDw zaK-Y&7V+qV;BXnFt*RJx)7fPpd7bpa&fHFO)FeN}J3#D1=g zo!w&ik@@1t%Fqe5(qX{0E%P?l;ZgyjczU*yUXjpJ{he^&zjRH$c)5GfJh(TltjMGX z0%{gZA2R~A4qhjhjuJw2)Z&?UjqlZ<*k?qEdP-7uRpjN@yRi@=py(Gcz7o$@j z?0XeSYuZQcFle1Y?=x$;Y)#P0r}o$7Oa!vIq1R@4S|TuoZ`@88ekj}VDpTG#e%zV9 z4-T)7myZ5z2B!+6x#Bx<+3s1&j4%$$y7dp^Po(IFl!-CDC2VSaoE>SND)n!??xD5m z{oo<+LRbQMm?*L|31Xz}WH%Vh6_mfq@q~g%M82C0w>_s{OD~yU&%_cvh^%=}B`ABH zB3EFGl)%MB_?g%SDQ56|gY@lb#q~*5#2L+##PrW}1xjljhCmymuqPYjtjX zDESyyQ7-Bs)`jDnVSj2%&^$kEtO5vYP0_HEue;f3@OYPt)u$Rh6`O6(A`a?~jxfx!uApKS zwQg;va>8@!$)b4A@lvC)p6E&sLza+kP1X~KgRd~mUJUmM(dJ&|=|sdQ;QJ%x+dBsc zG4Rv>-Gw^?L{HWFC)plAS@|^{OHTnj=B%8v@3KVCF%9*y^WFBGEKeRw$cemJGSd2r zg&iud)wwGX%o__^Rr(s?f_P69P#?_GVVTp}fPW8!gqh(F&BU`<4>S|Ua%OsiS__#B zA^AA`2IUarscpd9WhgtEuM9Q=v05&Fv1)Th3yYc+VpO>SF-2()H8<)_g9V&!6szfp z56(e?$Pm5tW=5mGrD$lL`ee<@(UJVYLBY_U08c;o|)3}6%flqzl-PR&G_d; z-fw0sVFoffZG!$=QCu{a)vd~XuP!ndQz7Xd-@11`Vu9~^<6J*>-9`JvM8ZXIiDC>go5NVt{u zXerbK#h%Ua_#{y*N>5)O842mN7lvcb=_DZS{A)Ak78Mmw6qX5y&Ek|T-rI~;V>)fx zH-hMMsuYu(wrNw_4fE4{1<|!!Z1JVA=tz?L3a+=(nF|=RSwYrNv&<;tq6u#0P6JVp zJEAzW*NZy+y;5?7jYyW)`*=T{Ncpa#u@vWXdCO~q|7Zj;j-I^j65yduzdvHk!MVHm zx2)}a#c`H>ppg)SGOv}Ur>8qPRh~XteLAb*$j=_F6wtr+@b!JkdylV}XuW&WrBd9y zibm4*-oALDu@T*Ud4yQJM1M6TMX4b$Bu1AG+SrMKYfqJ7nrmQ3H_ap)Z);bbSegaD z%B7}g8MS{aK%&QDwWz_F%Rj_iB)w%XPL&Ldi>eCku}7;gf0Ra1X>=X;YZ%G8r#kjW;Rq zJPPvN#m;d?jjIYN!RN}8;jvbU3BR6#w4bV$nKCDoGI6bfH_zf#ft#r-_u<1}f1KBL z1ep~Q$FH57ufniD(+eopZI(B}dX+I;w`=8K!(s&w=dR=7VW<3-5B0*DgSa-Cm>2-c zH-Cxr-^moufZm0&>u`&BEF@+pMYfb&?$*7r`Lg{(pg}8@!BGNgZUq{&>2mNI!~Lau`@Z;=OortJ>h&vi2_TWy z=0xEUR^)j%oRUP*A&BBFuI?6(Him2VHbRiBP4?j|Ke z;`7tXVsleVBxI5dpPa;bR;@gdYoga|4W}1!{U{8N9UaT-%Fs+ z+dPm!pQ?}mew>DeKQF&kNH{zsnAz|fiMv95AE%XT$*?7grp(eeJmy%bR+a?1mD_9* z=w_WREo+E2R`je!ry_^&e8Q;p-^{v~z3zSc6!1f*-_K9xuR;Kys;SvoJ$(Ln&N6Y} zc(U?ao14Rcy&%>I*k>WP;cF9+j;3B{xft3$9zeW=>F?_YQlsd@`=9`CKtoxqmp|Rx zE_C4$IYB+QT~*GVIGhJsFj>bSS?D>yn=zmZSXq!}g%){k8U)>}M!*QRD)J zo$2KIFAX{~1AJ&fDUC}aAsoE??=Ffxy6c*o|L5!Z?Iq>>dk6twqyM|nqXjYmnW*ah z=`E$_T#Wm9H{-Y8<<|JYc+Wyyd*qShKKh&E2v+Dx3pi1}Abg;7uf=NyF_@CQW27vu zMAw+7TKIdh9lNh$I}J#Pn10tuIP*=hCN@BX`s05|gzB?6u^~ z?R7I>I@bsJ$r8l4(K{1knzeyI$FBz2hx`p*`xv@p$uMD?#5Jw<*HqY>D*Gpkh0;} zp3T8dAG!3X5<*P#* zk?mZ|0GrlMFPNU0_N(O2YbT~NddRIaddSda4^MakHt{1b}C^gGwn_zpe@1ap>Wr2W! z(3dETL=iMW9&w9-^HFv-=x+72o6yK2W@ehAc-_08i6Kti6@-fDcdgAhb_F8Ba#NEK z%c}4QL>ymq}b3_^Q;Q zu}V1o2(V#w{D~$d6|<($Z3-q_g%m+NrYv zrmf;1j=Rn+ri&@fX z@gDY|OnB)mAEmywjNAs3@E5&(j5Sm1L$T4Y8XB^^+ry|hb;dJCg ze#$dutN!#D{7Q}Q2pCCuyHh`|!-c(Wx49v*BfwRRlFy-J7T2br<_4{L)a{x5(Q&>J5w7q z8)=uKalZRSS4dlY`XE_L1DheYN1)x@2T-&0o2wV59;rc($bJtv1M=_Aq3@iF`FS1l zd$Mz?8TP-#qWrt^Q~ONcnXx9cB#$&M&!-*}wK*4gcfp-VNi7W3MZ;|!lVVwCG*REj&f z_0-!b1s`_x^WBg34P6-vXy_AHU)qk##>mr4uT6Y@?QWAww--dV5ZXp{ap-;&Il6xt zKoA;n?K^Z|{@8&1w`R-yy`P@#=JyK?xVLCdw(->V9pE$g3KQ-iBgzp_vx#d_ zAGHZg^SrIDB4VFwpxD}M8JZ}4K=_81LC$}s#XGH=%X4o>WQb@dTd|vB-y%(vb5Ghx zL_ZJMrWKZ=%LC#uHavk-y)gStkshl4F)sF>^9*!<>7jXmI0$GKo2%;agYlLj!BD}7)w`wrds~85xXrM4H4&yr zb$1*zBJWky_a6s%?F+VIFOc91!NFBh zd0-tKow_=mZ>pQWKX}1T)4lGdqe+xJt?xexTIY9SFi(g;Q644DFs(foh}`YhX?K(0 z+w=6W)z6c+GR$I|$7e-b6YYb6t1E8J?CH>LJJP+#6n@7Lh?9)k- z^G!9D&95!y?@LGYH<8CBjwf>?C1VC-$0pm02hG7_kzY%5Ens$Gpmd=n0jL%A*>a7i z7Lf5oGh}V`dQ$F_OWl?$HXDoKEt#Y4XEmKA{#LKkd^*!-!1=1rkO-R^>};d#1ybV4 zm1=P2=#hjFK@^dYOE@wpW$2dDLnZVcXFkZqHhqjUW?tvj^u{uiVI^BWi-}KD4w`P;=-8YbGq@*?gGw~@H>Y(aPGSQJ=o7%@Y!qD_pon~-aNA1 zoL&Pa5$|yBL)RzP5Kku&PoSe^cP!T&P7C<2lZe0!$!sDpiKtX@JkbrIgJv-1txij36rJX}3GW1CMNDtcIg!BZ#2hv{rhp z%bmX+H4-TLi@)1@fRVzDSaYe?6ZRko!6RWdsJDR07J-x}Qj|Q|!4?PSV2AhshaRUJ zXJ(e}m6wdUh1oWBB!{`2?%ZLyK{+c_GtD3pVvopE?+cdiqd*(UwKOLg({!JSarg0; zqExI`X-H&qjGX-y`S8jtx8Qj~v+)Bx|w69YpUsHhkK+IvO@ zm6DPY!r534>~E!1Ey=iRBGZx=Oi)5Dy==~tW+LZ|XG{XE9U+v~hfn)DL)pP&DSFdG z;wXYw=%5%hr0Yi7$-&xeMk0gO9a|0Pg?p)DHoAg&x=aLgoA$*oJS+EC@>8kTMy(y8 zv#mrzLE|O}p|;rXhpVM*qCbA(@t{7a`5>aIOVw5qT^=G*+4Ov5uJt9!SkJ2Xqk5_Y zR|+{UbJ@9G?4GNuIXVzNZ=NVNZ}|n?l;nqAjlFcCn`Y*g9!0id>&faNbmq7`%80ON zVXvca(o-X{H@DnWM^(KmWk4nR=oo}nhK8MJ7&TeYT>HM#X5w%~zR>RYi|WSkz@_8k z84$?P;lyEgXQjN%*6Hry!S0&jSotNF-PMtjrM^r{V`C>P znO&6JTVe|ch+oV}l@7989y8`wO7pD+^;i(GCg*;bG`AHEpibtxZ!smckPS`{kVfjo) zr%ME|PM`n3g`RhRf3i@g<>jew7HS3<%R*P8rMY>2e!irXR7z6P`sOCxZ_$JJOx>rs z>NQ$q>h5Nq4E?Ki*?cT&-`1&;pxqI4F!&G?%{SNYQHHzr6Y$tj)?@=+SA+ITW_`C?=dSkYd>9 zHnMpONX>k-Wiv36;uRAb#=c~tpcoa_3{`Z)7Oh7|%>X zo3SFx>~^%;eDJ+z0R!Ey8I-J-&SWXpIRfXW`lc%xYa9eYOA3^SAuCmt_RN5}=4j2u z-$yjWe`Ew5FJCImaI~{p8;V7YS{t!GIbJylZg*TBGTpApw$&2l_Y!8ki<(6zPK2R|-?9v+XM2?mO4m(@{JD_w{`w9YCe(oaP z2zX=Sjc#tYJvjKSm|bm)0*)OXNyKvt-4BanRn{~8d&zQCB23}ITtp?bX2(<7bdNgO zdp^fkPEEzPi{aaF8W^WFX(+EI&Mq~)w1t#8mW%B9lYa1%m9ouTImFD(ZtQW)P#cVK zZV*uJ3e*#nQlMcFUkHo7!@M9!u5~ptT3|Mi>snNBIOYe#$o3k!s#)4f8XYN~aboGU z06tQo`(Xpl&)BImuP80=Jhy80UQ$S@G_^D2vNYEex2Bs=laS90;0SZCtgWejJDkSa zf^g5*W50i!4u!@}Pj7kh)(iP6)%m>K%7G^nz8gL@)xNEVCQsn8aB=0?o~{{tJu0?J z$`^a0Ec`gO^CRT_Gm?AUY+BVy!9#DuK*1c^Y8tAl7o}-xCbt1m0B8uw-)(ytJeRQi zoM-l1p7>26?tG^Bd(s^aW;NB6lMBtxru{Z#@H+0B90wDy9VP72X=y^L-WS1v!QR;; zVJoL0UjxRG$Ouco|I%xtqUGU#39)$zmJc$^rB>XE-==3dOKBdWwO(dr_%7|FzJuyI zkdQQ?xTV0nJ-QhA|EX7LaP2@U-SJ&I{cmA9@7n$WOswnxOpXYNPn5Tl${*f30!L5O z<)|1;IZL*MN5J1k>(GsnsJ>r~O%bObr8%;6qCLy0$r_IYN$ZxW+xN3S~O|#V9D^sTw z$Gu--`q#NK-~V{u241(m%IEylT8J{qPsO)h~trsA&fuiDw+_U;<>Qbo-*cDBWP?a=o;kEIFz{zBhzecbj7jO(pHb5^N98>u;t7)-q^Go7)GiZP}7;s!?0xLU-+wrb*)M#9Eg zD#m98?CmA2{j$By%{uL?uU*=F&+*p(v;7dAS8<^xK)v(5F2K+^7xMSc@!QQ<@gEbD zvxKRw=stS<5KiVZE%vglqR9MYSu7V}G1Yaq9-Fs(&2r11>qOlwkbT&xK%V{&P19H6 zFw`g~FQdRKmS(|)N@|c|!aKUs#pD{87P#wM2r1r4I5-k_KdFh_X|!f-WMvhbyP_nk z)LDaQw=PY9-Y^ICeCpgh;l-;4cMsdE5o8i54(h<$&m@7ZzJ8}9(OF$6%2$J=&J=BG z*RZ}%>jNHmE1`^i)~qJ8pJezb_b4N-&!51k9q#bD%jh2W+VE>zvhj9=LuG{I8Gb89 z{ts-l{Ra`o4P;hA~sST-PZ@>+ZyTs1UB}lW2T9U3G?Li)$d9?)MWs2FBad_mt<~F?glr5=y2RsA9@KsxCO^uqn6G8;MNs5JquM2 z_~W?>_`SKSxG?OG2MPv`;iBg%{kP^)tICsaSa#@S8FrHt75O(?ZB?%pcOzmM%&5)s zYD?sCT_y=y{J4_8%M3FzYgSw$fGnSikOxts6~TIOq~QE8{qC6Q9k6Ma%#hULOCiIJ z4Cy6zL&h>$KZV_L^UP&*N2&Lt)WuC`ug5|%UE1o~0+njPQ{y3_y2rOR!1_$DmPt9=2AAnS0^1D>wpWpNU z)xbRKZ2)|vH%neojy9F0{!rv8BxE%t;aegUU6j>$)#`)lYD4PmOcr_Ry1Md1y}6J? zee9S1I*Cdl58M1Y_;E?lQt| zV5n^Au#zG{z7*7rE=G|8R9ID%^C{qpaFKJ}XnzVeU#R@tJ z(lQheJ1kUQF3gUNt%MC{kaIZVcEp~QmA?M8y$y~%$J^5W?tp**SvNSXe0Cg}EVAsJ z6q74CY2j1)cca^=DpRT|W6E0VMIVcO)`+^7>a(DV$eCM4mY6TXdt+!xP_0D@Si|03h;xX{M0`lJ(*|%UaBe5qIiU@P`yf8;fLbsMxeQB6Ag5d{ZRqQW(@}G+lUfPO9Olx)P7B^ddl;A>ax91W+ z$E}Ypgs!f3lu^v>Q*Fkqf+#|DYJy;q_Au>RxcPp93-RyZHEsphyf7-(EWxfuqKndV zqMUVXN$?}CMy%f4$T{Y}QRdcd`zl@}IbSzXS*)3I({tO?7+O@765_zfX)SK2Z>MLj zSHnUVhxZ|gNUHypi~c+0&nxqJQj~eH3kBw(BCX*dgC?4I26Bv4FPtf#g}04Gy2C8} zGKHC8yRGCyqREAU)R@?WMm9(Ea6dAqv#4f8I=SB+Zcz_%*TJPsdqN7`5gQ`4K zEn!-s$rRt^x19;kqa>Wy zdTh0e%f%zhlarSZqs9*k(JsT>e7sJ|dIa~{_0qFA%bb@!>A}T{%}#Ml!cyCJ$Xtz` z?1^(IHgwWXqUo7mesJJFf`dg+#!iyAHMGecoN-v8Yw|0Q789G=F66Z{_P2Q?Nr6s+ z7v@uzwA7H3s>+}j2J@cT+NU*BOiZmztNH5lAy(n=G0gGTi<_d9H~GHMMLwY6Jgkrc zq$v2MWmU$iCX8QC`4LpdJ1lHitY{H>6^*e3eep(2AzJz{C-=@)$c}fTq!vcO#6n|m z-YK>2uK(gmz$MkmrG-b_8!pSAwBC{uROX49zIP&e&rgjgxA>Ub5!@Ge{WFYSy!#7W zt~|qjNWW<|&yKLW6P*;!+u2Qa9f?QGWnt_ZywaJDT|zy<#b6bYmz-_gcT3ig33l$A zWhi}G(MD~A5{^u@^txp6NiVaO9$&7=Btz^Hyhcub<-ujtlh-$q5(2Q?U-#$G(Li7F!_aTQ z*?|}duqI7*q+Z<%3AlRvIunkEr-Mq%Df1ZiG(zU7Mc&r}q9YCbpZl}J|2PvCGXnjf z!3ea!Cb({LutR57v)e6wBL_-WTY_Y@nA+v&bM?282wz1ENJePtwVcUa{-!I@d|G_8 z7^!3r0m@3|UQc#pGxVhcil6$=m8mF`(DETl{WwqqPJdSi{yWspSJtO2M*uahgA<&a5qrB^ zTVo`NCmfHq4?2^TZ-^aR8BGqAO+^{rIWk&WKfv=CRpR=xzvzS|y~72`n(Ks&+-O@Z zwX~^EM;pqxGi0*eFx%|Gq{vaUQRRfJwUfb~3+e^8K4yTnB!Cl{TRHNL>pYRW{4&EV z%vQRqQxlivX^q=+u9gICt;uv3s=rv<;Vm1&+|dgi%6G7sE0$f+)htL49WB;Yt9HJ+ z4c%Xy-RW&xP7$U5eIgv;TMenw__c8qNSLo+Kcxh%yjeFMe3%x&ztd98$Z z`OmbjuMLVu3dPIR~T{!&ne9D4p;5gi`qS)V%_)`VRPhlQkglwl$e+{o&)1 z3!XN;;s00}n|aw%0~NuJ(}9S}(~E+bj?wQO)0;~Kc!7cVxVLd`V`F1s;d#&n#e>7b zBBKdl{0TC%vUBj*?#I1ncxy%%5*i+ki+|at+958n;&x>ovrd6GHI?*(A_!#{E3L-> zQUB$;FzjTP$u3=DV>7qpkwycDB_S}WyfnAXgo(|}mC7#2ewkw{sOCtCy-AB&OXgB6UI7(RxdTDM~1*mx1IV9-or_~po_#nTf7quNt238C|3DQIcz zF}$mViWb_P*Dhb!2s2Wocj_0woS?rnsh`Uv{?=N44op-1pc8S%K@e+SE4DQmitr!G zxIJh!)8S74I7@3AJfbVQCTnW7wCNHSYyj?q7-%jHg42aam?u2P!b%mhyf;Vk1Op5Jl{L2bW)t-X4c=U$)W@6*)o`*%K?FRiSA0 z^7VEkPAyG@^y+Ly?++|xj8(mk4DS^jg+c0FfpI=KpLOs{G{f~BYmFH+moVZ%_mJ87C^FN}e}W=ArA=ZA|te$G?=P1Mha(=*hmsaC9wjoVFc4%#2o^bU~} z3_mKL>D{25+sWWGoo)H(;sMA{S^=%sbSQga+tM&yrs+spfqAZ6U#p%xbFMkJ&fmJ(oD-( zu*?R5J7Fy$guOG11+wceLMmG{jN5GQ+M=X$756lK4&Fr9@d2|CB51)GSjZ5o@l9(F4vpv<2(A2_oBwpGd(S&O@WiN z`0oCkKgqx5tv@#bX@X2Z2I?TwpTExlDqP^8px?yOf6E@fsglvru=4@xJVb1}$D9WQ0ZQ%b>JH z-@@St!DERF+K4jf9ZJ~@c>dG(nLl!a{})c@?f#DknqT8Y0;m{4+f~A13sRbi>lEwp z3NW5tdC($DJJHYzlIzsNyR~{pO+W^3uYY+JXM>9Gj$hJafB5&fqi9`*@O+{BQIU&! zO9^bxW?};RCvaA4oo`tN2^T1j7xIBlYPJ}o97QR!kqxJ3E-cSl;KtZn18_VYI{E|4 ziGS`rOmqx>;Fz3x53VaTrB)j!z!383_!dB1Iy&Go82(~5+j6=XJp9qo)_kY!=_nV{ z)3A2EVJn-JQ1#Ov(5g=X$rvuKCT^4}j5Dx4oo4(@rL5-b+;Rj;+VPE-2jUd5bW)UZ zO|OhdxoQ36 zYt6rGjVcB%vAtSONQJDH;5N5bUs$>&i+2wP6}Z<#-`(whiSv1D{aW-~q2WMu)_S~! z#6Nt=X{gX}3}U}@LP=P>ce0;fA)R?xZnsch>pj*UabU93l1Q(03~0#BZY}sFik5R3 zAFg!98ln)`*{px+ayf`1U|HY#bewpw%QaNE)>vL9wzFzqYS|vkS>iN5k)e3QVzsnF zy}oQ^Xw6{2L>D?67RIDMc;zx4lR;5|YPGxhQbwArsm^xF^-~eh;;oj++C)Gfv|Odq zSvD7?Ega%F+XAlB!hQ`z3|J(ZGd7s}DI09B(MdnGy7a4nFlWw<@|U115fuT&!+fb< z>O$$30>veI)=En)y8Q2o#&7A3?&q&L@Kc8DI6NtZ-Q5=Cfo;ocp+LAa03#|(J5{4O zXQbNfS*58bCoJdVBPEqhbcE!eAgWxY$z(0AT)W7qE04{jhXk&uBTwcFPSg>qWx8|h z?%pbo;{$hyr%@}?BMq_2KWO&ac@O~|w1W1wZbFgB6NJMm8FYO?xxwozeb<$Tl@Dcf z2VCZC!$(VHcbn@jEYR~mzRkA`n9tHLP3W(m-NZo}hCjrGnosLMmJV1&d$_gx*;atF zgK=^@J(y&WO2JOQ`P}G~zjMlU5xJtlOxB1FAGDCffGS3pY83+JYK+x^)_m%+_NOZt z`UhJdncn!NE@^MN739{N6!j)uYCX7^r}_y_RQW2veSNP^HhIp4{XJaH->l!`!0F}} zpFb26&+BM~;{rNb708?f%oqhbjM(Jldec52_2!Py=mK5kO0i3I;f*L%^>_4c=J?n* zXKbXZdg-a&CFwJZnyYH3XCzkQ#KpxZ)@dDF;Cz*9Ejy>szdl=?W4d8!?$?UZBCk?= z?-NlmxFPQcHO=8Cx&bSI6}V*1^*mJ2~~?9viIL{3>Od*`riv{aYFEcb)b8} zj#W@5*e>q~W?p6sPNG*UjrSJ~^~fv)M;-JXLhizAjwLHSQZkn_ zE9GwNP(>lVUR90eXtF+OF682tSF+epFI@v1+v)d59y0xpFR`S-|8Q>Kwk7|1eUsi4 zu!JN1b)alluh2(C$~ngC0d(|NXs@7ij^xD9R#Q!jc39>w3Eo?StQCa9Rb&l@F>rUA zCOXer+ zVs*6d(Y%zPRJ6WXwHHhx_UMuIW@n?n^bP!C`}qzC52E267Ngluv!DZ#AYeZhXg7nr zWUg>^&>jSB0dgzfOoKML^22d}fe&o@fv6m}0ps=}q@JM+*4uFcy2K)KBY+q}Jjj42 z)DZV3Ha#|8;%~$F+GnZOyWdi+5ht9}Vf+!iaBRPs+a^n>j^nDf4SXJ%9=iEgB-H)G zmRdMdeHEmyrkEHRtYK|1j$w3VZN7>t9pu(0g+<-I?X-mi>l+{idkKSpw_s8n;b@_Y z9Qi>}tS%4o7xa+rS!(&w1=3owrV0A7*IY_N(a(&UE|b>rQM&Xh%;2lWG*TiU5)+v8 z88&W2H4wZEq~$c6)UY4fhLW%0;uH)`;1o z74SdP-}#{PM)LC|55M)VPK`v&-0b{i`|quU!|DK77lp_~J;ar5x4TMSVyQR)?Dpte zB@feLN|U#=GdJx$oztM^%2KIpgNIrIske@xKzCeYDv5|3z0T*w)m0*3eHz|pyRO%t zLMs1Q2nCE~L{a!4A@O}}i;1D=HREeyTFvvD8=8r81evzDJezd#SfMS+ci(HHKpQr3t)COpz^oVO!Mo!Kzly(LXDgXL=(c4 z{`vU__F|^)cVh2l9Y;Td@FPE`#oT@bMcSLfD}g6z57rzW4)-sl6wXT~F|2xI=`vEb zx6Cbx(}f}yo=|9@G{bnG$3Srp(j0*V>e*WzrPm0OGije$CYQc2U1{$Q8PP_-I!3;; zklAx?gc@)%zt%_jlXS!RO#IKR_kSSWpa3Wflm~&C8i!UKhf&(E^>E9Y&#V-E6t`pk!30jJ_=WA4(t+yX zjsn0eedmGyC3N3J8U9P?q`V#}UaGj^w{#yoLxNe#;t zbn40TNRg&1!lvJ6y6W-ZKyilsUML=J0k{8!SsbZvn#1WT*7@%&ZtmP={kIAg{}qJf z{}VzT4{2udQBQz!#rv z^>kpZTW3F=?SJxqA?;Q;C8rKMhMPq_Cq`7+%fuelrk&_i*{&M8JnD2c*|5x}3*(Ov zB`3ZZ{^4TJpS#$9U&P?QLXGmbt2}@WVG)c>dR2h+D$ih}N9_5;&GnFvkWW(`RLP=I zwUR3z;LWxU71(UQKRU>~!)dcS+bZ_VPs!@bIxuO$ ze22?{Nqu(zDXcqB*OHaBHLw`?)8i}OG;43Fo-SRopv!V6PuhupN_Uk+xYIq_?>rRCZ4 z<3VjTp5$|_Lyy$!+^wMnl#0cc^}g2u;Wkd2tyM6+n8h;7;rc`_xwL`9mvu;q){98W zwcd;;N=l>u<9!7wZQ}HOh-#)>6B&eUR8o0U|%@r9sarq4dq}qG!sjw}3k4R_*@eznOQ40m z`6JAyBSagUn*=OIubpmwV|fu)eSP@WPYGS{It*OCDKpk6JQjjFf~QGQoUtfhH!;2>7-|ZCmXBcXu+ya zW)#bK<{THVYBN6!D@b~HVL8E-M8~vKwMgpk4E#LOf6YALRx|vqT8?_g$JtQYbn6gw@>I0~aN`i;??X|qtbf(g1-o{rJs`^a1dg&O~X5c-& z6>b<^MjvM{#KZsk95i!^L6nHvi8ePk&Qny4VYRE^R_?cTD`pM_1CM0W(XQNb zR*h0x>sjECOCOpDdD1CRa^&AQO^;prvBMDQfQgA|%1rbwe}~?Vm>9K6e_B1Xb|sR# z^JIFUq8#tvIXpCkr`l|3T#m3UtYssUFD^6?^JU9g zD{^~bvdFI~SLNHODP~9Ka!n|5)~nG6^|t4G`@9H7`KU$Cj848u-k&%~srV7NvZ~WlmD(Z8n6%D4dQc{*aqLT$)3uJymg4=&HLb4K4 zqd(nCPi@lpoS?+{GN`wQ+h^w8b=nXG;yE(tWjFo?>S%6OqR6 zY<5}I7h#K)bqq7lN~CfklalPUW9ZErSC})v_c&VKUeZZ@KpYv`rK}fQ*YG)u-?^4Q z%{#s)(6FgFF!WQqX zTq51xCi{ivhbLAgLwZW;CL1<4HMAbK_6kML6^IMuF6_F47kA z4#gy=y9jVsWToUj7{o(clTt0@qUSS^z27JqSxvFHKN(vLd2nphpp9DXL#8ej!&?_2 z8OG}|LBoU&r#!7APaM@HEj8p*kTEmOab%nLX4}RP77pgR*bPNbB^YERHca;SZ2lkE z$%8|PE^gO@00+b5sWuMYcQN8T^ncwk<1y4XGBgE=sOsqbEGSoW(rQF0Pj;#s1XCf7 zL2{R7nx{$%Y6!SO%uSC5wQMa~yE(V|cYi;&?z7eNp0m&Yd`H%D zEf@GKmiNp(GxuEAToe3w6$dzSmjB(cfA{$~NX;L7{vZ6_LO$tQadk=sN;X}#me$t; zgHj$I%u`cU>+5YzO~rkE^;IRxZ4CxFA6`@jh#feZ-F|Y;{@_v(;5VM1y8^08AScge zWI!AWL?_C=;SKi2y7AW2AkdbW}e#W}YsFEpl z)-O)*!Xk6)#eG<)H$ulo{2%IHcTJli!Re>tw)^Jz@^kdq;}Lj>D}?rwFvGE%Nr>w8ZRsytE*dWXjp4%+UV;$NlfZY zPU+6f8Y(TDD=D2RDxS(O7_F$BkBn|g`P!3_HTccl0Jr+)N`U(`H8qu$l?4R_`T6<% z!9efZ5a&=q6+M z5y}WcNnTtyDMFA83>WPI4^oSG4(qOFK`Wsu#YjQ$1fBRE8x6GKD|!4!k8vLO2O51u zMZ<tgs|t#-MIa5E!q)xE{>iM4CRt2 z7Ev@q;cLx0-tNUmgT$k9R3CO zc}xUPN2?*y;O-1*#QO`9m z$xd#_MrL>hzo;zM&zXYiAND?T*}!?kdwZT&l#RP+wc+53XeNxTcp#9t5ljIF<2}qhmx>(<^f)y+X~Dl$0-%>3Dc}SXd%n5JB7?CO%q4 zM27mHMr5vNQT%`i{d7;5d?+F+o*(aiOX;IoAwdc5y6QzMMtD^v zM?xRVlx>ATPsxL2dJ;ZWTXHLpRP;htNGTJ^4c`rxDP08UO?qWsbE><-W zOAyvKGiL9OVc_$8VYP6vXgod3mHa_#Ms9;i8|^XylgA2wEJH?T4ZY)no6>TVCFaiK zx>iH^nkk$^2d0m{OLK4HLdBlEXd2FErrsCwJU(dG>7>~Rc%U?NbP396ekCx@8(vZS z06sVAhRw=<7#$;=BCj`r#!zD?Cx|oF_F1aA>6w54bsuEMt0CWVBQnh>)>lt$<_Fsc z`JfSBFJ+uEV7G@cqC6C?Lph)Oco56F7pz0RHYXQ3)&3x;+~Ku%qU!9mkXE4ofS}J= zNftC53m3TR#dxSRtY^BG>=Q|9MLxadK-O4u?0F$v`O2@*Uk^*1k5cp|=ATT#F!}_j zT+zq~_`@vRut%ELWaXu$TnSU3(L{^h6WOeHr_FP#MAv2>#kTfWxLEb)r(0E!XAsQH zfjKPqK%z?oCyhD@)rE=HC!T-4r?c!qIA~ZOro{k>f_IB~_pI1iqF^cko)l9*jrISU z9sa%vC}3x1YVq%&r0@GYeb7*PVr_5wk|kDqZ*Py_1);`Y1lyyLi7zcL!~Xf605ntn zcu$ZL0Zr76OegAo+Xtx=hVr(}V8plxJ(_wvtNIp&Ve@ygEl*y5IXM+2n>qS~Z>urX zA5|GQIKS|qNyeL#40a=G`##rsiz8vAwNX(exFdcz0*yHeE2pa_o*0LKCtFK_;i*w+ z-P`n#@%T18C`2i{irzA;Wrr-G3T~U2@%fkq>!U?4=5m=v?255iDrpeMHOSxp@o!uC z;xuW>#soxU=AWYS)-Rd*KeffLjDtTLvVZMX{bmc7h31;OwPkGPn*c9+wTJTvkW@Qd z?Iq-Z35x-`TKsncfGOWq3cg9IkwF{wLV4DPb=zZSKZ7?>A+^(2bqM@axSjjOl6E)R z`G#_|oagfMV{aJJ1TfQLH%SCDQl5`LXO?hzWyQzDPR$YvGkL{P>qG1IU_V5i-75o` z&X9Q`vd`r2RS7p+M(YVX2nNU3Qe-DJ+T(`?TE=GN>-*$#nKDf!H$?{n*C}yU7<)QY zSamZU##Sn*W2J1iq$RZqRzQtdZ8mdL*F~v5H0U`p{YVts+nMqB2^0(iXffH(#Hnnw zKSzXyXUj!%S5JI#4a{MH?R)c{qcnNT$Nc;) zkIQzg6d4p%UMju2>8rxVXO%yzFtuTDh~UYxzslG@N0j+(6a&_4bnhy_8^-^wNBsR; z^-d&-Pgh<4pXQ1I8p=NgAODg`k|4OflS#U9rUl2{*sL7MecQ!bRb_2$ZHSNmluVq9 z3D{i4TUT;^*t;`vY_Z%)3AoTi>85~^(mLQpC$G0cV` zp`p&s&iHtEOw7#MT3SGhA3Fo?$F&o@^abH;OaQm!(>V)M1tZqliNk#ZIyU)ZMkS8m z%whJfI`izWVMR5rO{h&Cj}C}+hnd8vqQ{gy5wS>N8l681utyKSOtr&$FC0R`Ca=wn ztyMva7PmBzWe=0a$kB@$ssxfYBk&NhK2T~1H_4mYWT~(=Hdm~3j(qydO0oZ$NWZq+ zO{*SYzO4V134guUfOyKECWPdJmqMYHw^Bdu?COe4m@M4hxv7x|Byh1_ z8EV_fi$}XSJ+a!2qQ4$H()V5kvol+^_LKV2cE>tu%uFpZ>f$LCoo%%~D3{BxDl%HH z48S!po-)(CEORs*RhlY4T?b|Wkp9??cyI`)Y2@T(L#N1WZz}?BF*IFMT<2=a1c%CdSF73(mx545U$UQs0?E1J)j@g3hM0WB{JqMTvUTwoG*WDo{}oEuoz}$M({15U>Q45NYLIY)EkrGPI$el9UFF(d>P6B83z8Xse2 zb8~ZjeSK?dYi>?WM@PrNAS*jNJ2^QyBZC|$c1THE0CkoZG(W0%Eqrvlc7>LbvJ^2? z9k7|&RRXV_V z{n?7uTp%>)6j|$gMLGB5C#QP2m`7ZpUfJjrplqhyDd+m1ZtZ~0l^%_jrmt(r8FjZL zU9vx64|aT(fm5|kUjfp5J7_Z+HJ7|eI%XFpsc;50D&Bn*)KZXJ77m}aaqT9dZ%)iIg1obVgOfCLN?D~hxc41punitJ_IyChB($TT(#L6^*#rihIbM=|TM5)?M z=J}yGINDij#UC1t%xJQ9d%Y+XbETUHq;cM&Ez;W?>u9y;HMu!5^S<=ppeS`Uf{Ld` zZ@y!^7};pT&T%^?Td{mfvH0TP#Q0P$kFDHsbWse~bZh+DZhAt5({_s2`rwu0<;ccH zDm69k#pS7u?QRsCx$B#@v`i@!Yg{Lz2y%-=FaeCV~*AS^^{9okAj zxwtW zW_nkTt+CPryx<(BopW`Rz7U}KT@~1m3>9LF;~bqHSAD`mIH{7|DznelMrP@?!XmSt zFb`)S@%EzLLoxzxHP`*K(KuzlKyae^VOXZ-yL{Zub(IYp8k>pLtuk+x&8_!mi7KO- za=jrv9D}Pa3tKUSd$}i$a`&Knub{IrX-dMv;k&v7(9st*4D^-b?|Dd$47Jl?we-Xu z;Ia~-b_BL;n9h!T?g+ea;Ks<#&JCB!oPO*ZDp>OHz7AKdhq!IO9=CK>sAyTJpe*sD z*2Ms}IJX8fG#?%0wl=LQY=0GsVZLN57S_r0D?Xah*^w2^LM|o+IVm(zk{BEuCgT22 zZ?PWV_d36Vh&FoUB@yfLp{o-?O zyK%g7Bph@RcPRDx@tQ4^oc!F}{`I4eA7SQPp94FAU?7YjPimQHc_EWnAV?@kyQq#A z5+U_HaSj^`arm89_wUCeYcnK9w&p!WEgheb*gDIxSbJ+J!7rrmmr$yVZ@YR;(ANX- zWRi$;vl~on(2{pNi z$Oxyo)Oz(a$P?63Vj8XIM->0zs%7$%`+z-8V>o1!qly+ySoPLrV-+Ku?X$rY|9RzT z4;Wu6F5k~@kY%Y@uJ~UHIAiw2pCNqWo#Q;xpCN4wbXUwL=B3g~2V=&m(7kyYcf1xH z)g&~K;cV|Oy>36p#dBIJb$sylKp+A0+@X-px|Xg3S+d+yb?)=zA+O2{6QAeePEmzn z%KS5=L9{5fHRV-ncA~7%H8n&O=A_*|yq@s7M4fWN6#}+&>MHvuUyWaE)Tt8I$p&VE zu9|{|=lGa#9;h^bfF13smx`p7QORzUmWfo#oj}xyRGvU_kySugsiTs0J13PP4QD28 zxkS^b>*j_`=!WYJmv)Cc`GTh5)_wa&OvTm&b6o<>4XmG3nSPC_fB&c!0wAaVd4r>c z7HDu7NY;||`^&m`JN1$>(D`OFd6jE9(i50R?TZl^D9;5=&+N*urec|MDU`9jZ2HP* z+!z59%KV5pQNs9GYP;*A)*vru-S3$C%_U0}^@>`74L3&fS$)&SQ6W6a`w3-kIdo~N z`0|hHKE)oM8UtE^&~N0Fovu0tPSN3TLsh0dQ2FvMQeZ|~OLVwT%BV&sc6eldo2tP> zm7$$G7>f0$*U-){<=TI0jbEQae?r*5wmAO7c2nvf`?6}}uxCx8z;D0K?LFC7O8KNJ zsid(Gb}Tiz+)6MF8klvOFtkZW!&bzPBe7&k?_?ywi4xAeFF%lXbD=mApS_aKmL5xg zL`ExmwsqVZZYuB95bGJLHETNJJot2TI@ikm1Us=IFqEMKrd<(%^1#ls}MtmWKAS zjn~zv4|RTLufHqKY&o>5ou4p0<#2_?VcNn8N|^n?9(F*WGj0mh89qEyYC*AO#6>}E zyyIC(m4lac4L{?CltZN?qFc!*oGTMwt~R~WqGHe`OJ^i9l~FZm-xU~c7-W~pK%Y2f zcd)d<-9@|AGg~viaAi4}r!ui?VLga1H++dgpyG0H?Ngq7uDD=siO z&uh2WGT#KOTRCHKZOHWW1Lr7NYj2jpDVEJlmYjnx9*o*?DhXBi!JMCeU`9@9lf>FAd| zB+6JRZMyy`6Y^j?uTUyNo_bGdo`?vf;-xC+t~l^i@WtD>rsyYc!o1@{JJfu4q*sYl zSXQD3qp=*Z$1C`wirhiE7aU@Vb$#qwgJIN+Tya>TSopuK_1P#-$?_R6^3Pq8-CyFu ze`MruK>-p0`uOUN&}%k!bu0)hh?PGvN&uY%ckOj|?2Hbb12APr+h$wK`j1HE#Msr? z$OWisz7c>XYZhCY)_Z#n!QBV#t-!zBXl-8a0Y2Wj3qYBj?c2kHXM_DG zy=`-N=o|n&`+ARhy7xLewnv7~C&sVGMlVN4E+)pWMn}#Q652B|2AY}<^7F@wil%aN zhbt=P%gg7AiY5SrG(Uf&q-3(Vc%rs;rJ`aM5Y4KuUj=ltYHOE4phW;VZERexsaXVp z=38608XEyDb*-=OxVQIcaPTxHwgmuHzozykCUvBy^<`xbr=|B50>2_}EH`f?D|;|A zYXCr63xMBJFj`f;SXs3Y9ozghtuHC1D5yi;Dr2{zqK($G`ux zG#A|M2Pk)skDgxMpL{;qLih&;eD-yRfV2*ej0ms}v9&feG3V7*)ep0_4GB}WRC}pz z#c#_88Ri?Wp<RUVZ&stG9wTM>y6aXc2E{&c}3b zA)xqpUWMhnZEw`}@P%BH7B_W|+=L?e_^J73Zp_j_zG^^fO_bd$x2 z7^WD3$wZR)1{U-blKs{|1O=66%qEf8Dpc6f3A|1F8tyV-zqCd! zn&|bIPJQ6{+|aX%kbBeAnN0b~wNSu5z9%;lcYC)i^mX;Dh=5KB9g&7Tk(9Lwk(j=w zg{h@Ipoe8_Nkt@NqDe!q2S~L$3ghgKyy?I9j?D8a{r=fd* z0Ks|px=f#;UPb}hBnUsXN`Ad#bb!tN{k+=SJ9QU8R>(&G-$c}#tu`QRn#|g4?j`HK zLFVOkT3csNYR|OAq;+C<-B}FStjkxvHa`X5a+cpJ*PR^h#Jk?LkSq2lj@A`zcWYH; zM=a0w4xKLv5;%@&IIDLWJ!y5ppvj`;fiy8pC+9D~?5vDrKQLnY4Xm*G6d8GXryw!} z?aM2Vg^e|YW%UB@b0XH5Fa9%3yS4lDSv2&*52IHaD;8SB&{_pB$x5|`KW2*ACWKXz zwF_;426|#xpx28#;f%*ctMC|+cOJ%OkWi+Qr`4}uqY=9S>jF?QLu5qUcD; z8t7OXo=;UuU&+rYa$5GS6c%qlWC_cH6)=*=t$Nk-+oV5am9UizfLNLNQw{b1&yL@N zCMxvy{}nU=GDmys1`s6yCWnc!tC6Ae^yJON*rlzFzr9^xVF9=xzvoLzt-D)fVL?xJ zR%=FjQ%P}OaZztUepg|^a1Cg#xoNGbaiyVtslINps&eXE)N5{9ZERQqRZrg$KEMav zUAsWw>+d`2>pkcN?}K~xdb)SJyLP%d0g=G1y4u;P$y*>M4iB9U4W3L--A+y3Oio+_ z@ev@4l$TGIl}(hEju#h?T3h>9SI<^fPFGY+m6VKHSbS=11VZ6Lb@fbZ>qbMvQccZV zXXj3P`(|6)Mr-SOOUqhw^J-Jm3J?u@dk?_i{qFAF&d%+&w)K>h+7BNh?Ck^l`;Yqi z4tsm|!Qj2l&aLe1HfQIMsj1uX@vE`1%hAz`k&*MhJ|F`26&3ZSr#DVb-AqnikB**a zXSZ5ec@-9oMud* zJ{GtfqWprmS_PkDg4kua;1C~)Xhx;SA@k`zQINK7J4XqpNzIJIPM;e zgc6Iik%Ioav|&g&LjeN{9TYu9wfRqRy$?jtKw(0UT0J;l1wxgmsd@H5BR~w1H-x-> zM=B2cw)?|7O#yfac_uT20#l5HH&1o^3mS;;d7(k1L41;0O-gvfyzImm{NjT@ilmp- z+-Ep&hl)EJz8K_FpHE0Ifh6ZoU?39WKAKseGSo5^AVffMzo;JNopf%5m` zS#K>&&F)q#|Fas~e^`u4k~`oSK$OC3$=@a&NgGXuYUt_E_9HG_ z-+1lcY>c7w!byW!Sc7S?Uyo5B)yPAui;hNkxw?x zeo6AT2KGa~6~sA|x6LjStL34)?6Zf1WL<=#g>(1P9#dEu+Y;FFRujanSDQj^DD zU#-Ew|A4>QBw(BhQT7mIsHHzthqIS^#?{q6$L1w&==BnYzNc{L-wQ8QXIHG2wW&qL4l5btfk`W|^&e1FRP6B7Qllnfo= zF9}Ss8qXHp`{{K1dN=kyVZ;|r&OEGYr>oQ|Z^?}qvL4aF`u>8TbWmBl66uV{N5nhl8iA&{`fNi;ADvlh52SQ7R62a%LYldhE;{Bu3 zx~*+|8FDBbvG=(NuRjZg8;E8)`J|`^=qThSy!`wyu&%M7z3=UPzSiRldG}8mV@O_} z0j>6UiS)6Uf(L+j=bBY*wQZsu5mUJ>8^L`seBz?wE^3FDo$t1}Yj+4FbR!S-R|QRH zRR^R?hd9r;nCRI09aKkYh&_X-7Q`d@SuRSthSTx<+7=N!q1=h)TyM}U(B?QGk|4U7 z3(Md?M8FK_O(F|JBtmsk57tZGOq&#c9?8yW!SVL-%o5Q&(F%a&JCjq302mvn&ZK^U+?--Bu;MCWYS&HFX6~N|zuoe*FDp z&pfhEtCHo-t6My7CiB#3<5J-atFCG%D@pQgZ#A)6qju>qRmIwYc2u>_<9elp4|1o_ z`ChR7D1_8*B9(jCD)=Dp7O%DX8&}A?ig(#*YfcXc*k6AlH~o5t{~jECr>$e5ZK?Nb z`{2)Z6R-I~vi%{LkmGJb;ub)j7nYZ~&E_DWS-vT(xOv1*u!C5Q!GHA0h-bO zeS#FBb|joM};7bAtu+(#bsF6#A;Qn^yG@k z8Tk77r$Ncnq)2-cYfA*&&x?J)}FED9?+P=QZD(Z#SbRJe9Ps%XPjc6SH@; zoMp&2es|1*Ex%8oEn|Vhl2h2Ij>eYd;BZ0mj1w0_MAVm_Wq>>it!E|`JFS)3huXDK zcwR^}cawF=^bz88t;lD-{ojKN=Hb`eV+3*$*H0Dye`5#UhCN3T~g>=R3AE-~Iq~tOVm9mwP z{IW5wTN_Ek7-;~tlQ@oQK}^)Yu-1ZSy#ZW|O(sHTpKB(z{~lwmSYy8`Ondzi4X#eE zQu$=dZ+old3QX;&16IrV-&pR~Tl51x0g_#wT>!S_tm5pSxIfWSg!wA=)>~^moaMY$ zw%c)ib>-=fZT{IT68uQ(xS_1Qc>eD91hSE0Pc?= z!2OvlpH{A3Spc{{r`yg&K<`tTb2pync)xu24`B=x0mI+FoZxCJIGXvyCwMJ3Dyk==;i! zF*G)$ttv=Wy$?Gdmg>5f)q0yGbX9XvquG9eC#WjsA<#1nvpp-bglf`+YsH3`SQggnUjji&peIg7pa zBYd||u^ywXnB*KJsP3LE#-$bo9chANZN-q)!X=0{k5oJ;92fXTV&wJi-g)EH_@}08Hepnxczqh|Uw@4T=2#Z~Frq082@K&Cot=z=R z@=uL6I$ot4@vB8I%Z!Yx68$I6>+$k~A+oKlJ)HdARTH6!J@hdsW z$dX<^M5GfnHA2cp4~zks8Th$wbdQT!Uam+emC#96)mhmO;?;?vy?-W_8TjzT-0JP; zF-vLXh2{>abOD&(hLI4~l9#>#@`(6Px#U;-{5^L1hl~Hq@!!9&Q$V61p4auJJDSlO z8GoYA)fGtE8XClRfE3a%(i&u{JysRa4uhl$94 zOaTM16CIs8H@6AU`s?lO1-6y|t-rduIw1Q52M3#&m;lM>8+P)~FbPcA+jgPsT;!$P zOPWY27!f)aq^y_}SeQ@lSc0A1*6N@LJt`&-im?x+6!}=-vY~xCjyX|nO5(twFQ)C z2t0BmJX}m19IQVb195CrY+76hYB+5SM0$QA5mX`p?AQ2;OjP9@xV(zA!Y5^Ub@}jB zft5hl4Q3#-V=S7%|f|snA_frS#K9_%95nt!|#Ca z>+>GBl)!Sxvg3K68U{88o39*|S5=h)Y)a+I17U#jUS^Dfi<4GD&B<&&eQsa9YsBGT zc$>P~lTA~SQ`J{_^6s`Zn^SzcBewE(Zg`a&H;D0T#~uc-Ja}_siraak!Sga7?;Pl_ zEq6uQ?o3qzB{NXk0LAk6N*UpMcKKuaVu|ct8HIN%Ad3E6*4Ud^jwU+uup)xzpk!kN z`E9&au}-+K_$Nu-k7A&hqz_W14V*V{3iLHJhgIV%hx-!RpCwOop688@9E=zVnVpR6 zorDa_?k?(R9m=Y&4#`rh&&@Auyw#jrRWsRKT-4a_Ur|Hvvx!}1?dlmF)i1wvVSRJY zkhHvh5iFd{qs#QaMuZ`Z%kTX`+Y#Se2=xc-Tk}7$@vph)$GRCH%mYQUJR@?RioJbX z8QkS554*$Ja7YX0N)LCf*8Uy+-4rN+7rk(CS(Q|Q5;(XiAE2{FCGzIynG6H$_7yNU zz3tBa_9UU8kdUFCUQA3(OH0eC#2BaUPNseJ&XIA&MD3OIs_)>W_!PU-vG(%SQ{_!s z+x+UO@_FIgR?1NVS2pKs^M)MgWj_h@UUuo~E2C>)%kV=K-ENLJE_2jBmn=P{u`zCI3&;)IKwZ7q8t`ocHarT-DX;U3XjE<2Jpzg~^ONWJo0G$wRBG@0Zg?VHBO`Th2W@Tz=ZcWXH*zy2mX;F*7%Cqu#%MO&vQ-KR7YeC)m_ZMMqBOo1D)W*56q# zC?!N`aeL$8t%$NciJ6jwXRUpEQ0Cre`NUT^rfT&B-#}B#E-Cj*UYafCp17r)!JbQ< ziK6Bk%S%hlyqSdhR=QNSlU6tHfNs2(@~ZE#7+82WgNKfoJK#axW2}7RCX)im)c7;+ zE?^I-TyU6=gz4;T1O*8!mo{3hl2K4!hlE1e2}Jsw;DBeF7ucoE049= z*o4RO#o&wmKH(-E8TjH}oChdMgIZLB{1mjb?9(}suBYwY8nE{a(@ma6Y=^3H(2@Tp zTD?qvmmwKYN;CabP9Ob}8~)**V{8erIG#FTCsXN*g*=B3(!|g(6nBdiF zAT=m4K7LC{!Q*_<{7>-179g6Wl+*`o3zCpgUyhX%4Zz9suN6|yEtQ&3vC+u->vc<%B zwRLavGtQ3I(eCQKC*K>HK6j1G@s4^9O<=>F@CwLZX467tSJQ&+oOIQ}=hfRi&)dt# z2*}SF8O*CNa=Xo?9&st?5oA2=&(-OEzfNRzq%prSMRA@~jX!U&!2sGq7owRosk5)# z94;df(uw6yT{_Uiu!*HgjRRen>6C#(zA_+MYGRBC^)QaHuh1$Ld@w%IB89sbIBpn` zr#NWDJ#9t2`C2ADzOlG$lU1BPgD1mbt{{T=cfB%oW7`0$67+c7CIbsNS3VsdokV%})jR ze|MVS%Wrnb*8i*gPKJQUd+?z0_3KtCsX|rNS|g)&E308Qw}rH{>7pW_CjSTc{;m8* z{sC}@3GKTR;VFjfVQrG}Akh?JAzb_9XI`=Q1ZYt`^!U8XPoMsz**KjN*`aQ(ubt~c z4;3SCoTNSJ!$-GvV-rX>@|Ppjhl_G~+TKSUy1S%^royS9+enM!z=SGIxVN^(3lK3wXjDXN9a&c!JhHq|aPyS2Yix3N_7_iZStk;>*6XaZPlvNp z^Hr!_j}2OC91nMARe@==v~p8cUKbEOHTB;5AihL`k%R=w_0_qNxw(drkcE!U*6HqP zSC{2%ZO!G$c8#xZNL<|3b@60xPL##r+=}ihGN{IOdvvpH6nWRdY5uGupiAz!)F_eL zymvwVFX*o+3FaFM&FOAG+1og}0$05~V*?X?V?)z@^|cL+qaD3XjM33yX|%1K#J*-C z{iM_{smT=S?W>H2?m=z|!Os!1y+U$epcjn@&8am-44>&3qr=kA7^7hwS&JHD<%(Gk zEq{fP%^4VGnCNOwu@;m*dk^Q4);e*F%PO*`y1geUHT=H5wU+<&TEod3cMIXp4Vy9> z3PdDS>|8|jTpSlFH6HND5r>|kc~j#n&^sL=9&|{K0|%-`1a^iH`-Vm&cVcd4IAkie zg-L3ihY$C38ibe=IiS!*qGq;Fbb_M#LJA9>6J>f&iBV>7}=y%oyB88DULEj zGjg;lDvF6};NK_wd;O(UNEaBCTlr~N?pGiF4+STG?f3ray{_vT|SPgTducMsCU+5!n`te4t*JmB(o zW?k)fXZ+G7c-gGhCVFCbX;fWYmfDY-yz_w#YDWt#WSBHuz@m_oLQU2@6=(B}p?KY1 z7aqI4^%dZmo>x<0Ha}l!dD3DGz?|3>hTXVSsjxQ(Vy_t2LnMnomfZaOpzn=r4}x!xwLPu7)*kR!n;D%OzZ=ioXz1&2SOt$w=r5`1WaYLHFO7^g zCnfdhYj>rlr%|oa7k4!Iyc&-38COu1^c-!nE-R+0PJ@k%4{)pEYNA4cd`{1zY$C#m z2HjxXL$KhRa;4N5apD!Jz{O9Z&1BWByi@8YSU_QIVygIj!EWi=8*bnYPYIpiVfV%I z`O`hPYBvuxG!HsLOvK++-1Q#A*2H8)_=JOO;t6DD;m|FOACxV7;?LAxOeGuRrjO>vyk{@wSZ^MfIgS_b zP8*$`WjF<<3IKt-Z{m$=Nf6&G-KTSBX%`JOMOQV0Z__4WL?a(%qyn?K4X3c^7Tp)z z(n7HvxWRt$;yH-XW6oRdFKUsp1>1+;YZj{BJO#_N34{mujg8n>7E zYt0D}F5naK;Ai?e&mhH^qGps&R3{& zzime&f17z&1>gzb@sfDq+mA>i!CBAXDDF{%~JiFPy^@Zg$RkdeN zwOv1gr!33mtTY=*^DJhWsk++e8LT@s1xW-_@94)C8&7AV!R=7T)@e>&gvO5IO@da| zK-ineTUBOSv*Du>H{$V3w%`)$;++zT>QbBY8|JPPYSoIxn;sO2T~|er znwX2twvPv()KFbxbM6NGlyJ=YcqR4p(nd+4_^Q7Dy1dJGvdnar01ppHw((?afI}I+m8-9#RsA^no+wrW90-@ ziU!C6OD``ZTF{lvtCgra2x&19=X-C(m(DYGfO ziMl%3XE2~Pwor2@@Tevxowi_(NW@N_7j;Gv*z_?@W?LvsN*@)}5ymmosX1Y}ZU-GSg^=!1Mu3D=h&3SY{E%3!v&nXXCm zOGtJx3>hWb?}}jP~-w=wMh$!oubvO9gZ7+r`K!pGDKlI=P=x%Byp#XT)J zOv-7w9nur-I`P8QX*AtKh~nA9;&IQ#2CaO_#rNKU>Orz^omwy+rn)y$X0+(M3hT&O zX5j0`(Jb9wi6CXTCOgruGbIBA-Xy%kEa+)?IAK11a7Nj)&9Cn(E44=6ghr!P|T@pQ58qmld+ z^YCo)wgL7ct8gXNlc_I}zPdfVWuM6~ytQ4m=Sw^0W-J_3^6I9Q92ZMWO)E}}C^u;% zl+j72Sipj~wjaAtpJ*ZnG^Ryx%OT%#P{rYHMem@Ao|I*C+G~m#(KG0blIIwVADn6W zS&Zd;5NmqrQK3k-(Z{ot&54p8tA*3z2Y+59Y=G?wVuI@BMa7R;3lHjku0`NevZ#yx>jH!8)k6{!_ku=M(xT26}#kdh?<-nng2QrxhF%0T9qJD!ArpM(*TWk z07tm7&Oox1{B+)Q=`g;JS>6|I(QGS!r0AtRkgWb_7RGd5&GDs$apU)wCSex05(2V@D?A z-e-H{tNwK@-F2SqjZ1{JF{X3~+`uWAPN{ed&N-vPk=!XKQPrqB9cy~i$!2A}HYD&VWtE#nb1#bkBNU{`jBxF#uU!B3n455ZhKYI*d`c0{rcUp~_mgR~%rgxPH!nhZmkxqL<+8+HDK9omyq zT)fjgD+8Nbk79V!UGAP~2MM_a9JHAsi^Z2OTwJDK&^%vzeDYw@SO;_#=F4H1-%`1~ z_+Ww6x4bKoB;r}AooaQjCe9|505&yj>Gdn2mX?Rhp+1t$mV);1+qT` z`Y}ev#z3WljfM4HEQDbVVjPL66sda$wR%SjzCbHO6y2pz?UKWV{t@~LadP+|gFAK% z63jvLXs$v0CC@YE{!-V;c|2CHb2mkjn{&ZtEE~{)B<7HPq28+~10}~6{-p8StN24i z3O|NHM&ZZ6dNZWQAr$EDB8QKi7(@LI{3!iI-dXxtKju0NIev_1Y4OVzN9*-N}`8`HDMzX8K%K3wIT0O*1I1F^O?*9A*EC08L^}Vk}2s!sd zUn}Jn0;n4ROc{WZ0R$OFm5otJ5fpAG`_Y^<= zG$;&TFi)ZMcFN9$R!JFxZcL4h=t_?|(Ina^`Egy6njSwlZk^i)BJ#&UnHZ0gmL0M| z&z@FqyR>i@22AmIZ~_#;D;1?tDfS1WFT!@?D~yLt&{mt zd&5iGyehN(K>n5v_9{e*TyPx6PCB^2YX2pnjF;fk8T;Zi+89p5>#XI39h2CRTz1Qa zvHd1ERW3&k%Xha$=a!v*2p1fawkG2x>chUp>EbIoI(SpnWX$yDC*9FNZvt5G2e?XJ zb~YmLg^YZ1bOexYw22UZgy(>FK(?hG)n4BtKb`l)Bx(f#e)MA`FB+0AMMD?Yr=s!k zD17c&bavzWOz}xpRTZtiln@POoL`hLTwlyeC7ux`7N{ll58wjDy>zcC-4{2n;!?U& zQbx)J^WcD{K+5hEXdBqfF$%uXLq+J}q%F&y%d(uAnVWWo`el{(@bBAjI*kQ4IP7de zxZWNV74g=&);V6<%+A!*KfJlVJOwtHe{iXDJl(lC-c(jnB2w|HNQCUT-jc$>iox1Y zoK)zFjoq~Fy1cOR+~ll&wke*N%vqV8sw884b0s7dQ>5tmQ7&h#eFscQm6bg!t*FFS zt#2Vy87jqMXkr2mjF|QWmX~*NGMw947-%^;P0y1a%UE~#?E9>4N~luy3WHXKP`s;)B9}SRyxN2NU zOJP4_F+&78I#q7|bXWpQ-B-Jw2{AI;?K;_slA6rh_Fdk(+pF{I>&tSWuRvpfsLad$ zeAc75J+}Ipba&5tJBz>_cj0Vu+v9-4jg#D+1ZLxRMpjEcnr~Q)-=A)+ho(yq5ONjF zz6pOa@M%;gP<^?GG&_Q3qE`RfYnbw6XKZ42ybKV!%EcW`87rjUTj-Wsq<>!G*$Kl_WLOLN;dXD3yVSq!Y$Jv9_RVF zRKLp+E7jVDsq$1$z7EnN;4vCjygnY`!bhtvBcO;Y=J-Yg-`KD?yC<8=Q(EcOXw+8K zl2u9h8M2@8P_k`$bH(zC42WFKU@rTdw0Wby*&-=G0<0CtH=q2d|6Obi7IrC1Dg zkV1ZbkIqbW&9oR4N%%2l{7j(Rro!q1R!ml>Ai9ubZtk6F@Mn2jtBAM*tHfO`0?UPZ zzWk1!ycF>WKcy-DY3z}YMpKPLGt*6443z1IZ-u)CrlrvMZ|Kh|Rg@;|P@;Jbj_AFsi;J8&YY{fTMe8gQ~2$5R>=PzAvKL8p}M zPUNktuKxeXd+V?&^gdq{L_ib)=?>}cE(H;!1?leYZs`UAi3Kb`knV;>cXxMpgXAL4 zV*AdF+nIUKo-=3PJNLQE$LH}cMfm={`H4A*=V^R=JT%^~@dY_{4=Dd}?6wkt�R5 zfhj6_8;C|>{oZ`xdrQk=*Qk!HQwfmUrV|Zw4|WjvoC1Fy2`MjG{B?mPe7pqLhw4%W zb6Kg$5W`Prcb8Me&ed`&-e`+YKs@Qah^9}%2na-YcoG?a{&yyKz5Wn$ro_qJGLEo| zYs8n}4c8&#VvmEnGfFVz3xr^-YjitKi{ta|mr{>+Opmhh&h7;@xC>>EZYLw^0<-Hu zCCe={>{=-)3>O|tSugie_&rX4^sM>9Ux0I1-r=5rdYKE9y zYd2@vGM@KWD>E@&@r;@Y+__#ex7}+!)AClVdukXNM$OUkz!R`EX<7la=$pePxbga(l2=e5dA&5K3 zW)!BO*5z!I-E8vl?bX)S78KAypbsP@BwSnxkVmLP{3{3#of2{X0WTpjQB8GjHVOMR z$Q49d&y!ep-GH4fZM42;xF58f)Y;S7X#5JE5m~S;xk|x3bc#_$&`fBK&$8%%*JC4SVdV0i=2%Uz=*R2F$LsdUsfL`QN zDXW-HPXkQMR1(xJG&d-|@1s}r>yMC-Pc5$U(p5Rh^wKIvJ3F4rQ zH+ZSZJ&57$!hzF5+%*2U+yyatrxA}LXx&s1(6Bn&%G7wM1EK}%3gsB1xw*Ke z$HrnHA?hvuyG{`B51pU{!8TM9XkQogFmDRz=Wq)~iTE;e5TsrX8E!W!7}``p{+u{9NEbtov)~ zwyycN)a?yrBM1`>o}px8Vq+e!uBwdVSnnhF&XfuwBGYuTK_LKBfsbMUxLzG#Nyi?B_)CK+}V%OPIu(N zMA_0=rjr1%+#-DpTKblsL#NL^24iv00#~u+(yrytxf9aMH$XDuVuKqNqvm|6UKd2k zTd`P^AF`}DJUj$}KoAY)M?RnGlV6BZ-7<*gV0_#ceD>dOWay}Q0D2w0DB7oH(f~ls z5c7sI;~vgJSp4%Ws-XerUK?7UJr&sU6(J&=ix=fwNI)(%xz4D>USfrTPio^-^U0mB zyXE?uxBH2|_AY+y?Qf-H(D|&uFd89oct&6z`D%FXp%QA8lPys0Fz>pLIw5PTsc3!$GO&a!Rg#zPRl~6SdWt*Gkm|(&DOB=4Wx;;XNN-Ofu~+R-6x)RZLgptP^zY zvBpsls^dD4++B3G1C=fb`S2VrTN}p@kQpfs>pbpPS2nt&>0G=nH~RSFllGRf`PFV} z=eJtjeUIqQ{1P47u~essWNXUmt-k5;dKuGftpxY7)@MxzX|jCSP&2KSr4ic`ZPvG1 zGW2(lN@k3e9@6c0)+cRkNxK?a;%-VSqhjUHc-PY1-28?lSB|8HO{RsDwU(->rmTjH zy;@ncg_Ti7riGbOl;qj>5@iyqO0LQrI(CuB_`bd_sTO`Q61qyU7TKZC@u4lae~hH{ zK9fOqkXWw!r}6xsgGPUCQy!b^|53q=_dg<-^%ta-KEe_n#@+N*!7!xDdGF6B&#T{h zvxF%PG4*!C_X(l{cfs2WW)G360$$g<>)qN1H^VQ)gyx6tK_po}QP)84(v0lP{QT3S=O<^#FP|F@qr?DsX8Ct8P$1d+FPkLWV2V}ih zG`de}@kvLsh<81sNa4r8O>6$ULjCC*z33=Nn6LcPQ0M$hi$)~_-9HTNEFoLRf8LsV zH%=IB9e`Lp)-pRgC}-nSchzk`P6M^nYDF@0u6lF9yn)4ybSWM=w)au9B3-+fgcfRc zr55M@HyvHLSVTvvUbSuu8!0d2!5r#4OU{{g8#~l$#aR7(vP^q#u2-pukXRH3MNed}MRTvprdb*vbfke*}|A1yn1K<*^QXsH$I= zHuer^SiomZ{Xw|7YtFW-(s-*mwg#DC|3H&t{yJd)X@MibAPkZCcXQ&gLL!xUFQlZ! zD%`n#RpTN*hK6Iv@_pm@v_Ku05|z@~Jl*78S(cR^;{DCQaWX)PzR!05Tw$X9UHinR zb2K#6a!exQ-hrNyj~`?7w+!P~hXlL?_Dt<8Y1T5@$uJc$k%B{uv$ohQZu>iWTIon3 zz9OR`;r>ImuGlJ>B0>~=#_A;*K|4U>U}#b_yudHQFMa*0eKNk)58!*ZiUhi}Uv2V~ zNm?h-lH{gV8MVI8L~D@OSJ`qlBh&*DXDJw!mYoEphpI5N*I_F`PL8Z z;&91A4NtH<_PKviwX4iWnOBz@=$S1j_WE*pyWBBJNpemy%!gmmR=p+ zcW%7C znuMCI$BqrB&if%B=IstnbY5GbSUe*qZ5P$?op4 zlLR`_BJ8lKk_4!=d21xq-1f*q4PRC9J~glN)RnFd8ZLHE`*=S|sx@N50e3@~2b!wb4fNnQd%u9@@erV+-NtZ{v3#GM6jDCWm@rM$A%8FwKG@u5*60wk% zr}9zOp626u4v-Y~^?l#4m^Si*7JZ>)hVS{?_c0%`r_64^u{0P@g;jxyg&*gP48weV zec^ni^Bw9I7~=aZt23xfOO;WcGA9i%Ax4IUAtECuNm68toWL?(AnGOgaKI8^UId#p}4l=Wq#ncMvcX<_av3h9XT82GOP}HGJJ#UiamTc5tGh=>A%Wq z@LjGO!!zBTww8r6GsW#VqRE5^8w<5TS|_KS4t$Z>&7uztx6MT6UMuom?PPAYj066;s&C;g=AP<)ZovoB$v|VXvTsK2!lEilx9Ly0!?@MnUY9&r) z@uD$>`>((aDrS=O?^<*&vbo(~*IV!w`UP#EX$CIxN#}=(6^DQ>{fD~hu3uf9HNrEz zyE!N@z`wugE8#fWPiImT7`vQfeRI`^I3FG@E;mxyD#wHn+Tl|hyPR33%hW&>Y45B4 zfr0)i1s{1e^bECGrbr7uxLAlqjE)%VizVhd<T!^9L>mA+ggto z_%fuR7%hm35ze13@V_UszusE^zP$KG1o{2+qT$k}kXjCv)8Sg|O0v$60a?oYt)Fj*+B&WMGLL&8@BZ`zY^_rkuz z1>NcgEt+S%T5;UP4&BxMh+-HD6ecpN=9#0)xC#V;RHfQTJ?@HO)+ysQU32`kNhXu< zi14VTm;g+Ys*y48)sigqTTy^~;^YysiFAczv`GSk#yA^H>Ia2-7N2;F2L^P)UT`%c z#Rc}^8;ubN70EQ8gj}(%4&uD>0@dk>&th!9x^feFEB5dl$HfZIRnK3uE-G^E;>#39 zBJer?OFtURXWij(apwqS;qS}jl2#PUV(T;q?Mqb&EZF>pQud8gwONx7>_sWN`t)jR zE!KomB8M)->b6|{%5}Z9=n{6;rMulW-8y6p(zTtoK4C3QQK}77#eX^#@weAxK)AT* z?`ekynyTcx7JVJStH_7Bqc!bF*DN0`R%gT0#C6E`g~^vkTPYop9VWVv@{7Z4^9BqL z34ScX9J5m2;xG8f#*S#KLdY@JvnBc5Su?76X@Q%5|2VkL&<$irp8i>`D(%btVzIg$ zZA$LCmsp3lz;$cdeMiYP23yU=maVe`c{0$0pR+o#V;3#B-?F-E!u1G(;)T-sfWO*eIu(EI~s%0h{ogY+{6fq^1T@h=45bgo2~ zR{5x@&zXng?pZ}}?A~GGJ2h4?TXgAI=&bXR)(EC^!pB}>Voi9a<+PmL(47ui3XOcs zYGBm8^*PAg3{T|him})kh*cSi=z0n@+5;NR9sJZ))gFpPlgQ+BADz6IVVUL?xp;y! z{}p8Ajd`M?Y69C>;B2O`C_rN9<J}zmv0N1qsR7Qp!3O!uUUlexT=atV^#d+n+tJTZX2?e4&{O zJEXMq#M0it*4oy@&OltpQRi_b^iS)S z0wZIk7q9F3a(dP9c}&bHKNtPPw5d?Xe3(Dw);2><#q4iu%>~E-Xtg60LSa`a)$O>w zK7%aO2L=Wnk!P~M8(so@bh=`~Om;qM1QxJhPX-lHYbToEPB%@LfAB6}`SuMRc@ND7 z=RJEP`Flz4=c-7O0m&~aov(lZSPp$t=TZSrZ4%O*v$*SY@BXOUa)}4JS-}zCy4l<+ z@4%#Tnu&Ok?rvGW^t#OWkH)iXT`GoItA4n{qA;Y6N&eGX_J8`L z`e)m_j6Z%&vCsW;jvKd{gsjX0pj&_7Mc5(w^WVU3br z6?d;6qjVVBFZ3Wo>+9(o=p)6Z?Yg@8mc*5jtXscY7unitq7F_3aQi!BS}AXT@6WEM zmFJe-F^<<}h4HPdtjpM|*kNWRSlE}^x?r#_XJ?nwnC;=}pib0@3HR=uZ9JFHAjN4A z=G?6oLh)ktr1~t|-Y-*x4(aNEuBBj^t!a z=Vi`hXH1slFXv~?DOzIpqiW)qDwSO-&j~ zNgVtJ9Ldj~FUnskD_U&;?RB=DPK`hC@ED7VI>f~lW@LaM&|FC7{z;Pl2gvmC{{#gW z_NL{H7(Q;OXamf|&~9)9BHOaGnx@NM6K{@m1)0rPaY$T7UpA5hzDK*qjwN zpR$@pi;JC^7!^Z8)0B&ph2#Yxf{ms)H68&XIu4SXhmag4J_;J{b9lHw6J9J#WOSyN z&){IAwB%4;(ecu~cuJow48_CC(kmk0-to=lj9NsJqo_q~9q2#Wx-l(f8%7^5b{*9*I%sHxT|7{9WSq&wUT zr?I&w#tU~mrgdnxbz))J`)@T+67zLZ*>!Kix#) zB;~F2$P9qQ7bbfZ`2NpK41f~d3m9D3QfQX>XC>4T1{w7H%OAJTT~muSB&ZAKMRDq@ z(5bqNxt|LU7Zt#jy_=Cp24U0QBHSNtRa>3%d){nrZhc|+iU#%MSQOq=Jj%Dav&WFq}W-kjD-*RiM^j*{KHEM}~K2DejC=&GUC22$UC3 zRg76ovn(v_k6K|nEP88tc^#pZ+nCh|G8xZ!3^%ZjSDP^(g&`k>BR+i(50jF)TmUnt z{sI)wv?M)T7vgcvot+-$R4DEUuCv7S`1G7H1lI0(4{5A9&c{NNSX$FswQQ9sv&kb; z&2pQ%x#NtEeYfE|yW$;6-@!S(Swe!Fjg>3bz3qE>FQyVaNvXo#fd+&&e(?<^pD;aa zxZ5Ew%8TL>6sTv=sFCd>l%Io$Q3zkfD&<#wBt1TIe@hcOxwWS07Auk$uIMeL-5X4W zGGKx!JGNJ5P3|~&a<*RR%%SNNB{qI9#UuQFPzn4(xG$ZmydYso%%)pXC*m}NOM)9-p~*rbeq{JjUjI>dUF81bmOvgFjoG8GmTHCbF2OZa1eQT<<%rmJR z`s#0m6Wd0O*-q0bF}gxL_sCX=Ny`C^Se~w_!$+dIJ5LIFjH!_g@QG`pj!TZl@J@qY zqXJ#_^?ukhL!l{iEng`xizV|^o$y%ilHIDja3wba##-;aLq`G2e4GrQ?F8-i=D{(M zb93X|f?mYkYLdXe@2?KDF?8o#55*8lk@+7rIBZ)AfsFZua;>x_gXYBpp>h zv|Z1#f;fRQ2Q>~6!uOvn4$DCHp;pK;y!%gT*uSTVzqUgXv$C`Qy}^U*kX9fDESyD4 zT%P+^8xl$pN3|fQzF=0-BH-e!xgrRxTLQ`h7%|y?f5`#cv`H$`k4<+f#BV`V^ zrJI*qNQMmNZuh4mYgs0dDFT|My4SVkM)#0JzB5Moh%g{~l%aX`ZtwH6FF?csEp+r7 zIToXi0@Zj{vt3{=pri4!iEsgYrGDt?{{$h4laR$Io}41F`y`pKV0tH=xN!eLzqF$@ z?V?RR99E4lP8u^Aj{-ctHy1tzD`zF3yjAPb)Y_IxsZ2~vL#&QJpxuQ>_KAL)fi6)K zb!~#}n~1htps|sLB+kRWkBhvYf3}00IAhWr14vsTUKAiJ*L$mwKdBGGw=dHgZ|m?} zUC$j;CkJgY8eb%6l-3xUQg%?;Bt-=Sf)4~}=g<`6w(uRJoyZ8Sty%1BZR|=solnj- zH8_wgiz02_ zAdT?eRI!tdjrUV@!>f`9tAF4h^N$_@3v^b6$PC4ad=9-oa$C;t2FmyL9+h;QNrv|0 zZt{4{uxQQHXyMiH;N9HnKn8Y+o7{zSB|V*nNkEOeB8>b=6^r@$iOrm|!412Z*Wy<0@QjmYN$#VX;@<)aPgkU;r3E{8igfOR}Tiqu)5e<&cQW9+3Lr={bo z6!%H9MJ(^2ffxc@fQrcd6`gUnwysTl(X>NN!sQb@qEr#sHX+e048o+;29?^+rT+Y~ z9ILePGrMW#sk>ebu!!MUn6=MS6mE#iToztmp2`#-rYxp-4gGE4VgQ|MKRo1tJ^ubT z_Q=3*og~X&8hsx-N%==Vr+-Ew@h&$SBrJ4w$-SFvA)u7muLT*c1vex~o2xg1$M5rL zu`IZ3*84ZkriwK|Hmln^y&-w?$@NK`mIU)IyUh_XTM-&d4Lj32!c$cR3w8Q~H+Q^| zsXR80i}SFl3{IXrS`QD4?K1Ho0gc0ZFRzP-z;Zzi!0kgzvW!xeJBVZBA;#c=i1ESR zWAUMj_CZkN5+b9bR&5F7cbkMTlSW1$>bUXV&wka8x(@a(+<}UD9KtS7zP<^6Ch&d@ zgXB51kjWl?QRU`yavY4~XKechXbiJ?*4$4|h8$Nd_jLAFFLgJ(CE{?Xgm{1WV4q>n z91afZs@?K&)Nn?ZFg{KJvbiJg4*d6}#)WDpMkYTm2&DL6jx&wuXtANr^Uf7w6CVUm za%l9%R?tliMp$0n!%WT0&d9@4!NtnT+QWrX*h4|%E)0h+2HSLNN;=P}L`9C%$kyVa z0+cDSr_@i29I0H<-r{*ZukdQc%#d(exz2@FaOec>Nlfo$#Q+bJ-snn+37^8$O~jd2 z-gAqlCC4m2x{9VFm+L-Or&K?`0QYCy^X^v*)sd+bob*>`mr7%_6bv}8kp8ZNX-7Un zkrt$dbpKNu`Fr^OHS&|vUnf8HkEJL{gC;m0xP9js7MIr)F(78=sjTl7SEbwrOJ<^U zQn-(xn|fj>3HWWTcUJw+45hT#oF;D+`uGyp&e)a>l+j11C80W`SZHVKoPf4JQ!_Lsa9YhK1t(yRIK+2`#g zfTC;6=+ZIhC$duJgSwMRY*Fd$^)QK_#w&Cw%YN}p{bE-4Oy0XhG{AOfQaZ`cgj0+dJ7Y317?3+BM(wLE3`G~ zsWh|}%WN557Uc&BxOri&8hmjG8*uywwiyifV;Qm>nJU&gT3vl|g4BM8D0XO+I?_Dc zF1s{4sk%6?UaYn_l})R@G{dgqbc49iqd~usXL`0JlQ{ZyfrhMJS47m&NmJ*e#$DFz zYU_+tOnxsgxlF~*&d#x7zo<8#o`!+8pSO&5`pwcr<<;=@LgfvGQpjKmV=;{_J1c9> z%f-g;o=)Fd+ zNk4oWj4z4asHI$h89_iv0h6`tD{RiXMJfXp)$N4m8^duh5boxN+;%P7$cMKJsJi_} zEq$SaD_+MVLv5Vb6iZg89@m(dSoHuq?pGh)-TQS5pa=!Fk=!ZoX1ITiS5<60u71!N zPsAk*!^p;-O~{RcsSV4#=R{DOT$^hcrJ4U2-*#xlrI-(@c*8 ze)o!HMpUEAa#_piFipASdNPJ~!5nU|i3dh~Zz)?~Fp7C>r-oO6cd0tyIA5xzGer&O zIeCW@M+l<&uKtIn81wv->wHAd> zAZZSRa(sFi(V~GiPXM0`cYpiLnx}bZg)!z>i57|&8_^bj>+D)wLV_GM_zm%!`z=AC zD<>}Gx2<1(z}Oul_#wY~dm5FFr)q?!^+k@`cwzG-owSvwEGshgC@dIdi+nPklz)3> z(|H{YCc>VwGd;j5C&!sg5*Vvj$gH0dfsR4Kkh~o(8Py)E@6j$HR(VO{G;B96n^0n4 zKd8=%?ex6vj_<2@T;(}g@?gVjIWu?}<59J{)_7Fi-m(`@3)7Vg-$l(`FZ56ARUW^_ z^l)x3nB4TxB-j~QI@lKk{CGBmIgsbz(z}%Cs3EQ3HR^As6iLR}u{*fv+UQ`ldfL07 z2Y`8N?l@L1pHa?7$-|GI@__Qv!8+f~xm!Xv;3^bv5JsyjR6OkND z#~g6j#4~S1C4gRP72|@|aLq^f`ZjxiVUH6%{Mr$0+E{NhI|>ig*)&b3SLQHgurP6u-(a%EM^jul zJ4x0TKciSsI0@o7F>tNjtw@wM9b}F95RgWdUQc?|o}Zqs8%#rI$Ce4@$Dr%Cz~KtF zS?(44X@X7Wa-He4gE3POJ58oI70M}(%U8GFK}QW?`gn1NASh_iyFfn0AU%gmBFo zIVCMPs!_w~!%6jhyroOWR0|LECDg{KG6tlxr>j6Ei((o@=x;ZkT0pl5bL+WrV6KV)Eny^F^$A*2e<# z#Fz=@mbBTLFlr=^Xkn-4T!aE{iCwnLy!%2$fqltepBstP9?g&c18 z&hPH-R12%BtCb)Kqfa#cLL~8h1}uP2G_hi2PrN_3tq`L;TYh+V+vlVWg#u01gkdEJ z{m$RJJI4aR@?Mp_dD_97F?4E4r7PLjx0XuyZWAVf;+Rbt)>v*RJB4{h^q5E_{cHC9 zJ3vomq!#n3lZi5HkixQrMqh5CFXy@(Z zztrj?C>&354em8YH>^GavfwwZzxpPiMeh6>btzJU5Bb58qJaxe-Z{18{1OY#+{Vq5 zSTMg^%KrQ9xD!*>sgZ!L-RieVJCg|)xOYMa_XVYic7!;)Ec9B|u8l<|XK(F6G`Sz_ z6?qu=n=pi3V+k4#oIS@)*pASqK_CgZXL0b1k=!W!fwL70?QG-@abfN_4>KiJ&pc7Z z$E+k7azm7xI2EI6Gc3(C7u-}vYIpF^N|eSXkJ|S}(@piFKtdG0ycHHx7pC&JgEq?T zS#v0R8i>5F!ljq>n41X?{NVuzyfMm~kx`Qf_;SQWog!>l9-rslb|V19MDOl9^{%y& zsh>^)*Y^kMq8JVa=e5OFp_#Bz9yXKol!_F;Vm`>(znqVJ_xi0Q?A5_}-*V4t{V1&g zhQZWxPkITsa)zzU&nD#L#5aYdi0`nzVties>Xv!iTy7`*8OQh->?3Eb^&Ax%KH?Vs zF+Hw@QeL+~QX|cu4!XamN7lbI)&7E^{O7lk|1VxeAm0JV=RdfOxHf;b7Nf)U=V~4a zG9!;~Gt9g2+oYoy5zpq^RIYxN8?#1lLxn<5A%D={k!5jl`i4S5cM#LZ0~H_MK#~#% z?>Qu2HrbatS#*InDqk$;!w$IXd2g!G{M2|G&D8MDuJr|NGm>&~M%UUmj|I-+BHY z$s~9uHDMCEa@;MStr}q6T<|eydK6mETsQZ?uVN;L1025FFE~u}vb#Fq_47LNR$AI0 zEgbM37&nKl>CV`>gt8kX(y@UxgyYw5@6W(v*~m*xUf>@)YY^>%6akOXxf$H$t#bR5 z)&<_`>MFJ-kF%Sdn6AsC1%9WC{;B~yBt?@%6 zgspA0P@{8l>yjT&4;&t2b=&N3OiAgyx#5J6#N1BTch(^P`r_Rg`0~h0<1buVdZIQrr58}F)Ey}li&e|dhP?+@BHQ^_RA z&@)}$vckk(H?>&VaKBKswXawFq_3PBSs0rQ_LjAZf?3pvUI}#NK}RCoku@lYO4vU1 z_|SR`_9lew^kqmE>g|)}qOwRx%Oon-@zvEH6LR`?FKWc8#CBrM+--KF&V_>RnwBA1wbXOtG-Nb-GOLr7QYM+-;dFVCAF^mwXY#s-D6q#dXz=KD zhC!H*%gfq=f`T$KGNPiQkJkygUkT!mE-i+CxU`hM3m_MI0vA|=EiCy29pdK3#+_oR zF-?*lZA_fq&nIFdB^O<^Qg8Q-GV4mDP!N1O+@&B{@>ot;PP@{r zMw5rEI@ffku2Yq_p6VYgyg*!mqzfPi=t7);L19nwD2#oUuBAuAw{Vn)g zV`X7weQm8~b$zjnQcYvIS=r$a98gT1YOlh?=1?kICUu>Hm~%%+#QtG@YdYvgsT_lZvSG?jMEnS#OBi`zDFUQ$}AS{1~bQ1)VMnMKK?7iYPLR?8!_v@4Fa<2 zD)~wK->r!LJF)vezfP3>=M_SUUZXu$Al6inp#Yv^4Kr38IJaD=Qem&nUqTQ_G3B6{M{#^lr#aT^l)zN%ul7Rv*%nMdp zEXuBr(hQ25zIO*6*^K!02j?ngeSBJqTnCjYtdLPF|_5d}_5d zy+TO%33#5qUp*Pg&oz|F+3Ca6gY6wzE@wYsKxvRcdfnys9oMDmb1Ei6`xSJ#6uUP< zCT)HSJS%;hRB#;h_E@`K_KtQPq?QbDE>fv4;C+OU(b>RK<(}>%xv`?mB5RHXMuoA}^$- za?W1|Y)Fxnl4Obc67{CMlFZ7XcplqJJN>g^>d+t*EZiR6%Sq8V3<6c=5o*o;H>R_F zeUg%4h#`NEKHeNYKHob(+ppBg-=U$ulnZYhJjQ_~4=0{4 z^A6b-Gr3g;l-U*y%vP7cHYKgN0e*FXOY6S87bY=ISd3gB8}=nPZrcX(8ObE4qgYIo zdeUP$UPQXF7fU4C5F2#1tmD9k^nxE_~Zq8L{Qn`dEPpX%W=c*d?v7K)1pbu~s zs2V8Nj^{d%3MV33l|txuY2b>QL*R_q&w#0?|=0!GgP8) ztog*t`Get}y${U4iuHUBT+{-kfJ;VR2}j>r_NjY-@S6 z&%nvX!t7XSSIB5}$icy(YOK4ud8o)2uQSL}Ez-x?uX0fD7uhCDM z>P@!_cS(b%j25&?4g%mS<@q;%n_L6RDES*DNR{yT(;?x%AGkkj1vD#6|LsqdAT|^> z)aIir;XhO!Bk~7QK=bjXquv?af!V#mIep;;gI_DA;wq=By64*_cI=W`T~gaU(mOrB zbp#ZQ1mq8UWpsLHbcGa;g%*v4m5fD{j7OG^2j}*Et(>w3G+QS&J7x6RCbilnw>qS> z*(bMpWDj`d47#MYdFKv!=MMVj4XK4!>3pftiw2n`cbFx&o5VGk#y41}blQFEcFgE~ z>yalH0g?_ZmGUoE`cfw!T=prX{8LDoT11sje6x0JqduTT>r1t9Vk?t1e%s0Lz0`9p&{$&F0Ibwkok|EVnAysn0rLT0qqUptA8^+_C0En&AiEYw}Op{() zB$JvaQ`%=zSfxP{PS*OrB?eGkte{uT%%8$OeTF@<8}H~-diEUQDGdHAsz!UowhKdK)4p67cO)CQ$-B97ejbsCUD_7-5?{QXuOPc;6qiZjE7P};r#+~oB4y4laq_Ydx1(|NSEvDE zsINu&8_{c9$wL5TzJpcJ(*{8p^!mNakls?pJj0LwZbAWYnr~ynqg@RqnErmQv6tHCb#Ga!()a z$lNf|y_GvjMf zl=HiE9s)8OEqfvmCoK`Bv%)qJXLe0V!s4YhdDaq>hPFG_ZFV$|=_%5F{8C65|8byR zY#tu}v^1LtT$rEORaem5m|vVxKT@|e*4N!P-BQ&OaLFqz9nnQY<8-QCg+)A50?}(! zx_DlUzmza4ny$|hFg}akph#NSEOttDFuv^7Q%I5l04%sR_dzrL>*?IQW*3PTj(GD{ zfYM0=#%afa`Tc=|G7AFW9APa$&@BH!9a2zw=Wjn86zMua=Yy&|D&Nu}`oPZ#+A!Oc z{B7gMoi~h(Dx|1{|EaM29=`t#PT}vZ(Jxyo@1InRq?sm{nPeEXsgzv0#9`&y(n8O< z^^`W?0B@a|lgutRn_2G;PK>lr>GFf~j`CCrd!qd#9ww*GnT^mQMm1-PlX{8JO-=REtIoVk&UnVgDxGuRi9X9B zbz6_MM0l`M!(92=#P!&NrRJU2#%gxWcH@57%)~}Mud1WuHaDBs#kEWMAbql%&G{+s zp5oF{#o@@JMsXy;z5QLU7i~VG)8(ki*d#>I&FpB=;~&ogTkiMeQS3{)eku9^i^7A0 zi!h*MA^io#f`z2y0Adj<1@5#xtK@;6ql1o~!^nINM=N85^5&RuzyNBH?hPvc9UFuTw;k)?aORm&@wVd5Lup;++11M?_&GqSNg;MDB?pyL*u`83x8@1e$pQRZ(9GLKXj2Yd_hMK zu9+OALP3NUFlSRxdy+TkU2H_P{_&)YpM7Y z3i=}lD$HdumE(1+T0tepg{+Lg=|9^9jDFu|~l1mb=L z^p6uds{7F>A)y9hq59MdTC9*wBe0kv;X=wcKWlTAVvDJH?&Yg>=iwH;b@gLhZ+Cd2 zMmG)niWYv|mb-XL;!fx50$Wf(20>6QkS>wu@3@Kaw1lsd7oon^hAaB&JZH@QPRsD9q_INIAoxn$(5IPRk_YU!xpKK+gxHTV^6P5 zWlD^LIVK754M3kk0EV7%WAtpeR%T{k>ze+lOV>*?#tw3{F0$4jIiCEup`D2jz}=Mh zuQ-k6-&^EqrB(s33bRu2t2Wdo10DN@D1=>y%eHOrU5##o=gzm|C)6G3o%XT6HQs}i z`EsTrg;AbDSO!oh`~G}T-7qxO9T$|JHMq6AibmlAJ4G3&x`wGEFs$0DIj3y)+$sWm z3nYCv%!TxvW0KyD+3gUN*#H? zFRQXlW)ekD$*d%5S{Y0nr{%+^q(0*96MqO6d-ayI4BAtrYu8*{R@xsPxha%pAMpu| zh#upkNa^LbO=Y zGY(~FVNfp-@Q|908oZ8jvnhWUk+^^n&Le!A3Dh>-GTArsuY54SzYnR3I6khmvTKgN zO~ZV{=k>6@L3?0<)kLNa6PYGUb$sS{+_o3r+!;Dx5g&ZeZgy216id7*XNTcjUx{Hp z%YoWL!S`zEg8g1d;T57=9#VnT6T!}E?_#BIA=+;SnjX)Nk^@cY+V@XSchfAY#HKrTUdsswEDz5tAM%rw!6J1h+)m?xcJS$ce zzt?rT%~*w~3=u>qb^}sR{-qIq`e+&9V@!YoT^8eA`N^AvjGWc{qu<^-E%;Q3Ppj51 z?()QH^7+P|tbnpkhJoGQ)46x>jYw0QAGEO5G$JhLE8qDSmv{6W?{L!-#_4zQ`R`71 zbL^P%9nqL$258;v928FJr=>Eq_jmVBx3u@Sk0vpwFAj9_d@JVD@QBC@9`^AM#iV6X zP94z%&w{sPE(E5QkbcAeZF)G|O39gJyEXr_h-g$v+RlhA>7ZNxj%eXk`wD^{r zHS+Om?Dwtd6W13^x-N~U(KmRWEULmAi4bXOdb%tXxMeHyH8oN)j$F>quzD;2_ofO| z%d7>M^aZ?bOPv1$)%@j~f2ihrJ6;|xobOH5)zrKZLS}WJp2Nk4DCVoq?ItDep5^zt zfx!@$vAVq7-Rz;{7S`JQ`o*4(p2?P(TF=3+njR`u6{SmC~Rz2o)+JGF8fuXhNCCNJxfb$Z%vHqQQ`o6qS%f zqN0S9Au2*-2pJ+0p%BR!ssDQ=Iom!t=W~Dm@4k=sOmI=yQg_-)Ka%9HNLlNYTT0cr8{fx8)Q3tuPry$aM#ji z>@Vqh|HP{Fs66fZ@;>9`tCJTKIZ1qb6n5Cz$w40<69M* zfCP6xYnW)~j~v&KD}qllO!Fcf8MKUYv#*O234^#b_d)$8h$ZN

$6JqQf&GWaOIbj;5F9Z{`D&1 zuS;`F3*r;+mX+n_l{~B6^8A(i^`PWzx&@u|v9}sU+%h)Lcgt5ER0zp*>9|w)Qtnkp zsIJYyj)X*>#9KF`j7%~jEpoQcRuq6=QNwzkAJvBxaFaxmubZL?>u@(wTjeGsPM7na_Y5Orag&UNLKt`T)n_s@?& z{#+fG=Ga%A?-*XjmgQtrRuw#Y-)8*d4_&REhDV+~KEX9Y5$Q*J`v>BgiHD?)d*s%Y zXbUymzMF7A;dX{=OLe+&O&NQZ(}y<$4dLe_q#V8!U$oS%?$&>5HI#qZeXwV{=RieC zK<8t^!zsbSY4VmJHX<%oTYEs_$@Ue;SY|Pm7(BRC4!4B-t3LcW zcu)6V72?i6*NDJH@(zqU|^o6R# zQz!K-uack)@nFl*xGDktgHMePxw^cF=2|rPs{Q`ixdy_0&+_X^biccvk6e6JGds?@ z`s9k>MW>Zo?qpOuU;CxL-+XlJk#MVF)R;%vD}(Flqnw;uKJIz>p)I#3+vCTUbc^Sa zPoIVz+H|zg@BePW^U1Ymp)$B?@&6@2$Gh#RYV`^lM`@%wthnhJ)wM$-2(fQ2+*u;W zphO!Hq8{h^d0V^ehS=oLbh$P5hl+NqL=PS?y7TFNfm)JqM0o0}w{14<*WMGG6y*9< z-zYF-ne+vIavzZz7Gy9W?9Xeha1zXs$!1?eM@Q$BsV^CG{y7Wn>zLfn8&xIMHP-H| z<9!-DD1Q6d-ff>uonQsCu;Xpa6J5r1rSHz>k-^EItWK&pyw3IB$K7QXy=(DX!ntk7 z%vF{4u30|Ew8gjZ#H?-ks;c)^`mUM7;ukKer&VNqQ&0MhWn7{4N`rOBl*1fUnX;^F zN@%lsMHYYCZ5ucIhxLvJ-0ovNpP9(W3866RmO3O z@!qZhbKP2W7IUu1-KOkgxP|r{pR^dwZcpFyITu#bdMIw8UH4pU#zmJx!Hu76gO>#Q zMwOoscA!6T^`IoZA^)PeYftCy`pMvO{J^}qK_|X4K~{B2rNor6Sz8 zBUpnugiOtnKC3Bm$Yq2$x4#Sh?n9d}*8NsmWK^@ed1ijm-g=kELH7NXwbs|UGE*}K zb2+c*M%u@;wVmN^r@f*Ptlnw4Z3Rn#vZ%#7mAifMBfb5<#ICnR?C=^*zQk= zeyF(R>5ccCZ_I@&e8MBz?8@y2x$^wzS1n0Wm(P2DVZB_~>!iM{#73{n{TJsb?W$sZ zRWWwZPj5+Lm;iGdy@_dPp5gb>rlsNqYLf3Oqk9w$s@lFJejZ9_=z1jit)Wb2ZO*8! zc4JMVxrVgKGiPkr9~HphUT&$+c2??^y!e{qH$L9npT*{5uA{=RL2AnewIn@W zZTcdD&$Txlb@LyppA&ht+*~c{MDSU?@4t6DuFF|Zar2U8Sxj6f+cjnt!1qNPYS|usWXRM?4ykewIi7U^t+Gbn2<*(H7 zJEJ_|v!C&ccHnB^Zumep;10Kk%z2r{cUO*B4J=t|lb^Hfh;h3UVfK+t!*_(G!@rh> ziSUYSvx85lGM#OX5B3*Ut`97WkW8`e%ipiSZ2kVBXKu%GcW0|FJy!Ku9-Y+zon?_y zuIBHrm#yBh-Tm9}x4Z?y>j#9wcbJXD%tLoDWE^fpcQDK-4CoY1)c5%D^246dp?d}? zBh>?z{_SNF4~ab;1cg)`7JgdS{VXi7)#g}hj?d)nJD81Ojj$DJKo;jum=Ziy;(^^a`ZTlGE40*(FYqv zQ@1=$b$Xa8D$F@FIK*|@X>;n}Jnzk=*GgW#FR0Cb@#aeL4*zg3`&M~DsY5e-XZyzv z7VD>a3=FzPg)@tCr6ecy*&bcp+H7bhk#>~0AosIBosdD;Lua|3%eq!$=i09ZU(O2R zR{o^YFCvj?9>4Fz?ToWoUcSNp>E~nbeNL4b-7^+4%&4c{%XmT5PkiZ7)%1o9zZMo; z6ujldA3V^^ctquq=&R0}9S2(14X+zelrVU>|KyC|+}`ZL5}o@2ii?WB99t^M;Ty>s z;W#4t%U-|yv&%5+(=?glIkQV2u8SySTAC2BAY8{)zw@bpmPg^+XJ+xMZY~+{G0wPR z@TFWyIXE@PrS(*?x)iN|$1wq^YoFiv->`3N&ORuk%W*wXiYsba^W`O5+i!JB&G1#) zs-VZfQf$7Z^zhMZnzpADY@|Q0!=~KKt<2g?Au(-CojfjWT%EjPZ6A4PPcky` z(cWT;W4e4R_EWE&>-RL?G&)}ITTHwx9V@=tZ8|XPcjxJ(N}Vt>ls0)?#W8s8lMSpPUNMDRM_w>G%L=3d~1G}kft6Wn_eR`kF{CN>RElFYjk z2I8;OAJFN3pVc>5vTD4H#NEnv>N#)i-&S0g>CstYslCi78g@YvxQgRTat^P3xoXMM z3b>x+OJ@xnudj4G}LQTBo{JaniEep1FR+PH&Zn3g;EMwLC?dx*dwO{sKqbju|EA1o8Utc5q~W z8UpkSrc8^sO6M=D^#j^9Ik*=PffAGP$F3q{~*Si&FAwn71Rv%IYRf0^Lw}elS1Z=8EPwfu|3;EUmCr2YlfpjL!uKs5!;*|c{GA?!rOc1K zP7}yp78tSHYUW7Yh^&<7u_q&UHyrW((tYm7DYt`R$=_`}6Wr|176o-wbzdK;kl(D{ zY;E(??OVml=A|jeSO)qR_78A-Z>(awmiE5j;`6$fwJ&PT2fLrl%~uF%<1|RSK9h0u z&*a0;jLEw`vc1Ny?EA8iUWtC?y;k~x68)6|tsZQx5&8lvzbFl~1{DQ|>BcFms$aYm znftm%$~Y?F+QZ_Ck%g@bm=l)=M`%VGTzjf>NKsvH@UWRjm9Na`BG$TWqv$QJ@d>-OV^j+-7V@N!;d$F3sO{$2ghfY08h%KD+6_xyb= zj7hH-|DTNoyHrlUFoq5VcGt-NPmw$^S#GIvkdDTe;dW(clKM411tq74j#YVLTVpL# ztzWz4KC&R_*PB>8)~bDC8B^L(op3VxhxI!sR6bLR^GxPYI6SLrhA+7j($5ngwcyyG@`Og#N z<4ugeXRs;fLA9}{3!7=8Q~u_y8EF|^jt4~)55~Wx*|Su};%ItJfSaBl;Vt(n)!PN@ zMYr=GaQmKk;0th-In`RKW5!L-Mf z9G^BScq`v7+sZRgG}@rD*2J@ec`WC;%}*|?kyQgD@$#efp$a*(LWy6NC3w~wGdtg&&S%7 zCAWxf&ENZ9bSJc>zil#bp7T!mSE*K0>H4k;j&kkPT*Z9;$4cv)68(JQXBma)b*SxZ zT+-TB`#LaJUh`&SX!v*6+!i{T9gCRvDex7Q+zSnz=inT;`!y?ly|qYY;qAWBF{#Kh zo5wA-Vok??3YQHMTy^*~3=xFldL7NT2ej&;pmyc>_zlYK&rYjh4rl^J_U} zA7eJqznT(fSrA-$!dga5%`Qdp8TYB@yJ#Ev>UFjSta808_IbE1ySlb{_?TaKuf*1; zvlgD0^ia6$CO52+z2rsL_M_sDW;1K97A7cth~N!ax}Dp%?%TK7ZF+iMv1j0ZZGb(ffvz4y|+0>{NGIr~iWYyZSEtx6CJ)_5T#Ii?KZs)eeV`WwTm-j<) zG+=C?(+CO*dgkufw0Gb-!j;@5067e7eoV*LW$qlqt8$FI4q*F4Gt4dUMi{Zj`! z0zuB0Xk$-uoo%R#GUnf-gMUv^ZjX$zhKz@%LSVhf;_P;9`oT*yMMmY8Dtc!QF1yGT z0;^*euYB6NDs+o<;rWqHi9K)SGG**G9zMeU-uR{5m@9i%{Za4ta2fI89bRFq3Dy$B z8&8*C+dVTUHSpO8J15ti3*1*f7-bYNtmgS{{d&>UQqNO?3_jKY3-Y%go4K$wv#d?G zUgh~A#hG4_jypO#6};RV#wO%xpI^3!x^V`oYR(M*)6`>deu&b zmMR8=q%|iTBeH63D#ilSR`Wzh4R{di%H5bX$_~)|{Cd+6loqx>H~zxA<~sY$v!!~9 zJ!SKJ9%O#La$)SD>XE0qZ9n`tIQlYIHaz<2P;Ha1*JnTYw1C53VBL*4t&IVX9v=@k z(2h1`bgn23opGNRKVkEL>cz@;-`=beaqHGOic z+l4pRj5h8}Oq4URudt7?{}v(1zpb0|3U5U0#)@Jdhf_zdHZLwGCbPE$``=<(dx1Yp zyx6u%_)y45$hxd@UH;>T=X=YuHytUs87a#cAmdPFx^kWPkL3k{%qcu4ex+a3w~t< z`X5e8`tN>|No%JT;(c`;r`N*Z)P3Qnsq3zAuAiLrRsMnn0*&&iV)UH(%`8$1(WQ`|d3lnJ+%>e$gsrDet2T1CN3X zY)zx3nVuP_(OAv40*{m9B^NbC=b=oG;+tlwdk-bnPZ~$!vEsl zh~an>R-TJl0YP$6(VLV!$}G)KxN7P&e!FqMxjpjWW$D13AIonnU#If5I9Yp_w@pN^ z4bRce18PSyGA!35hWG~zg&&G&9QD^ZB>ilwY|o2l<^61ukF%l*9FwwZ9=0@xy9`|w zYIK@+FRifQ%Fc7;Gk0Bh8vES0v{8h!S$ys?n_y=b?SM=Pj-_0E)-jUJivIC3Et&a` zUTGCunY&x7q+MomV(&X0pSQJl(e~&ctJr*g%|fM|E^)v687Sqa=b$fYX3S)y89!`% zG@z1)iPc;^bvX^q>%BDaPp3XgGMc*t^5}+F4&?!% z5(rB$fFby&e+lxtlw~vpHE@4k5Xd)wIf&Z<%YjQVe?AHy(@ptvX^mZ^$%|XtM+1<*k1AYv_V@397LDh9J`MRgj_L28p&tS8r?!Uh0louax1)mt(Ppomp{==v zF{=G$%$#6!PN^rcjOV~0zvYFLL9afZg^A=>P5k)%-vj?-I1pUW&Ek_UlMXt^QmOIu+^N zbzSu)pl*R-b;`n_R^*-bTcD;6pRdq*fj@tL0ong15$ z&>0KB+h7~OCLbmEuwWYKej5{lot1?R0WTJD-`qO&Ef-+V!LVF~t<-VJ>&;!~(ucI( z1;f59Q;})8=w;!h&IhTYk9X)q04@>?>sLeA2s@1n#)FDH)Sua7EE<3)3eZyjO#_kumjZ?*tH3CK8o4B7yl)o(nYVEM;s-!Y2E)Fy zgK)GpC9)#H^v`h~q>2%@PW$l<bQ6xBW~1z$G?4yxahm&$wzNHWv;q~ znYjZVjOwesH&*gbI06gShS@Yqj`$76dl-Sa1wYO^O00<>2IeC`o=ksn=aCqR3^&_=q+r+3%%688|T9Ib8SZ0rek4!caD)R9lX zz{TG7Gf=z1pkgF>B==CCz;1#m(e58vP^<41=>RUu0yJhMkDv7PDS&UL)jt~?wE9R7 zEzJu1uJ^2*$ zxA_?~0UgB+woLIUPM^ZxGKB}DV*h%H!K-?JqL9Z1q=^zm@U)IWbb@mFTI3jfKt?E2 zNuTPKi8^Z*;DP-2S^M`F`cbX&FT9PRlZDyuYwIu-7Y*PZ37)AzjcytkFQWW?ma9^M z+i#0^@eIIrybi59KZAxQ77Y9D*wm=N?lv^G#8+1cY{c=P3pF(9U|2A%1{GjwqVt~% zL`d6m1m@~#T+s|_-C;ER*v zGL}tmAA{&*Ff3b3n|d~R-3l2yRVQ>~9b%zF1slCWd~6`mG4V;K<3aE}Fl@-#9i#%h z-xjYI6^xoxfn;Am#(-h-AA-0)8j{A+kL~A2(uuTVTg(aYaF5yJgIo1D5J6m z0rB_2c0ZOF{R?bOFtISil;UC7Q%2{;@%#y}o`GR|`U;dthK}}R^8Fp4{C($`(3ms> zj2mq7(KDtX&&u%63L9xDL(EU20?tR^1)+sKER$d|JyXMhNT#kqOndr{Q#l|m9}L?I zUuQ~*Nw6g!rz61S`w5>70P`gnwofZ*Mw$E1a*NRC+67FITju&kw4KpLC}?M ziA>7@xEKdzwVEEPisF?#bV*(B&L1Fj2n-urzSb0=5U+UV4-mROXz2o05V-;j8(Y;j z(=#<3#$$^-_w%mST*PGt!^W1pEoJVX*dmYaQds*GU1l>6sw}J;5mQ8Nr5NXK00KW2%6)^vqJXuke@MVAzTvgd*$jSJb5K0fMHcJ2nSG2vmb% zq3@1S5(v=ATu;<42>PyPD47<33}8Yivwxpwo)n>ImTET&tzW&U>2}#e^sL&z9*@I|CveIN3^qWBig{+F!^*$gy|$WAPqh+ zF-$r?PW_j3v|w%lF2p92N)5QGQoX$V7tj|#D%eWS+ncIX$j`hXbd=KAx|x7o2!`$W zHu_M7{>NMvV&B!S&z*R~*m=n9r>SCVlB-5*fn4;%m<#nNP)`M>%SoQ=ew4_2;B~^v zfuo_-K7tjQo)F^mnbZpm0JR?s%YT06zwz;5gZS;1xAv|DkFNp4)Gahj{*?K)Wcq|} zff}S6{dg`kSa-p&)PQr;Q1Mz3b+3g*r4kU&fnjTw&hr$hj%4Of5!B&eZ@M0|t9M{1 zfQ1HJqymapS_jaUBMG!+@Wx()Vfz?TmnlKVrz72?JZ&22&bq3<{@;Rd8=QsCcc2dQrtml>s8)GA_0( zU}c2-g!e=PNWPpQ>O-UJ>&!ss#@SP~mcm*KWh!3lJD@uAEGlS%cl8kr>jD25N>mkF z0-1RYM4jpT&ZrdL6f!LJ`7LUwc&!aUWqnjzItPdwz_3+&YaAu2s-YP{gW%vurV>MF z`s@Dj!+`C>p=Iw-jV7;p+p+bZR{v4W3tpalLgOi;?H$Mrk(xkp;u$Axd%!w@VX+MN zsKVmaB5a+1n7}KLi0TGxH|FhqidZ{>DZ!3lV@$BeR}KjNdDrsqJpe{MIxKv~gZ}`> zEB^p+omCtwmVh(3a1K#|xyI?shpL^04Vl^(VfXE1mF)s#Ck~qmQ-V}r$*cV!xkNVy z+)xOHEg{1XDPh$KCPci0n?Y8QeCz3xHUPqaJuniK=1f zL?(a{Rm@GOb3Ql~8P)@iFfTm4V-Xdv^&?OPM57d5fX*VE)~a+$R9J*3<5xswW_-OA z1uinI)*hIsnqDiS;$jv`C0(=5bNed_t zngG}Zh8^R~cu5r-#yEJ@h`fc@W*3^;+X#j&NfJ=OPOo~rB$4NK?W#6p|HH+Wq}x!z zQ078O!h=79;JI77QMNGYBatUMCiVYjO{A{ zD*}eCtnO7(Lhm73+Y;>wN`@9>c8?)=fq+YM6o9Yc;G9+e0ghMR3Gft&46$qgr-NaG zgQJELT*kzLOvoW>_s0!e9ztNeqn%0>c}oqIyw+p&M6oTPb1N9Oc5=35-M7+Rp|V@~Eb7q1s_3EDsN&4GCr3>$EbO_aE39J$NP(1OgM2cg;6 zqz7oh!JJ@NbW}6dXuRq#fNr@Ge8yoW?D+!2)>Y@9WTrt7c!hE4_E883 z78q1w!6ncFOz-ADVDgF=A9~Y`N}ee0{jG&+WO}e16h3ls(G7y%-J=bz2PQr)5}|WO z4HvH$adUL|L@odq#RYbfrMZ_9SDE09uaA2G8rLY$$^g+Y9}EjEfFAnvVgZU*ilAD0 zEA)ox>v0uI~?s}z(J z+gceKlNq)l@O1)xB)V^d2Mnt?66R*80^=2b1Muu1!KWSIUo?A&1c;`CrN9^7R` zrmaTc)!96$d%+FLI9DjZA^}xk@`~-3=Q}~6ph3$G*tV~eo+>bzPEj8S-ZI7|hu)nY z7?vvm>oimdw#Vy5T;;FL!RLUPh2!?asucw;!O+f_Ob{dP{_meMrfMNC4!h{Sp zT)f_X;KnMf4TcQ=?j&Q!3);}xr^K}}A>VyNWV5gWgZ)6Z0mG7?GEqy$YaRfy`QEv= zP)tCTGo|ll1M6!PG?U$Jf~dit-qK5fR&g+FkMPL~YN+J33S5olI0M8uFl-N575d}T zYt^){RWa2xCrFdqbTbH&$8M&|nL&4@4GaqxVfznoymACD8=!L;0oC3B#}0HxV5)U` z<-Z3y_}X{~u+jxbFQoyt6%6ZU1z5P89*c&Nc(I7el()@U2ZW;K0IVl;I4M!(Y)sKN zEDjb#GM!EYFXdh2{T<33S{1;;8P@*?I9@qg$J{qn*3N=qn^pT#b02e2fl#`dsUp{q|B4yws+pFr##9+`Dw z!1e{hvU#>q&&GSZ5ZF&nRr}ckHxmr&lqb;dqOALmQzm0>V&4aX)9y45x(MJ8VA!VQ z+zx8txMIb+UkzcR@^q5yb{jn31$Vypi68YB| z+~iY}39eg?ro6y2Q=HWg?VH2U%`5zJ?pOa92w_+k0S=f^ywTdT}|aQxKc<4pm`HnKmL)%Z80& zkKLFxgfZu}SYS!?I;usAuDKqYI@- zubSF|@p!U3RcwOM@2PVe=uP3{5v4$SWezq4OV9tB0zMDu?h?{lO|Ui1>{I_W1+p&z zB|>_Q1-7|);Z02tF!B`D5yVOZ1kYS@kI7tt##j-C4QN#XM z-H+I$M}K13A~07_?`^~;J=72zr>a+}VdMKMWQQJT@I`ub9yY0p@c%g}{F_Ee zk)CZPjwuo~5!56_5~QRj^O3ecC>he@jg|I|s|ZoPz!@r%ZJmb^dY`;lCfXb270s`pX6A|MLYpdiEw(f4e8-|M@xxlfV2e zkk4!M4J@qwIfD2F?DO-#|H~-;=U@Bp+u_x0r2O4>1_HNL3b{R6u}{ zbvi>#huQIN7dAI%jsnO(mKn;7>Oe@bDjU_t1jO~jfKJq%J=ZQv<{z~<=9>PT(;88# zSxsn>vlPs(`Z` zDQX@Ml%uou%!|$?_$`B{&=MbN!PwZ~R8p^KFuJtrsH{!?+njkmN-Mnbc{yqxN+06J z0!S}m6QrJ1=Aqsc%C(hzHL+ErKMo}0w87xeF3neOx?_WdR_Vc4vzcdVuc`Q*hS5pI zH3sLfrX2$cpX0u`J1hVOrOyDc0eM>xem|^n*J2{xtVj#Sb=P;G8b=^Tgq%%eAFr5w zN-Su(LE-Sq1-YReBd=Q|Pi}BE$A?9|)3zdz1%K-*+v!}QIeQ~gKizIfLb%>x)vo*b8*s+dnyWgLm12=;J_rq|wH+EzYJS~xy-}TbPN=7`Q)-9P#y)wM8&JvSmPl5cd4~)Nk-4v+ zpyZ&Rw=R3|E=s7(x)zY1cZz&>nq4l7j|e;Qe6ZKuvQY~01km^4V1;9Ul97T`*X zacENhz(w7Od|L9PMk#cVPR5g^?}tNICP)m{cG?gWoW_Iz|Sz|H5X1f~XyaAmaNnI^&En=1L8%IFu+Dq3S7E z4{|ge-Gm_lTNpy&kWb0IaTSROK@y{G>$iTSB6Zm`@PyRbP5D@Ia&_CGsGP?ZBSMZu z*=m}#8_muK53BVD*ZpBHnD?*Nz$ldAIr_RIJzvB`^R7br4OF>2O56v3)9Y}4?7 z^z?~3IFIzuN)|@#Dvqb;eH57o#1lwH!? zYz`-lPZw%mG<^}oT6&(pQ3}=Zv=OpOV(%VfJef(Nu$04nSZxzS9VvT^KXB`=`$?Iq z22X2N3K#so>zU8V;GhW&ki$6e$q&&CqUMM;yaFfeMmli@p57Nb0@=hEnq*dKz`hP zJ;bn-xv5wdN?b<&{+N%k7eqf0g-f&*m%rSt0hw#TUkv7Bqk0pLxXSS42Ky9*`nZj) z>(x7CwHcsx3$w{oVY2@PrCGBFHgU)rt

)JH|V@Tm@c35mvVX+?u=t-J~Xx+}0^ zhw2dYhEw634}acQiI*g*1fv!xwD(y=eoQy%aB?q<3(mOFAI+zl6xGc-;bp5 z*RvA6bbwiyOu5HS6;mR~6{K)B`3(mN4D@!n=dm{YRB1}yVSCe7V>nRT>MfS{n?3U& zA0NH`0Nr;+2`};!=z^cN<9`P_&Ho3WE7+Tuo7kHe*!^3EW!0n*coE+VG!`2u5l6-; zWZUjQPc#rhz_VhBL7+ttGRExDmWftWYB);YzkEc315*jX<9J*OqfJU;fZ>L~xJ`^T z9;97x9E@G?@OXYp?yZFajbWjSaa4i=HOyB%p-uUu z=5J_LfmkZjis$RpwiVKpd|_QV0mRbr@RPrOH9A|}?zI6+XlCAjOE{;dIagh48FJZz zbipoxf=^bPIiQ5SBd@K;B|s3`;~1&9!9}jGJKjiSop_=SL(i(&G-jXl5;d?zAy4{# zKs5qi?j~~KguM1#*oQ!~wI!$`8Hu`>j~2y91(i2aXS*!2-`GtJ7%Hye+M}}DuU~{r zi~75J;~smq#dPA(YOe<*%;i)c0c6ybzs_sswO&dga$vLp>H9+!YM_*TyU8h-@O01P zc}27uR03q7Q%8(5>Bt2>lwQD%jSVoB;qVULRb)o!6fTJVF|~hHH;}{wfbFdZ7j_KP_6x`D0M+ zZ*eV~MC40=cZq(e>jVNqW|){UG_2c%qmwMJ{5c<$BiwrS7sz?Inbg{#q0{Piy-4s9 zaLlPEii#bK>%%Pnito~oqwL#R}s@Ng>PTJpnh8E|NV)j`}-4XZenD~Z(wO}VEbRKV}gR2+=>t) zSLj!8VeqU=Qqk1peIGgy7H}U<(hzb?>7DQO5ePHi3Hk<*>xqOk8;=Ix^ZFQwXD4pI z-wGSJIuWVLi5MQkxIL_Lxm`53I_-6?f4q};3!a)bW%em>PF>Q52rC1&(K}|U3bv{* zd8V}o?#-YTIW=&IQ^UIDzA_WS)&l4jbsvR#8FX&QAw(r|lLf%ldTz>5N65*^OCYG{ z#$FvQ7s!zy3~e-gVtA}Q9cuuCl|~etx3A9x_$odd`;n7olC`~vgt-90+GsgibRV(q zu>&WIQu)`x1eQ^Z=0yiOTcprtzG7oF2ix^9KMQL)&G<8(fJNKwcGLgIkQwY#9 z?Mw*tVK;6HM^!h?q3ybJJxRlbU&R}V+HNZ}m#J-!r2kd}2hdf#b6G);i< zw2UlRZh!O(*+}|m@ocFuKfthCWNbqxvYWG0o5>W(Uy>8u<~!q}s^n^#A=r;NMVu0wZMMUzHD~n7wC6{?|BJWtZ z0`i=Tf%Dl1ad`Jq-xgj%I=41tA|>H4ob)7YU<4U-5=r}3KhbnH0%hbd95UaiRwo=? zTxd9{ok<9paaz+man<^^SuiBG%%M%4lnOf2K#O41!3n}%eD0?-)4=uMqZEqvysDmi zkuIc#*CI~(m^Q^$>t( z#yg7IE0hzYKfr2r$fZ7nin5`b7c?DCcaJOtlk^U7PVfan5^IC@TR$-1BpIg>dHa!g zDI1y`4&RU8XD&KlFn!vTLp%)ENyLAqyDDN&r$eeCfi9=ve*L|`NhnOXX|;dI*zyvq z!d?e#qA+m1-^fbegm0V*YPQLjca=mChSoO-wa_aUQSm5#fpk`n-5W`lW)wp49rOTJv%8lN zTZb%!;!(4^#&@viUBCx>l82Obdv64Hycv}fNt+2+x1JbO4vL4|nb=TVh&x0SF_u(U zL)jCaUsOm%NU*25#L{B7AzYWc5=D{Fcs}DTHT}-KGm+}1;A8)OL@WfKQr)&>6!o2j% zs23hzqoH@LYw|cl?S`sh^bR&|sQUJb0I3*h0sPe=b-|>0*SWe(pUs#B>wXUDNvJcJ zndV!}uUeK@y8^X`eY5k5&@*_Vv7D$pAj@C;~0TTQM=GBXT&0mn*vrC!(g4ZVZCHU zy4zEy;cG9ZoxI<}nX`s9NYN~$#qDFpjE$J;!|c$`UOAu~=+dTz)_G61dk*}Q$XKNd z`Y@&r0h)bwGq1jLR=Qtl_~CYBa+Lj*sr>87>e$PM2-vn8vxc$4O+$VRFc$mSSmgLs zz7Oo~S2=ixVL?HwyddS{>;dc&}dHxX936XU9 zMbA|Lq)d3L879fkDXZAnfpp(~^H<%+#tHcNxe{E2qMvj;%0WPmH`p`Y#T(R0M;k17n z(8K@rX$l%9PZ}0<;AgH1Vr9m}QA2p^jS(SM5>==@?2*DpRJm<5f;IYOJCvza3jD*k zLMSt9K_SUzjU^Z)7_^3z!d08`b?|jNhU>kEn3@kxSw6{NESM`MPm@N;bfxsEM5UV9 zG*N^lgOoIBK9UBCvbAGWi7>B*!2#UEuu2>R8bv)bfxR3HdHxjZ-(;|oO<}!#x&vsW z+H&j$S8aA2oD?MLYcUUM^~q%5Y}`^>6^g@%@sp11m_#E+;J6tZn3iVjieL9c)MoZ2uURFf=5zPdcCu z#7JgWxliwJI!)EJxfS3E$>~hG@(abeii6PT`-LR`_OX%azf?P{@JR>EWJDagpLB3I zglMrrYyrOux|4`tz*^25$<+Qkhs#&ujL`$)g;nJ;2Xy5Evwe|)r9b0(0^82Hu9(IQ zoWb!pH7+am7~7f1OohRyO-f=qXdm6<2=V!S3c%Ns_1f(0vYeV95|fya6sW`3oHn2@N#tZdm(7% zZ~jbxx8lonazUdJxe=G`3=nJ!6$l>;frry=K>b}Xby|cUwHv&VL+oTDD(*m6AgU2= zhM?ho|DCu|h&<@i8C;6we{faUXM;~1q%8NNSmn<6r>LRk*?_+}{|v>}MUAo!c@Lsj zE|AmAmXJF9k{Im4Q=)x@^M?&~Mg|_MKG~q7`S+|ilCnFdQc-@UbpCp7DyZpk5 z*n6I!x_vabiFT1Rah|c3@bJTVQEHqj(C|6SXo`L1++?~-R=z?xj~^_ z>;3ZU33rzGz$1DvKE!A(?6kAc{9sgOSNw(QcN|y0*(d}>C}0&vo)rY z%=&dp#+BCJs-vdM92Ti7;|5UZcjZ^#jaYnXMVLWs^YmVlM93H8HC)K}cfXv~i{FUyHQRpn5~m@%HwfL}3GvZZ@-=jLB2MG|AgLBrVmz zUP)K4Vm;_tUNwb8%>;WFlVE_(ncPZdps90q^eB&&2LL{zceGJ0k)V#Ok61>eRY-R) znve1K0zo&ZjmL#}Sb#dPh2^O2Jo4|Jn3&d}fYM_sq8Hnc17~c)ptg9@)5z|L=Im2p zolQ9#tjtZhmeQk_8WKI45M8A9z!P?E{Q_~y3f-8B=jGyGwravLctnBfFIp5xr0rNr zMA#ZMF*MozPVw?1cYIMzV7smK)gBWnF0pZPeY)}O^$Q$0+-x(yaUbP>u2XE%{ z7-tsUh~ET=0P&}LKQ!JT-VnZkP+n@{UBbB-MU!|P#b**^uEW-#IG>2khQt@-l4@`U zEDX^^Jh9az$q+a5#c&`ZtTws>+xRljARaTsqMK-^qAn^EiA&ksvMAz>Gg%rkdFG~s zw`(xlQgrHV1IHQcl*RBAlnlgYW9_IfO{rwkV9W|9vkjOpHCY4iprU-3HHnmaGc%oc zbv-nN;~4jm%xw#=_DF^HsV|cfbk84{Hht@GW{M?be^p_+CTKI-6>1_Bg1t?DLAa4J z97ky5>4AC*%#Nt)+P;QlLYQreB#Sjm?$gMri8L{XO?R6!j5}N{Jmbb)MbGY(pR;;{ z`~%V2b)z-0Pl#^(b;V5nSHb4f(KGu`gnC)c8p3*N%8Hmus6o{sHo&8r&Ds-%e^oOv zu}PnDT@+37|FVLUV5XTL*jIrWWZ`vAFfDRcC+hx%8*zJrc?ygij_hG{a*fOBVE3%` zWBp5$&tPs-I0r;XE8A%H6&yh z6?6USVr>Xwj?NnA_<)1}D(ixLwJ3@eq49=0Q3T-~% z4@Rj<7Se#k6Bd`OAo+y!nJl&#SfmP-Khx8l0K z9hrZdh0fJgICia7L`e>f@k(&@f=`_xcw)JN&=lj7$}eXzyW4kco}oS7SDf8-j3e_? zbG3f$V9(hUIIgRv zuX5QK>iqo*V@1h>fDF7zsoJ8FBAu|@&gmJ1Iyn2*$d9yn!mM*x^JxG+`LQu)a>s^ zZ-u|?(vF)2bRk_!;);8|2WR4CYQohNx*Sy(K=!9t!k;t~I0wA;L}%i;VGG7WA~uWD zb$f)pzy`5iu?xNZl*NNKhX+Ck(=P^(eD4>_YaSS{8{mG?h0%W$f%L?kq;Yor~PL!~7mB zDnT3}3vd303X{}Z9z`IU)0-(s#nI(L#n1&p=bd%2`;qL*TY#ps_L z{7}`%JPhaQ!r5y|70AyWTl{sNVC0m!26%ZJOtShyy=B8A zxfv+2Z3x<^zdDc>9@iAt?G6fw*_qm{3;FRSTWQQzKn~uwV@AwgMh%*j z{!m2!KMw52gin)2n{t`{Pc~j6v3{lj0@zHjeACyfQ z7}R1S28Ac^&-Ncg(2T|{8Ke%X82Cj?7=UiKORQFvMxdlO!bKFz77K8d*( z32pUmM(SD2t64@dh!N$TLjqOz@cB2z(R6>FFc z`az`~!$FEKS)e`|{ganjKF}#NC2UL}R;bogaeFphUkz94kcbG2fH7+t!%b!GU7Np9 zm@TRVNyhW{7L>83!$T|fPETGp;{KTH0g5eu8Ck9Qx(cP#t$ncVJjW8zH zB#uvH*GEKnZs7~qCM_~~N8~XX%K=HlllPBgHH9$*Z2U2)h;dC;mXI?)?ma@KQA9`b ze2{dtwG%0c2By7KG8h+{(&ipTn9$q^3JVOmbFIF=*d2dmY6mF%_EcCO=uRuC;*OX5 z-ay+Fk)6ig2I7Db^udT(sQ5DieIa`rJaUID;xSy6bI_qJSR}kJ0v_I6BP4Ki^Y|hL zczSEHEaiMVIOTY|Xf8ltBc>A7gE{YFQyIl?x3pxnA2nTUox=HDgt^=AraOe84Mx8tJOkKZA(!IU7jOWRjng{Z*^-IRC|eeofl zXHYyzZ5$CMHOslc^^F`2Gv3a|-XEX#Fuaj1m2~vL3!tTiu z;_EGftzW`DJcZo$ixAFiz!=06^ZuGLtill#C44}2L>D~wCh_Pbs3kpWyqi$t;lUf^ z0h`ThcN^2@l63RUMivNR#T?Lx!MZy4c3j1Ue%eenin$&Ih<8NVg3^G^E=~r8R7#N% zHWyrF2KyY^kwLKf*1%(%wRZ-SBEt<{ECOTn!e87GTMbEDNgVmK%1vP&9XT^zW-2-Enyx(a#4oC}P zvll*1E%48rMd+_N%isN(ptH$;u2SU8MVW&NK8;DB|}@nY*1 z=OaCJ`I_W>Eqd~bw4=oym>}!tYi}+>Gce29x}$4*6f_DIzAq+p}ROW#hMnv z#G5jEfH)<#=#dFIV=q|+Cj`Nz2r26uN6+qxH!JJ9OTL)F!Ez`h8}%5A?#iJCPP+qg|lo?R_@$<-1J`H{lh992x&O zLge2!SIy9$JB|LxDVQu6Kped{kL`&ryPC2V7&G6$P~)1lDGdkh2crj2y}>w=s9g4) z#r#n1^bBF})0MI@%H+^NoQtC~ESc*Pzx4uw9}raQwoZ^nf%hko(h*9w1UVZNoXt%j zMl5HHGfwC3zaUCG@4^=bWzetPee$+k{u)&S!NIp+Wbef%rN~xDC>cFQ9y{aaE3e2# zqsUgO&dRp|{#-lK1qUjX7HYQW>b6Ot3L?PlRzP z_RagP$l##i5jiOW<{;xB?ST6rKS`^z^8>ib-vL~T0Cgb8p9tI(_~BBb#}1r^{d{!d zsU&E^00!)$p4O_z8G{#*;#(O+925c406M=Gk;Y^E%4j?zmBtu7X#l~SfYM2eg4}3@ zo@zZ|41L3Idxz2T!#iZ7;K!s;6RN?f3!w7kS+RciK%K)tfpuG#2#!3uWAXTpWSuN)xV2ujg%_qn-7KBRi+69D# zEfO4Iu|(*7y^t+MpNMlg=M&H$An3putk-@DPTF4u=kLRYkcp*2sg)dwto^`%3dk33?D(|dNcLnSgOZ#}+2DKa=mC&M6= z+pOb+X0R&MTJ{R^#b?1Lg3lS(NCN=#90msQ48X#^JhDQzy&oYuZt_vG|mD z#&rFg*1COw-p799#J>S${!CFxBzh+=))0v(yifA?jD+3b)M!2po?K}eO5Bt*W{sF& zsXDzq_(2pSeVa6+z|V9cz2t%u!CK{M)4fpt5U?laji=PbU6y{1?Y&NT{|pgTt9Xj~ zbiV2mrSS5U?y~^|(7hSg4?hNqii5yXc-f`q7XPnnUXno2sTCw*YxfmkruUZOm)P!u zmcP%s40ynQ_yZaV@XXjfIW~@5pN##Jlg|7rF7_6R+zX2Zf6!r$dbUcPr`lj`tkm=p z|Duqj*dkPVv)l}3N=l8urm7!OKveIJ_hnnnV%sh>iARjD?w=N}dqgdNIcqrMDpZ)> z))MFfA&Dd_$`b1`orUS~J!JKHNs&9mwdp^qA}er7X0d#XWci#rxK~w15iCBZ4)V%P zBlTSDl%3#2u+u4+oI{5((#M!#$=aq+vXp~VH-@7WUzI;&$Blkm9*$AU3-UmN46pc5Bhf5NBU0F=Biw;CdR3d2o zh-P+;cltM+FK80ix_Db8*OGXE_ggp~LGE@UeW~kZ0su=WqXyATt?(uN(-Jq2;60`- z;Q^U#kS_eg_!%#IS1}CSF-k1GiMAgqsxq#4h|R50BFX2 zl;$b~xR6tDkWP58VJ;*uo7|hr=7PG=BP@(O=Up3os)Q~qLXyrMa47oMHo#IYtkW8D z5+8oYCf6TWty8Gi;BqDDpRvO?<$TLGj~zIyq|h8Bik!qP zz(5y)1{JH`W3oy>K8o4{G2JX>p%^j&w0zG0XB%KB@HYSP2cWU#vQNUFO11Y_rTV)g z6frQj{ttL6oY~HPR&ILmWc~Rt0|}i;Rp&)sb#s9{1Z+rOrhj8#zJY+Ke$o!#A4f$5sp7*eyXe1^h9Uwnpi|P9S5WUt48@T~ z$Y?=Dr^g;P7DKf{&le8Bs#T@NNN59Yzx8d`Z~kGY*6g~;VQH2wQgCqpZ66dce`E)4 zT34(a4+$R&SCkYXYcfb*ngCM~E3-n`S5X^Ns!kSPiZmKe%M?Fk3$(t?ZIBXf9B6_p z7LYPsG*37dIJRNiu9Qdo5Zy_vv0j2Kfm)x<*^nh35oKl!3QNX zwMlv@Lnvsnp;)oaFl&lLiY4Nt$2N2Jwb*hKQ-VEXYPU>kcC$BzuVbFBScwttWq1{- zb6vUdxYL#@~z@gi?;hF568 zRV3y)LX$a{qW7Gy^3!6Z48vUjc6k3-jq$%7uHyu^sP^tGq|T6tAT`*hj};JJ-1adD z`tGRy9rMVjRNM{t*R#PD>b*?OW&l>*hSvvuMibe!ypxtS2N+949u*w`=Y?IyEBYAE zna)B*oTSawUN7m$4umurq47Jo7Cbx1ugh0hN!Si{f1(~p{zpz7Q>dB)0Sf<{>!}v8 z$7NXT!eDp}m&5@~7scLW@3iTB{xnyF*p3{Td^A#BL}bh8d_l(5zJ<@Eox&z~gDh{e z!tl25n&Wd1XfK5Gdk=^d%|k*7#+o?S?D_HQgyC&SqX@P(eeQ`BorAX>4uWRR=1)I( zmh2rm58KS>bBmIFvV2$M(BzQM){TEX`h3CWd{8Jmp)e;!3ujkd2CBAD5@_=8Nf_D( z5^8gju%IT^pY+X{&Owu)$uqydaxV;iZ@ML>1Qe-sp+=aoMy%u+VJ`R19LHF^lsWjLP~LIf~FuN_zZF9X;Cf5c_ps83g@5tm4eO)11n%T%1GJ( ze*x4J9dp{-gt#ZEUvKg;(z{STX}OfKuaXji#ARU~p$~ z^c+3Z8}}3hTDkI2K5C$)$S!4)QZqk#E_Zo6)%p2ZAw&M0<>wnVN|dzWkLm8!RUWNy zsw`Bq9)qyKREcQ5WG~)7aE4NmY3h!V&QFgL&`~lh_$w0}1`(U&pjw0t<8-*K79HxB zYUC&7Z{mq%9eSB8#K*5y`F9ka**I==Xrv~aV_fh}jS)tDlbEXiL4Ap-B<5?a4n`gCOOurxrC;GQ% zefv;E8xXt^FH9|C)CeMdH;3x2ZlwXNmdqJzaMuQON?Xc@Cg@o{X5yocQYF%f!?-2C zQ>`(A0)PTv{99lNIURu*_!#N;^mOw|U6U_&sW7wLA!ZScifj*caFLZ3L0Y!Oeu8J@ za#Z-oU$W&j%@E9ss2{z7K4E$oWsFev+xU}O%1Y$opxHJGwyY@sM7EoY@zCJx<1B}Y zx@@xB4=v=aH>-{oo^OjF@T{$s(T61DZw&6ISV3Px?o=UK6zc3*Mt$@-JTSih=4UY^ z)&wo+pUoh(xqLyswu_E0GDUY{uZ2O_C>Gviv^V@u&fKi(FJ1S4dRDT(4sVhMPXDQh zW_GiRuv|T&d8GK@_)(y$BItaWAgAAa8u0ufmVn_zB`tQYO&LO)90V*vV)hE&7Bhh} zL{Zsiai(y7A8Cqa-$#$l;oRrjIZd8>JYINlzk+0WYk+SIHThc+m5nxqL8B$vNc9x> zzi_^%18em7jWN<|pc83Kqy?=miD6oDZTIYMSNmI3P{B2Xv$4{XFK)$LG#7;yg%m-u zu1uAa>}llcuC&O(XQ@`MX|3swLZ|erVm|TSQ2T__9`;$nvaBj5fk)2@Mp`C;NEAqp z&r_K#Fp^IUM&~Ovj;I)OLN7@!Rj?M|ZMtjWF$Al`3CbU-Lwsgg<_V>)?XpO;skmMg zjz59{HmPrtZ9Q73*+#W9QRKg$EsNC|O7J{??`4J zeUxpYTgu=d!d?mR0`Xi<$)S6-%z&*}us90>ARU}7Z@mG|gn7_pprO7z^5?bt!fN=v3=6bFco<2&pPp`>E2=(N7gI=-F$xLf zMp?RQs2_P(mH>2g?Sv%L-WO13-dQPgL^uFUpu`vbMZ`}L>@e%f3%b#Q8L zHk+)^5hw{295$7bnXAL_F0UMmwa_qi-kKK6e-B~GPdidPav=5miipEO2ECZDHI5Q} zBvl=d=?nlS?Q5BAPi7fUkgGsMKD20(h>8=C0zJb5b{Abo3*M!7B6r$0J)!XNZPVuf)ZyiQ8{6SCs@6d5^E1dxxtM;uRNu=o@34N zr+rjz5{dn2QK!$~%TKlYIvH{UsrvzMX3xwP@~ci-$XCrw)Cyi@5UW1;$47awE{vRM zMUaWYp^i}c*;XwN-GliITTcKsF>(6VL(`&P$q1MG#AlTxZk{!@^fLjA)Ol`=uJ!?6 z?L}lZsXU*JcPP2_2Cb4jte%bDci))lZ!`-W zCSKU=pd3p=dKDx3J&;pf%*m2{h9`iKVQ#9ft3W2|98P2`28&i2&gDTEPl{iX)Q(zs z3unR!cn-_phrs+iPeE-~&VJ;1#}c!(Xdonur5BW|%}1Kdr9a?_Tba+-ObMXZq^D>& zN$_v3#t0e0jz)$T%`PE+c1p)fm~Iu@@o3|4GnJmb5K>3@pJ1*aKH~i|hE=V8W0a?x zmYXn+oh1&R6)=E07}?!+7c=o(?l}0Un^aTL8v08aXNiu&&|(VQwg`(?$3M_=2vFT(hR5@Zg#>cV&4@uK70DoR1VEg4C`ZQ4PQRJmfp=S1S zYd53}wmY<9IUCxV{RaCg`ZgeT_R~=lWA19?$f&ZqL-ms?g+Gs+l@pBZSCu>bs4-yx zcnug$0)n_3G1W&l6ElU8OxMT1xJGnn(;c@E4rOR}V)b}1+FsT$Q{#n>TcwVmL}!$T z)y-#zX=XCNNOw_IB7M_}ar)+R9VYyW`E=_V%{3}6#i&6#Z67B=PRLd^bOZI zijCq(D_E$@{jhE+D=wRiuMhE%z}7A)OJ56e{IsR$6EYN8f)OiImlV{SEa+Es^^aIA zSHgU{>=yAc+9$30pDhwEo_|^-^Vj_D*?WPkG=ZNjl6M$}sKPXUceXylr<4LHy3y^P zQGMb9x+t4i3f2$~0RtoiWde4m;&JxrrL41cf>nrYFOi~+*M9^Ub0uj`=o6jGf1OGH zZbha3qeBw#+4B0Mzbro%;YPma5JJZ@N{e9@cGvCY;^AeD5X;1r%`t;6iv1E+NRln_Kk zyFODs_}ikl+M-<%ZmJCB9LKVG2lULAAo4Y6@5qQNfCWPcb5+ z`C3f_ptsmVM8(x3Hzl8VCSId-S#q2acmm5zAGF$hG?+adVA7%^Uv8>l#qQwq%m1lm z)lJZJBx*M^k76~h?+-ZHKT9O}%l|Hs%>MdT*g*H%d-QK`+Ef$Kn)**3@x>+L45@au z666-N&c<+l3NHs0%Qc$O@U-*71-N?sXC3YQ&d=61KtAcD-xD=Hor?=xWbJ9Yuy!{C zWCPNVie)|Ddi+G+HC|{jit}meKxjwUpu!FWDT%I77mfv32vb!95a35O@ha9U`AcZ= ztfkuy9p*R0Lt;B(X;Ch3-hd@)Khn|-{s+;li9kyuihm_L;OT)(A4imM_zHH0;Bov0@03=8WGWxxdk0{wJ zXZm73{AEkZs3J%bIl0g?P-<|vp+*C9S9ilByD)Uu!!hb~9r|*IErwGa`kPq6&QqLr zIudL#hKUKtqyFLS>73@poB*x71sqcC#2^TtO7I9=Dd%_83AlnFzikz4mu(ZCkirN; z&n;9fJax<-wonuq{8oWqEAgKtuR0i;;20M06OI}P7wtI2WaR=8fXnTM0`Vl1r9RVp zPRdxj!i=rB6`gCa9MM@_B2QMya&iIYri7^6QdCmizu=koZ+K$-fv0GM+SDa5%4K}T zXHfkbnEJ>CN0-h#B4B;%VcY!8^U<0})b_EqZ14Lc-zc=TCKT==#~U`oWWgVJb`k0T zF`hR(eizlUf#>UPRrw|b zQc`uvW=80XvYZVF3}P9@W6I73DJ>$WgapHMfXqyPpG)6_&~DXTazOufh%aEC2+aU# zwy3D8x{nQAPhmhS{^>? z^qOFSft$7!>Bfh_59k&uGK=L~jMhqOil5O#6;f=xw%Gnpq zI72Z=)GCuJMzm-o&?4b^4Lf-eGd}^YD6Swp5&bj7#CRG?@6PzD4He7FTl)8i5kMUc z^gb1rw&U$U#qdOo)fJiqC}+ zM%~RC5D!j0?2YZ}6y$4LJB>R5eaMEu{?6KNN$3ISdm_SlO!IyNypSms>tWM&%wYZu z4*VYLcREuDE&DV@`R)BR^;x&_Ep|)sXtvnVJ$=sKQ(aD&o*T5G!}Ft!5O)=RsresoPH zdQAUtpUg)`N3IeXv}md@hFhaO6qtreWE|6#>{UR%Nq&(MZdBZkthh?LiZb+bb0ynJ z2)wxR3#24bF+6znb{8#`+m9#*aX+HyGXI5_l z?Po%bEcFw{7Yzk4^4@)w|7n&nt8;Hckf9AI6%j}@G0?y1t{rHOD9_K3DM8uYDynA> zie;1dOTxf&lUzXQUsv9LR#6UK+(TZ?Jl+wX7*X}5Zb${#S02(ci}t>L?u8vzaew6w zrIV828aW(+8LbOtaf&7|UIG&=_MzyT&_S`-gfSL2rRP0H$kN|SDoRmx4o<-Z);8*Q#jfc~F;TdIjC$4b(h8avTOVU1o0@e41qg@(kWW3`Recz9*t;uK*-; zNn$!Q6fu#idicA7Xoppqu)|9$!6dh)qC(f?seEkWyJBqaC!pEM!Bc{<+i2|Cpp6|_ zn3jtBOR})Zb)j;)RFLpk^?urOpAWtn$LoK@_^H9z zC-D>Q9{)eAvYd|Ne|AznU&Wd=M)cJ6@kgZ+@DX&XC*=bdYtL#W%~`6`twS*vZ$GD} zxvKB8Kp+OJtwp`W)qNJm#@@Z(WH{W`2~Asj!r!bdT_)HjU98>?HekGflzS3=Gv(8| zLw!@pEp-(7RX*3m1)Gt<8w%Rwk8E`10tdpPDDVdv*7F3y$`1im0nS;Q*;9gOL`buw zrA6BO0@&a(2{LgqN!DdL$Sja*iuv;Nqb}gCS4?ibwp9B}cJ-ez&OX&Qm5v4QUntDV zrK3beHnK~UNQB}2lI8lyVQLKuWL`gz#*ba`z_FtE^KG-`$yO5m5j-NyX?6kF(uG&3 zhN_C$%0(%6VhTO-{;vcJPw9)h*w;KENgo&_xAHU3p82X9BPgbdzt@Xaa@O>FvSc-J zUTJHNT`il4@e(wQMNn&AlNhC24qe+;Ev#;`CK}Y#%ls~?6#YOdF5@<(n|2%t$B?i( z(@*T%)fxH5!q~D;+?vtdddG(dJrR~FmE`Od)CV7!m7DnYOJ>DTi91Y z=o#B+-KHF#u=_59;Hw%jxZSX9mdQ4b!AuwWd_2AMt(;ku=K;SY55JcUGf-|yP^Mil zeV>U+FyXm~DpdQ@OfYlo4WGB@f zIH1=wegx?>r4@(~{F?rj7!ecAg_%f_13>l+oWS`Jfk(7IZ3_&)OAKQnyi18)cLo%+ zXek%@Wft!j&lfH*E3Pb#r{BQkVzSPt!N}R z{}4iUzM3=CZ0L(4<(`m`0fS9a9NdZ{Lx$jTQJAKH$Y-)+Yfyq`c`%6fnZ8`^`EFZG znh&S)`cN6}ynf@(E9*vJbs4t@?I5&u-aKIXCpD_kM`t7Wl3P$8me?xk)+|)%k;<0V z^g|Kc4I_QM|JMb-ZoU1H`E%qW{_Bzd@1*U&j=a$!%q{pN`jec4$ zPjlYuslGpF@q7WvjpRmKL2C|kV%|Y<_qc#^54~`#IB_YzJ7QpPVjZ27Mh~~V9m8F@ zKqlSjWEJFb^E zC6LEuyAY}fVUTH)+U#6I!HA+R)pd7-j6*kZZ@Ro>TQ)izI9_j8d){;;w0DVaTd`(U zgj5QJW2cA3gpn_5)3$7HZEw~tYc1=TnawKvYHa_pCUSYxwUL|QLtEBZ&UDNFyv}&v45_D_H2m$x()du`DW}tW1SuP9h@AezQIM^bjz^^SWVe3C z=B~60q?e}0aKm8Ia8BA_-nzV{0zjsz35ABxLFkCrvjmBO?_v*N?gtZa3#Hk{TzRm( zBJ~QmJAlU~BC3QFR!<(a=UOU!Auh%^>76x zI@qPIjZNI5^Nb85Vi^S!osqbPV~DkB8Tnoo8m}BP zQ_(}5LPeM7qKVW_Rct%oIwm7IZr%L}?01`F+`^__IXnh8SS3s9cuEg&(@a9jwRb2kjw7n2rXCRT&qa4wa5C#) zQfqPLF?y(Zh6L-Q3xcfk`{FExq&;=L+Aci?;*@1JvI{<3Cg52oGhL!T&Y{bZDV$pO zl@_>u5g9)g+6-2}XT}*_du*ZyvqFv1r|_z&1ENr6$zaNuea*+{CSH*ShppLfO2!V! zrrbYPOvasI3#aZnQxlU zlaDAD#hH$MiG^Y;WEZZMfq+P|!^q?m!VBpcp{in!9)OwvR~ATNy*sm68rF~mAfN5B zNqvZndkjn6WMZ;}w96){JX&AjE?76+gD-<|jZecD_pnLekJ{*9gt~7;;nu)K#HH_a z%7sZ;#eMufEByv($Qh6$^Q$mfN28zih2AB@_#OYHzzI@A;Ab$9*$1F;ugP7V3eb)< zWFm-E1_Ad>a{Sk-EHPVt5!X_*AZGbMOMaL(oM578e<&=pcG8nS^$$i5oXeh{^97=O zHHf?4pyy^t$e~$c3!0bn=E-B^rxA`3P*xNP8l`p zJZ||SZoZ^K#iGbl?VRjfkL0fvO1gNOAt>{8BVbIFfrU;<4J#Q$u!}Olbxwz42yHte zfxSZvh@7T)zwpu{5-!|$6`uJf$%HBkB9^dGLP+rBp3U-2RXJ=v$vE zLLEti{!qeGqQ(lsYF~{8sFH-1AaA$4dyq5yK`ud47ka3h{5H)x(> z;~S+De3iK-W8Ue!BiW~t8daCd0#u#RCQ1mxV(ZGAixjPeN|+h=d$!|5&5-<6FiqY< zl!tZX!9JSss^bSpH*ur2QWQSaKY!pB(hV)?Iy-Y|jxa(#WNYHS?OXrNkIuq}O{b#& z@S}0Cx0C6pvuu_oH&>U(l>g#KQ=EVJQ61=xQPXS#R5$} zJvNYDJZhnI5!c3Q`WQ&~hD)j9>&+RqI5&5-(4R7vbW35q`mZJ!SZl<#_iL_O%(YlC z9+a;0)Pj~1yvH%LkS-1;Eh_DU=PT5@jWmn+E*ORG#75wQKe9gQ(Cv4h0d>WZw7e*& ziK%b9WCLa9-looR$8DFegV_;!^v>^vp=!y}=t?uz7qp3L$$aktm~SOuqxHXtCFcfk z3%$jOBY75mcX9Gy0YPH62BKl2CEmhO&N^^NxV?cuNpkuL2goWh+|WY@ke$L}+7RUZ zP|hRCafm&B$Z8!!nBi30yZCx}r&~(tCF~LK!!i+CXCe_>#S(0R9M(o5oDH>+qiMy- z`w%%Tv)T{LWv)c14`WAI&z=){(nSh}QXP1~gBf{7+6z&f#CE zKbpP(!hybaGW$cfbX!LdgsKGwD`!231T9k0t;UBdxPS1Uh%1(X|IhsBk8z}sosEs1 z?LX&0(BOYOPO9F5S1C$EU{EopxS4avrms zcD8%J|9;8=aM{a^FmzEELB&k2MVzBQ%if(3<8cjVE+TZ15JjZJX7y`eoYG_UdtgA) z-klKIG2^nM2?&gUPCbgAPLuGe9XUaDF%Y&<7v_RJJ^K0J+Jh8>Pavd0$2XW-ifo&r zPoq^iwkWbRrZ!t?wm5FnM`~2>p{Jy8(|wU{&pCvs56@>=ng|wl<>z%(#AoZm=D+^o z39(@J!dMs|HO1f=#y_s|$Ts-BL;qZE=^@)HXYNFTc|M~BQtd3+2=jFXBRLbGV1RBx zKyH>i30#}0qPBE&XrMrMEsR8woU4pguY)bD8t}Q9!j-3>nw?#6$|SWTvb2 z1nz8f%?T0p_|k--nktEXeTi%j76@oc;amg2EyU3I+{vlhQW;=R(^FBXq7#(o{zQr-#~QrTm8PX>c4MvON;zBQwy{TaL>dAN({DbAfqI+hJ3!VraF30O z4Uo?~f(QvAlePXuqB>;l;Z4Yp{0GuPeSkp7kUANG489xT6azJT1ADu+%8N7`on@QT zl1gSfW$f)Gn-~i*d4;_^%zhS-Rfj;@V@fOcJsFVOy_A4WceQ@rIhu`!F{D1H9VL6P zTdG$8yoaG!WY0%ql&%==!97h_5&Kj!1s6P@C{0Nc(`0J~?mE%+A}GD3>_Ji#*+zaW zhAe1r2$pVXP)xYFul5L|#dv!){1}6m3rqpCgd5>IU3%*m$?dF~^ki%MB>osMRjm+O z-L@*rVpylK!KE55jn52Q&h-!gG}^qOhx?d_8|gO_CCQUl{V?`2SP~#A{mE5+J$vr` zYBFxzCPEMU8Dp2Q9Odn__f=kv4PK+%wU z<}(;Mxp#yD4E&N3+yI(_Yczz8Y)uVm?9$s(3vQuqT{d`$s9y!6{^@>7JnYeif=|1J zw1h<^xcrKXaPX>D=6ZlPB54~=N$gVir}eOCbJ39j#&a?+5}w?MJ5upqtP%$(v}GIyZEgJ!S31Ml=(QUtObf<=r0h5=!1;`^f9M*UG(;) za?VRydep@`Vr?NYrk%F&I<1#}m)Dx0F@O8$_C(-b2}PuycAJ5NrEaq(tZNK(PEJYh z-6-C1pZQR+D>4tAocBqt5V3XKF*+%jLcmAr#qxRsx^XwFMpwqKHTjB7+pMN}e@pWI z7S-#|T~%;-Q_lXC5}wnU<@$C{;&}GkeYueHz(yvig;ZHctzzggiOF=5cH9l-Sb+|5gD31Xdgn*-+GN%yL zjg{_wY*S9|1$Q+c;iNIc!*!Y4F1wAm{1HzC-dQ@Gku}68Q@RMTYbesbG)yMqK0D2O zxiaAtTJ9HAJ@c)t>acS*%%(Wd9Ti1~94j|Jo~1G^s>KIExkka`SEzj3>hV2F%wNb+ z?_i@G!JWeq@gPpY5$Oa3Xr+M1=zj~rsAN*x!+vUt)*n0K|Ln!~ALK9pE4(Y)*;)Uu z@Sd!y<%IlW5z48-I8HBtj~KTp2)@VIXh4(~fG-}PPY+=(h`(p!x@ZmRW_EC64ek!u zh0k_ep!&DSPF3Trz=V}hB}I<+r@ELuPrr(m@!PJr$+>arxy`EWoSo|Z{``yPcm1k5 z3LoO)e3%w9&Aua8xZ3U^G$;-w>L4hFG~#|z6r#lG9Q8P8;mR>Mow?ODJiUpzGhdH= z>u7W-PB>f$frDtajz2wJ1S&RanWYu+5@#Wr;-wZ?Y6N-9Ml||62TM;#V6e$ArCEoI z#_884sFE&gJY8G3)1Rj7v0S$;=K z1Y}g(-02C?2y4)79_ObZDXG-~6pR+*?=5;`FYCg)DzQC##G)rMV?7qRhn!zN{_a=x zf!nO4@aHe2laQRZiO2+zGK?=Z|Hjt2nS&!QnOhB-Vy0!!xe@klkt1ysUNQ0xqf#3svf1E6- z&v`NiomFY_Vd5tWaLq?~o;!=qBtFxokd@-Uli9G*P!+(p@XsQ7KtOY2$f&#ul!-a& z8c5#LNj%EyKL@D(vZ@3rn@U&ZQp)jKkw9~7(2T;V7uiDHNcw}g#yvHY0V93#iCz2# zp5+qBF@KDG580l?eN~2}>!RJ-SQzpMYHHul59jLe7~oH{X4xm0g^k-Yg-MI~3c%3v zIoHP&ra;Tmn!d`*SO-($e~NK$q|JCo2?~8BhG)|s;8=f(3zX_0GDrr>J8TBZJE{Vs zM?c15TZ6?OMf9ulayJ)%2L8-_CNqKKThLw{G`ovVC*3H<3ey(7EnLfaF!Z{L`HrLq zQN5&&(O9OGN-PZ17OO3=^B286oEwaHwB3)3b0OxOOQi%;*3Mm6BwZad&2Pnp)@|f# zO}8prmKuuC`C&m$2L8;UR_@_~u||PvSSnGO`V*nzVbHVDLeY-5U#g!Q4dU(ScP6g7 z_Wsc*(vBIF>IIHE3Yv2E^XKYZe-YB-DfDE^G~F|V3lr6HB8Oy|E-FB7IIjl^TBCnY zN90Krvq^WDGImiczs+%w5nSX7_*WBnDsI^FD(p%I&r63IOwAx0ua_S9&5Rb7#E{G? zydh6#1S=t#6Xn0s$8ahYI*ycfsKTYl0b)@`nk0?Isg0=(?LN(91<4nzlPke5hUWzTg?(Gw3sF|95JgO^7bpa-_4uO_ed$j<;Sxt+Qm+p z8K93er)d<00IY*xk$|RXGWd0QW;7|7fljJIj0F^zphhDyodY9xog z3GPv^S80JV&uTnUZbgUGT0U&?#+a4==9C{$)-1dffmWZomvPn$M;C7vRB`1Wx5r;r zY^qrhX3{LFOIk{WB56sY4nwyn3J$V@7O+iF2mX8yrp{|Sop03kqausQL=kZw`4({M zDh*2}WvP_S;Qn?_cR;$vw9iKF5(wWW9??=4a&ZH)O;mN0nD(MXWZEMaL4+gPSKxz1 z(1bF$9;Bkg^h67q&(0@HDOqefC?W)D&j{3Z!n4AXuRM24dVNv%$D?GvrdDvJbk7&9 zqP3E&t&KBh+-fRAxm9<=yTrOO^|F>XG`v0y~{9nOZMS_^&-)&}G&vvW4 zprD{Upti1{tgfK4qM$W<9}5LX%B@pb%A%mUrypBeA6@ct-Bm*k!mgmSqM*S?AKIS> z3*5is!h9S&Om#baEJ}E#^CJj|fPjdAV$F1QE#sYJ4ILaT8HfS_)E#6A<*R)aRV^JM zhyt;FoY0Z|O6VE*0g!;0(u@uE02Z|QF+@RC_$FHm201IR&S4KiyNXz?u zXR|IliJr#N*%;wF>^qNU<$bq~9{ojlm<}j~Oyt1E<#dvD>wU`l{&zGq7T{uShA{9_ zgWYqTpCJ;ftvr?l3j7wjY=g^f($9(5M z4c7p}6n#S9{CZH^@rx_;$fn6-bswkbXM~_Ud>i@nuH`DWj7MZ~q#7Um4w!jF2RaVK z&{Y~fvKrr9=#Wo9>~nIEDYob`)KX-zu9$cW$w=y>#OmxqRwLwm{l&{TfOUQ*X97w_ z5XISEb>|>6DoVF;o^bCpSBDdl&8`7YK~!e+dg5P_+PiV1Zi8AFe`7qFlS*ST&bevh zT2p8b5R1LjjWey)%yS2q9X`B@>PN;Kd&&3;ByvF|j8LqM>CzH|txR=B6C{=hcNtN` zy@OpneSZB@{dOc$g)#i7g9ZO7L-Je8s#rw8rdV@+LzA3Y0!y<}wX>tc z#m!31X4}=JRnzUKGjrKR%VhTN4V&A|R=dQS%Q@YtPweAo@8jEyThF=M_s13#Kpg;` z`#$*F7JGj*iLQNKEj-ynYm!7d8Zz}upF!48^|&-;n)H1@Nb*+2!@`v^o9ttNoLTnF z&*v3sQ}&0_bV)`mZl*tCOtzW(0c2`3#?*0c(!}&7dW5vcZS~7w%ae+ec1zQ0(-lk8 zGSij8GdH7bG|T!N37A9>ZtT4klP%4&5fNSWut<$267Ghi&SPoIv?-H@sBvRb6=~WR zem-4-&QJ%ATAluCP`a8Ss`M(ug|m@mUG+#S_nL6AjP$DGdKX>m{%2`c_j(jI#`U8S z))3nlK`>YMFl$pskVG2kjdWkCLYqU?QmoFdHXN?*Iw-fcd&)0e9dNdWznxGHWKK7Z zhb+3_4Uz&|(?^$AiIN1UW!X~OA4X+!D6TWhBz z`L(CA3(*v8CEIJU0N|EZ+%+Vbh5gEsQUp=AXR*)b(z z=HSIPs~~WoK>b4JeH-BASrNnsFvLiY!BbH^%2OS#+RST(B8|UUs&Qn^Izgz2?!`S( z0t!vPV1dn?2&D^$ZQ|QXwA!iGkc#6IT7=2bw-Ka8+vvcu&p#0!Mx$Ef2~owLM}Y*V zmh#2B*yivcn8^(5g}uF~!Znd4E&H2RMjG(7H43SaVGxbXI3+${sx@#dbo2;ib8OP+ zK;fjuq76NOZlyTuq&>*NgX`NwJ4FSDL=B&h)#)Om_989@k~VG?jED}w50Eb>T;k*XkbtFAVwz|5LXYAJ4iPPkX%~ri)+gL4JHr*t|V$Oe|8;+Ztxm$_&gV9 zt_w^<8t>&#P4KR(a+@kF)GzDkW-1ruq#7)rG;~RIK!*%4-0}Qr#soJZs_IPA8Z-p8 z^21O+RMgbGJ$v!iiKZ#kF(A0`OHx0+SnN$rcopMQ57B2#bQ=knHy`Q3up&z^=sCH1 zP@&b1-Ge@ZT07uzv^XxaR9#dW3{!`U{0kH!rrGqL5M$`}yUfhA0 ztvRL`(42tc8QnI4BP1{U(2(tjbA$%4U(zJ6R*?OQO(9Ar1##L;jKr`VZIv*NU*5@0 z=5Y+{)iX;oT&gwNM5<`CgR)X!z4I#@u0L^Mj7DHW)c6v7fV*?rrZwRJD!-Al?lqOT zyV@O6%(9q5;etsg97r?k0YGa}h^6GL^mQRDw0V&Fso1tp9V=ldTAM|smJ`Fng^ zMT&-4_+LAD1A%vb5o`yc${+MQMF-P&H4&|Q)s#D;Mt2(S>IcVa#gyDbR(t_s=L1-u zfXrMk{S#WdH3vBErI4ljQpyFf${OYFXi_e0JB0_`uL>wRAx=l0o0I~i>MH@#JIp1xNcw`{^p?4V(aB=;2Nbb_ZVEd*hy8db^>?4hQ z{%YH=aS@~YGAMlExr+C|IYn6vf`Uf9-IW8EcOenECnUN3vlXxOyayw*^>U7dQO*Y!gmfI5s-F+bjsepa+^d$#kp)hDk9|e ztDWJFk0C>djB@)Mol(uo?s&cV%RPn$`>y0F-DCQ_SK^fJxwWn^u;u5&Y1v>a*n@t4 z6&tqF9!bg@E3r`eM&FSvu`_*Z@JN^Rg`pkKmNm1lt<=L;@dfD)V4!LKkWP%h8@o{L z9i5>w4l2Eemj)O2x;e#nrcGCxjPbmzX@u8n9q=Jq5F$T2#P*lB`vj;&=-| z;#nk6tjXT%&%EB^M572Z)q?;OS#m%b>aENzTCZc%g+-|EulWQCnyOnSUUb;ZoSG+8 zW*h6rhGLqNrKtPP(W_t>426bX6`4sIir3UAe$y5G*^0q#*~97cs`YVdB=NN^N2q*G zIbACOQK-pl$j7OY%P7L$sS=8?fR}LUHA3<9Ud01Z z6>3H_0z1hyhlt&zTB#*y`s_*s6a6*foEbP_lA^jh{;O z`_L?O<`&P{7+0Vb4aGCqQ`tQ@Rc>N=YwV5*{1Ym^T(+R^XF2u)!P0n2AbRY05}O zDqNV>NZ}6o%cW0>9YO>k4~^mt2RJ~pq_n4cv1@wa8}ue7^SN2>8(QpJTJDSXeA`mh zI~w3yTmG$Zv1@kW8};^bI_1^&mDdt_%YM&8+6y;vD|DbGWmSer{6=vBau)gIvJCqx z2SuJN3^lCZ#y+8}f~l``pXpaf1$XefG0(n&}wqHSqol>DKfU+T`8)6sd;OiUH$cd8$5`T;sf{e8O%T8xxHl|+lPpA~{iVVyH-ReREZQD}J@|Ytxrmi{v*AwQqnVm2AI*Hv{t95rH&j zfW*h9-_m{Wdz17KxS7CxvS%EP*_vuRB_w&tB#uXt#Jw4t?qNI_==R6G(? zIKOTwC~SeAQSxb2VFiL!HqAiX+h+{@Izfmb^O!vNeL`X89*F?X6&dH&x!((M=2mU4 z<&L|wzkq4n=G}(rr48QIYV1|nDLN`Bvy{N}ErXSSmzg720uMB}t{6~E2&)-iw0&^2@XWLj8_9+aQ%$rPpcDIs>Ic6@>6KKt%0V#s+JwL${mGm2!bj$VguNZ0C>dIP7KToA!G-fY*h*&X^6&OJuq}o3RFP^3Qb><6}N%6eQqKH-Vk3KtOm4olDlb%r;K~HfZ@N+ zyok;a(4}Idi^QL45H2If>=R>8Xu* zP@Dheh71eU4do7F&(?>mCj9d159J}fLVVSF<=QuZD<0}iU8|M6+ANMf5x*)9iB3@o zZ}5k9@#yZ!9@kwIm+wQjNyYbij_*z|u0>Wh;KMl}AyAS5Z<1+5x8R zN`IK5p$9B4806B&+<|z!r&afR$pD51N8oSz@~6b6oHOWw*Cb&1eMf}p1fKcH{!OSF zqMy86KPuW4HVbw5Jw*SdYvHX|o!c-*S!0ChbY0c?Y+!##M2{<%KJ*7;jCZhx*Fvq; zxmoDSlB66%c9)3^yG?}?x?Nnx_TC#BBw zmtl62Ll}Z26QZ_nY{1h|A*Ab|;qNq*P|i0zMPWjGt5zJQtIex_L-S0)SK#_X0L`l# zH*Q5D7VYG{dyFL~QIrinv~$c*VTLKb%qlq8X?H{P#-?`&5g^Yx69a6C@L~udTV$?F z4c_3JVEEr5PwAbVxv)`WBSc6u!3?ClwmsG)eK*;~2W!rDOk^)y7WB}ftx<_;HWYSpLug6_CK6^w-O{$)V+kpO7}U+q>F zTy#(Rit<54(2)oAB?D{+k~Gk(G%2BWjQoX=psDpU7$QGK%KW`%$rYmdP@J-?c*1*B zBT{LXVBE)~gB$Yb2KSZbBUHG}zvs%H7OcjS3x?#Yc5s<2Z;!dmxb24ZdlGH;xmTLs z?1OG#IYkoQR}AS^fZz)^;vOzZyB@q zhhh{J}0dcc1Ao)PlJu+n39xd(GW4Wwe~&z}O#Wdxf@_Mq1&54MQFOCfiu z%h}LM_A7_H4C3q06{&L>5OFZZt_wc!V>%XAj~1r^>;7BAFA{`a9t3+hoj=AVHhx2} zW+lNpagfCp+7lh>8aapH~3%$Rh^ z+-*0hEv6%W_|6&rl+*RP=_w^rQRVL-iKI+!WstJ)>oNHmUS886z5yYHGE<-B_bL^R z;MkA*`C368M0iWz|@iLKUsY-0DSShL!fUTIt4v04u-SgY z`N{{C@EwBrP5e_#60`C%k2W#-1}(>xHl_^ncpz&sty_GQj`OhVBB0jHg}r9yLNEi= zr@2GLK#)2(R3YFMeq>gm0QLlX09ZxHO<2enGp4!9BcVQ)B*DVa;E3a=PkQ%nuz#Q( zK~CxIa0CDV`X6cQe+C=>!|0J8Fjda#-@d4VF3!$&w(Wan=K7U} z*nVW{W@>igVQPBo^ZoZPRNt?hAJVFNzbA&b$mOR?LP%7sSFvI299@(b9%2e^K~r2` zpt>YP1V#$l^LSdUQjxMcWffgCGWRbon+`3O>9QSHL;V!Ju}8z9)A?%KCJOZ6isibe z3U@T7xn_=2Mee-lQp+q4>YL*BqI=P zzl_tq;D{XmWaLK^tU?8Yg`Q;Civ+$CJ{7YM!p6xNB2l$qH4~&LxLl~zZng|ti6t|v z2c8A|Vz7r{T56B{?=#l*#Mk0Jy8QKR4AXMjLjJ7}=kqYyEV z)deVBrZt$-ZChZbKm5hyun``aGRYjHAGmye1Tsjwh_*wJkh86>9BBnP1`nTG2B+JG zh&1P2cN&SFOD{ns62^Q=kCY7Wbx)`fMShG$V0vmMJ~z4?gjr^lU-mCawV`|VzroBhC(zyB*d`5&6I z{vUf-*uuct&g_4-uZpi4k{EKg&@ZeN8hrp1O7rUG@n5#S>K4%|#FojR0{oQfo3NQI zv=Xl8H=x&I_ef8-aaoJ_k!}3P~kIw{Z`ZY5w1WSIThQqQ&nd?QLb1b zx9JwcYvpL|GtpKBo1Akr3;O8b>pV@y^y!a3XL&`xr65&}S7XwwC)iDHbU*IXs6qbfj>jU=w<8{!#z_wD6K~xDo_eV= zR7#%LdYMd6w+LPjX*y~gqkPjP*3jl3Yr>*c0a0w{KF3UQJ$l<|K;pg+>>#|Cw*5|P zymXIuA#!amK4H+JFk?ex|DQSRO%#a!rOf zvQ$tC>N64%q6aN*jlmub0n_5om{xnEW~P~J?rxa(tD}>$*QN>_dX3>hx^(UFwh&^$ zzAV`0Qdmt?$`+l&T4#%KAr~UsoJL{E9L=Rk2USaRY+>wA#3cobCT%2 zB)K)p58~w)9xlANp;l5()tx;xtOo6^UJr0d&!Lwj3Rr^9#)j*auvj0g}?5@v1WN$?GNvHNEfvqEP+zW<0A&sNLP10+z}7$3|T9 zop|5|%j3rRk<&KJ_AAf)gl*elC@k;6CMzuC)HiOiP*0V`44Fg7ZlgAhefB{bLutvP z7rd|I&Y+Xu41zZ&%T_=Q}ZAFKEf7w7^9vRXR>~q_w&Q6Ieg26uCcKqCtu zZdtwu=J2wG-wX?Jz!(riRpI-Ia+_g$^I8e5Q=0MgvSv&((S7_8m_8AOOe@AUkP3T^ zyg9uHcQ|ZIG`Yyyoi5C`RY1!dP2mRb93Z)_^!q3UPq6l(nC&rU;hrp7lwPQLPkD1m zWAqXLmrJD>-qgPT<UVXm#qinSX`)}9Ye^9pmgbXG7pApUGN=A+*Cbs_$7{RK4 z|FJvyLY|DbN#gedhHSzJ^qLy&TfBt(eaOXv) zcHa#BVk#;9YXO6EkuT!>g_x`!$&@o(Rj%{h_2vB!&ezLLt}ozP^sdobFj)b6cs{zT zA$tfyR>a;odd@&uKs`Egl$ZrawLW18I%)7p6nZv_p=AG};A0g0Yy|u)#C;by7mcVV zw1x2yIaaX0li*R%7?i;qQvrJ{lpr$ZDXNH$Dm1I4U>AN+VV}yLgt;qIjDb4h3QYE@ z+0%NE7DKf*p~{kzD5a5>LLQ4xD%?6oH+?==$!iUT37uUBVhfzfmEi!576hMRT$45Fh$P7NbnIUihGu8k zfr?@YlAsA$0YNMMI%qlvPv@|Uk^;8aK{q_sh7#VJvvjBsqN$Oppg(=ubLqEh)+6K| zC2))zj*M@t5jppjM^a_k5O*9#bs6g$4di#k7iK+0k z=Ox1%oEPBSH)q9N=?=ePi?P?cL!(`y*GP-+ihQ0xw9Q0xvN z5w-#~QEvBiP;Mdad21?O`NKx-`G-Sa#rsDodHYK#c?VA+d*ts)-juybhE@f=19?Gq zD_&*2z3GPF2HwS#kw1zKFlj4ZF?!2hQFnj3h%j|t4wPpY;!$N}>f>atl(If2uzw>v{M4P&tsq`AP5ph~rvsOQ)ru>93IHO;Oa*BcTX zHAmpdtX^LoNzG6q6s#)9+{wGfrm-&#IuI<5$kP@{G+mi|m%Ir`$#@7dIC(G@B8WCR zApwOQRq`o9SqcLZqQ)F4{%*5DqfN^h(^1os$;={amqjarc*6$1Ez8yDwJI#Y^{rfK zE;RVA(JnYBm#3d$5L<)55900|8f38X%F!YApL`4pMvj}y${o$t>dU6J$EY`&bmj3d z8`w~cGREm14M0vElPni+gd7CHJ33F`yf=%d)?}=64xPh%2 z^<>@(Uo8luGQXfCa_JHTH^zp}96mZ9nk>CKSch55P4AFau0ndPzW~#8b)=H9r-$fu z{tXXWmy5Z#pNFpb2jI(`uG*Te`rX{7pg6myJBWe*oya{2fY@OQ*sn+?YEF7mMPZLG z&dxficE15Nsgu&ZS*2dnsc%WlNt25D#ol(j(68n?N|M z3q-6ALu_0Y4*?c_mBEp53=d^A{}5QZ$o(Ma$e;7-(TTmUrEgZn6OZ^ocLQ#IW9Sws z$}8w2Dz3CJii&B0^~njjhouKCh%G#|ibgmWFZF{JN688!+7?^S$j2LP1 zPmSiFNxBagDH?&zofIZn(W3P|@QOYnmwm`|#)H%jBC!U!2j4!98N|T`gk*|(Ls-h& zzXaE}uJj^OKOzrPi2oL#N&X|{{7;vUi_`y7<29>UIU}24_>gvHO0WW13xR_uN=jj| zPMX9AsOBvJr-@gB-ujzK*c^{AeuFmoR>7(dI8uG+k zxZ5G4xa%QD+M6NYj_N$Pw#L8-=N|?xXKfW8>ZW^_VJdjDPwW#hcFTplyKu_~$BH5h z1`@tAc)YjqdkcohO>C4NT`yY3otrsx6DJlja#IfyDPRv4B9-Q%&5R^T55#Uj^DW>>y5HGdn@r2st1x)*cX7x9cXd((72PCuooXv z;FP*#&Fec~Z8D0~(AeB8B0#pgSb^V3kXk(DuyI}4$icg6%%W|i8%*A4(Vm!c&WxdX z)MvPYS)&y?Z|zb|?nFjQ9m)Ix>twNQpJBPjP#NlkY?Tv2seWFwu;U->YRlb>k~o*0 z&0h#1#VtOG7*uKjuk)1``h4}bo;2xpjqIdQlZ_c`aBMVrfpe!M0giNNHadu3VH&c4 zW0@%1@US)Qb%D4=59U=*qDSvNw3+D?Tk=?L)3q&Q&NM3FE^t+cg>#=f_^XS7*J_E= z)S%m-5#BV`833yRcJ4Na6<(hOE9t-ZrcZmTsm17e;VPiV4brXiXS5%!yWa<)TBt&G z&b0homdYsIQn&DgCe%jGw8vg*r4c(__0KU6T`G;IZq?lh@2XQ;@U*2`#IoG@(aPiC zq0jP&GAa3~xf$(kQI$>0()pDlMl~W25Z7G4D<)l_^o@L`2XX3)vDF$sAQ9&braR^- zbkqSCCT*{>Z^Vcj%vMmQhLcj{06(50Xih&V!bgt(W1Ie-hBseajyN8sE8Snd&!H|8 zeW(`9SHK*mI`4 zIfK1xbEdfnE#^LcOzwcm68Tj2CnzAghz~jwcL~OCMroX0#yhJnLDep27W7vbA1dMG z$v<|@TS-Q65(sCn+4@}*E!kUMptf;B<|8HJ<+t>W32#&-*BPvv&s9}(c7x8xd_6cZ zt&*wAiN8KH4M&rjlX_QdP1pbOX3~(m89L2KXw9&Wq&mgS^(Psn=PVx-gH|>5ih%)b zP+UBfKl8f;+I5g)IX^xX7%^0jE!dAqH(nx{X&mj}Qb2PBufR$WM~`v?EWRf-A60Ux8#M&l6#8XI zibAiYTE-DdS--O}DJstu)eaFaYj0%>=mIhoNeo$rmp4FvLgpPc=@sw^!c&^m%e9={ z5pt*-B$3CEmL`{AHRLn0Ia>ys2i7_`j2}Z7=@lnL76h(Be5UB2YJ}DiNWO}w;^QJ` zu#avUZK!Yyjwx$Ia7wnEtYkeCvc(6-NEB-R2#(-c$Hm_kBPS3`T*h)^stmX*!gfpR zL=d2REU3;42-v493Hi|l%w#VD7`dqyMS#dzZ|DK2mO~D>q6pCz+j2Wf&F#nGE)Pg| zpB%V$be-K6J-5vKmllLJoe{`LCo9s(#n4*9|7GcT0^LT3XMIIz$UUtEH@{jex!O~& zHE9&nMBv~wm9;L8`uGs~B$ry?ZP?jckk%Vrrbp4=QEN|EdM2Bf=6Uuz>haX z8+hBZVX9i40)!!D&}Jg~OOb=CiA+_EY+$f0r7qgYTzZL?3ZHful{PONCH*XV+Mt^b z?*vx_Qk}upgW-D{P!=h)INE@;ye|by0NV`Xsl8!LHI)#He0>&PtC7XH&EVM zo)C8->fhQV9UTN+v43z!JA}u6<~l4`npg}Pi6Hpqx1{y(TR7_V^aXmvgFPZ%-kE4m zcMdT!j%#*BT;5}PoV{Gl^UaO(r7YjnEc9O+-kP4dqCgqMX_Hb+HiUliuTW?~+isQV zsrXV>{;CEpL9iBA>F+cPd3}V2pP7R9P5hH~%b?Yrpr_nlcRZ>u_7wOvZ>s4Ee@<+;$Q@3jQ0KQ+!I7Z`k)c0VUfwc) z!L2;;NtAsbn4RoaU4Gxm>#4<5JaVu7Q z2TdRdMHR~(zRg*5JtLDYSb^DWNh%^lb0xXm{-yf|c`7_Z^i%=|01*2@Q2#S}`k%8D zWdlPeVQaJhTZtO1Fey36kIZ9)SI)4Z+1#Uvw^!gYzt=%2u0jrsLb)xsST8#cl+d&c zr_ei?d@ulaS2)DA7yw=nX?&CAHN%t2gqLe~`yzM^uHW!cb?c>yP6}@|TXm zP+ZmwCD?}c3Lv;072EZw}xWmWds$$2VSe z5Za9i_2=0mvK=+Tc)HGSl0eJ#{Ok?{^{{7)H?Suu$fSP|i8biFFz3W0Ye5gkua{#! zmR^Qw)|HGx40+IF25rQFB~r_hYA#@DuA&MLriKQ}M4c#$+vSsDM0OrMTxz?54U#%Z z*6YT>APYczC9v2P72*`oqsgtndL?`~edw964IOAR%|s15Yc)|%vnfl6+Zf z?R~zxPrGZK({5|?&-^jl{4x3%Z-09qPwx(m%4fP@6mDQa&^%+%o(%{ac1kM_3MnJ! z-99{Lj}@fk*8rsNl@I{-sy<;n(S1rDLdBTL;+^`38WumVW3jXEedYp~adOIpksBSv z&660am601SkGj4V3Jg4PCsE4ye_Xh~2>|%gZT`LC`2Xlcl`^w;FtRfG*F0vTqL%r* z+}Av&LOQGD#ScdrH7z!-i(qs0K`JA5E|A<3`jbGFq7~b5F`@U{` z@{n#p4_VYEh{E3Qo6#N9Zx0#q*516{05g3!NT5HY_HB4%fBYJtw3@(=P9H17D8VvC zH)S+Ds6ta-gO=oBLtmX0TXvsXuFVIMJzpl8_S%8YllDHs74$lj8_}ZWNuIlO?~6Z! zrfN*+aLXo`hiT#vtUZGGaA3y1j>+Toq<8>ax_Og1rr>)?ktbq6W_^5m@6SRLr*#?8 z0D6NNS7GR40H%@6l7tg_ywnBMp6aW3$orgPv4VI`!37E=Lq&hmFBAia z28wkR_0V=j0IV4!?UNs`-y-4`2apHr+&0;iLe}tr*@(gjAg{T|iB@)SHYw`tmb`4! z5{V5?p?Yn!ZYD*>QNj7;13Zq7v5yf*MoywZ{o-9#EAAeqp{_a!#gZAqLiTX$1f$?wO zQU49bzZ|sxj>d7T`9B^7!R)phq%d;0KgCvyVnjocbivBLQ;3Nn;G-DzLJs4smSSt% zvQv1VBFgFZ#(_uz`&IL=+g3D*$x~Cm@On&pW@321-Mv8huv(?l*H{q-M{=vNAf>l- z`EXm2ms{oN<(TCR#zevfR5+qjda|Lf*qyHhPYu)_#9lvL)YfEk3AXNCY#EJQb=~9x z;X-_25kg034f^aMp<~F0U>@p`T`-r<C%hYM7= zs={s&2oe>pA1Hzj)i z$B`&&{+|epRNS(jlSBTn3P)~}fp`2EiLqj&5vFJnoy^lqOM!1T3{TAgrR5~Yf#TogwactgKQqj7) z07A2op_!>^4GS~I?M-gTsb!G*G?a)8^J6BF^DgIX?KNCRtxZe5|cYF^7YlaF949`ej!78kC`yd6`=ie(X%-aOY!S@AoP~6VT&VmGY_j)o4`ZLbj zPeRD{*}>35irF5{$07*DX`L=+o{JJ4l2vHoJzEDm<@ne)o}A^sBwyF}mUoaYho|y^ zZ&imN3=(DagMJCq!#Jb&%uFia`&Phn_!cgyZ zFgwE>tIo|ZZs%C)f~Y_{*hKff>Rh0YK^Pt*>YLaM@XQr(s>G>D()jb3nU4agpzR)q zR2|)rmsvN7rv#@qTYRK*+C$xk40|Gko}kogGr!WG%#+VxQO|V~{vx#g{-H#!AUY`3z0^B@*)^W5qbjipdsb36XVNwJ>eHNm@IR`r;5`*<Q&qZZ2Q|xu$bPbKa7z z-S)`}54&?@C zDkJr7IwO_C{*w3Ul_(lW)z=%jFPICsRWYVr$wST`Nf49snjn%2?}u$OXtL@HIB(gm z0j9B@*s+(UKUg;WeoELLW|(bs%*I(CS>UCo{!_6gJHe2wIeX|^;8aW)nC5dt(A~9K zFCY1cAZ^B&A?}o+Ofd$ENkAt7|5O>e69K`DXaH9}C2w&rT>vk!GIv?-qA@PgzAZ}j zQq7{%I|Pc(j7{w%cj+z#43@>A8OpTja)1eo2ZD~mjS-B-bw$__GjrHr{PS1~m)Wf{ z|E1y$3rr=t-OgDY8vNGGwX}z1jCJ{QlwaO!Z|_X+qV5D^zp;|*p^E}R03 z5KVU_OVRg=72k?@WDF$Ps<3|MpjQx8SiC)c@8ZhuHGVL?HZ!Xw+knxQ?1plM{b36A zQ`(^#y)oV6(5kVfTFS|QCV~aiO7z7n=&WmdK%K@3HUw2I8bkm@3r0fzezG*2l^gs) zd|Qy}O;f~F4*GIJysWg74Pw9q%Jg(NDM4b(jDAkcko`BlmZcXGP%tp7Y8h+{;R=DL z5-~nN>lHZ@_6LS0`v8%qe6xp#@KiR?Rfq*YVt)Bm$jc#yq)j{~wHOKal~PjPDIGlK z3_ypEjQnhLp2;%_rmtAd<85mdENHBzs~1UjGbV=t$enSpUBC`GXJUFvf~R@|oT&d* zmmFT2=9qZ6nx7pHTb^46kRh{Fo-bfQ` znvG$}0xPonRr+)MOyE_Z`+*F@Kddp6zc>6G8kN0kvNB{iVXWkGn`PL%C(d|;O$g& ze{K4H10lVny$khXXRGtRx}lH00l=I~2`N{e+A_w`Ovxrn1jvEG2E8I$wzg)ggur2& zA_rf@xwF}>AbwXOqqd?p&UAn?^MiQeL(A%ztZyb*b) zz{b^%hm|z!zG0_xe!z#^zPk@EoAu15h&j*x8s8amnmC$8n|mkW{?4M+9ipDB3x`>Qb^*@t&D|vh z9Q36fR36(ekSN4}O`f(fIyi^BBjsX;R(MJPJ!g;vS}vviE@VY0pqYvILRByW{kAss zlYzPlB_}52O+hbQvDgQFnpl29ETQ=|j=g%gQx_NtiM@O6NIRw{FQKAReT=fe!q&O5 zozRzrA~l54NV4!ea)afv5JIWQ@GSE{hC++9aJ+py^U?@HGbSK-x9s8N;H3+=+^{|#!7N1`lld3HyRou1x_!#gH@uH-OQ{csz+}FU9o~!Q|Cyf<#XY5=9 zId~!@n}dAjqBXFh7!l4)%xpPGY_+Ra#^0>Z*b#LvWUyA9+(-i{%?NFaqC{t#B+=hqyF=*5=BYxlWgcTMqwx~G z+_$bmttQkU+>h!qw3tJjGIWOy@ARka8$Bl^{mUb(8p#7ixYdk)lMoB>)sp(*`&brU z28fYy)`V9`SR!9{Y0}#UJ7lKl67M4IHs@#}ifMS)JVhHOgfp zhn;zhh#0-XFOZ7E zRtAqnjDA}gHJv|GxRBYC5(T*3!bS!5>7ed6IpncWxWvKBif=P&*#1sJW;_uEuNU%2 zDBMmn)igzM4NX468a%K-T#2E(;krD49?7#EAzYl2fpG0#h*`7$-X$=iV&c=mz*f-z zI2Q}^f;r$keILUn4b#d4w$Bk#U3@}dJq1&`tWCKR^GUqlZS2!w^mF8b1OHQcWT`mN zVTXsBEI8mk9xYR$;jY601#M&y6(WBP(xp0}Ra&5R8N!aA{R1y#&0c`~lPkdAQ)~uq z8!}2;0_!En$<7FBm^Lb%-O2vGSZZ-~@2_Z)LvoOw*)NIE2kD=rCf>hiNY*AM7XL~r zl(Vz8F|u=T{VTojKk0g=qQ=*KOXQCtv?i^^CghT^#=?U|D2LAQ?@~S^ij~A9p4*nq zQe$x!w3kz;582O5QVpcM=-Kb`L-lJCG~mR>^(KcIFH_F6_J>E+)>{AzH6#XzceW$s zBjox7K@}0g)GuRo0Vo)V5{zRdVkHu)i8Vv?x$XkXsDe#ic@GWFW$wnRIF1_5f%%Pt zGB$1EEj0a%1Cl`=C!D&igYYYj(d>eCR;nF4j*geurfuR$4jWeH#*+5XI(V2wyUR8h ztf!Xkxle$dYeelcWnF^34CAkmskr3E-AqB>3z9U5J>i|qicS63{sztT?T8U z3`pOtR6w41K>)y6l^nOk-LPMKr1E-P`E@nLeL>w z`1DnMTI*ma5M8ppLZA%GwbZE)HQS6@TV1|Z&3QPqEaRP>NtOPto+_eUHN||7q?1+!ypaq=$%$iJJBM-s;b8I!u+OjWjP_@ea_PK$8 z^-l0vbj%QBnk^Kzk8I{%5Nw)ArPE9Kiw@iqlHM#1B0zjo6qsWmc9_{L6#$bd1;j6N zdhB?7`!VM0b|+y2YPn~CPIVEHrw|{Z;OYRJSmc;Vz~XDj0|MUQ82+hyj3#jx$y_qU zn;m>Tqb^sp+5paap{l$gL$LcmOfF@8f>}yMs}IvB)*n)v25UN<^cS^v|3_+1_P4-Q zF>}+iGyD&AdsG65AGv}RNp#qBw`&lFhZxs_TNK3Bw~wQ@oXQ8Mg0qJHOc(Z!71e@zRaGB-Q!!Tp4xO>kF0+?2 zEG>@Us!T4+(Jv^1?kgU}a4eF0XGyr?-t(LKNu&gNPfU4GZbY<4EOA_n^inurmV>}1 zs#b5j21=8Q=nd5a{_bJz*6M2I4C+oHB_y4p2hO0c1!F~`CJ}ryMY0w~(eD{K83(Od zP^P+cM&!>t2KL4hB==h-vv?#ON#_RgV7+D5BztoGK)pSkd}xsQJCMdHEX$Kv-$b3K zc1m%QgKI&Bb~5^$n*B_|LgligGgZ+bZGQquStcPo*Ss}wF z$Dhg+=mN~8$(Kwj{I!06uW$cv*6zP6-19|4KO4ImAAD)m(LmQO zjRMCtD1VOq;Y--$f5f<$P>12Si5*V09<95x-~Il02G+%af~A(?OzCTg#K5X&Jw&(D zP#ARxCQz(oL9gg6AwdtzQrc}nVioonN(Ueyp}TdR*{)r9;x#QyX4Ly8xFbe^a0S9G z4opCmg%@ZwCx3}@Wyf|R{>zDLjwiX9+v)=B;#Z{fYTvt($f?o*nml$GYQO$3CcsTe ztyvUGM`xIW?@Q^cx*`sWe|i(exQ_Zd*bD$k_zg-^3{PPM`q0F4NuHKkBMX*#uX3d#A6BD zo#32IR{eu=dePYL={ykW0}zg{!_hCon@<+@>Qcd=J;HH-y5@%1m~>C$7w~e*84@BK z)=f$2E&f=(BfdZ1s$u#Z=70W=%lG%f;{U((1oRC4o2-+ltfBZNEPgaqT0-~|;=2Hh z7n+*YipO$=2(+r6%Ng5ja|EFHk=VvH_;?Rt=y*7ZfOuZdf_W$GtrX1hI#`TKO&L99 zSa;joHNC$d4a%%hk})x)JQ5?o>1G=JPtKQWEXwS4Mxh;B7MPG~Vq z32L8+5o4Xi-ZB6`s1Tfjr$Q&)qRqy&d24i%%S*iUD>N_UnPd&n(Sn9hhrTT<>ZU=D z8ke?;PiGT9l1SULS)F9&VwcaB`E8JPiJ8>ef5DdIIR=NZJL;EQp4kdnZ8NX@qa(&q z&%MLHW0w*7HyyQ~D=57M>y?n=klNKuPb=kDqFzHFG^p7UAHQ)VxhCu%AiqeX;+EL=2~tQ#4QdrMSh+lT%ThWZ20AYrGO*+(?XBjT-~ zee^Vk&*$rL*zta>^QZ3`_AR0J>ui(%$Fz3l|HZTE|E|4jeJP(`PEa_q1c=baf(2j{ z1)hYS_Rl18MFWAN(S%gjyy^kSHn&N6S)FhbN)uS_&)5eA9f}d_e^nIb-w+2jwm~KW1P>vph$J z*I}aznysS?I;r@sb!!eTw+zItI-c@?5X6HauOwwf(xDSi`^MCx31)A={0Np3vzBpT z-UwZK-)KE496W>Dd2q!JWcf&use>$n-J@*U86yJ7071`6Mcejn>5-AGX)v{3+5s{N zhBL)pH|-HR9{h9B>5hK0AzHA_ar9pOm)fbgC-!*7mm%5b5z?8Kc zxeG1HP}crc3`+C~9B*Xy-CCvJMkcjIWwkcAY9yDc^sx*x4Z8V8dJyBNtIN8kA9(T5 zFYL1i2~QQ?<_*Lbn*MlIb&={BOgwRwMk*GKK*U*yepRY2NK^S2r zWP%(kJ*V20!HDlX6m5&logl(EW>BZIxfBYc)3MFsSt6?yc!K3@yn>%%SwY;R#0$n9 z10Z$Dq-qOicI$%~kA|nDMV*^c?un<_Io`s%WVedtH!w%c^@HWbm>AaqU@=mzn39Lzl=SshSKmM{Kk2>BT z-rnH8(X2D+Z3l%yFV-6>OIvIk!>X+-{FwZ{@xA|hJOK_&Kt&SuTo_9(_|wf-fv44%ovlu{b^}2#^X+J#f<+HO`wM$wp7r1cX;#E&NQ06V)OZ zbO181KGRA#xf-2mG(MrBJQdTBi-whsmGH{ykiKP}Gu}g2&ws&q6}@Ff7AwkS?eG19 zV)4JA`0xcqz%{%?50 zA4QM<4T#GBdcPcON=RI^LjnPyP**>gdT)|O>^J8Is)+;g+w5OuSs7) zU~Hg#z$iEq#*n>KsA(IJ{6vT;YlsEBJ%5KT`0{WYiVC`jM4Bt5hO!{9{It>v=Tan5 zYuUK_D_Emli#l(biRo4=^SOc5879i1gJ3fn`fg}Z;$AznrR!Y`laNGPZ*y5OSjX)T z9`bpy3d5g2T~#WN0p0yA^JqZL!gZEOHtJe?ser>lUp&+rsb%U0l#!Ej#%2wLU zEbhkK>+QbSLl7cK@eiJ6Bd;MC4Q(fdMWOTiiz5@({+`b{KYT0t3O1EIvtbMq`K>@g zsh}_R02y>0rB-R$kpp$XX?-}CCnCV+7BDK_608bOM?$SD-xo(e-dBN7r-x#W2&oFE zFDQVJj;NhWtOp-W+#v$jKVZ3F9Kva4lvuZkonaHHgl$2tUujryqJ6@RD3Fs&no1m6 zX0~3pt0>Xb$faIUE&o%u3Rj9E9@=1XCG5e0$&X-70IE?ksW>;z&Fsg;3+8mgcB*CK zQD6G%`VSaw(zGhj^ZPkyPL`mqw%`~x7>!?p@dygeF6Ac3wZF$In`Vzw&R7$ak)h{h zRReHk6S^2|`A41kJ$_$@mP@uI&j1qOz1ZABb{U>x{ni10nGt3EcJpD^B5PZn9_R(l zPOTRmADVt{>-pI77_YO_EwYw%cGW_Ajle^AJHz7Vo;`Ds7jw4St%xVHaDydJC-LsH z?+KnXofb2Nu-4Aq2H05#pXUmg=M|9rQ z*KV=>M-uV(m$&|lW&h<~WvZCzYN|MXOqmw2Ve*YPVN)SEVXxU{%!<`fui2iv5F~X7 zH4$^wS`Y-sa7ShxFyvzx85?p85qu}Gpvfh+(1J+!O<|?R!~mv%&w*E0UsXs`0HjIy z6+m(>+2?%ejyV}2f|1VmwC=vux}|o>ag_D6JdfuI+@p?BHi*id+rQ-a90dD`b$IQ~ z`BntGHMjHW`0Rx4yvN1)Rt3AI*mb4x%#ZHa0zU+IQxJ$3SPPCu{hK{v@L3$3@7H^A z!kr1hZ_N`rhi4=7?!IcrM=Yprm^}%Q<$x`U%d3au`8JOs!~ol`dRl;uAH=13&=8m> z1f`1?P)Q2`1CaT`0-BPRVtu@sM~Z85l800^knx<7r~!t#gtU2@rOk%6=xYyqsA~G+ zg6M2+;p2`ieQ`tdPCI_Lyu)#Ydgl+Q0c8?`p~yUe@moANs zE=r`6ob{nA`VSZI5T7N^9XXE&)mS8)IV>BFKKQlCkYU&(ZQMvLO1GK$ZX^<4NU^6z zr0+cO+!%7(cWk>?yHje^oZINrWvESIImTHPt+i6IB%x5B@a|+dtY+L;XcWie-ZnKe zLPIa{!$R~L1)V5q7;|S~TdkQmC7Q(aa2c$)P*Q|A4J!~?rq&v!1Kg|P+|^npr`rT) zR-E0OjuNwE@S5Q`P z2w4_W6^4I=+Ik(kNWj1=ne43uP?bCtkYcMllBXZCL6*srkubhgfBkLVMF`e-ky2#Z za|lxfni3Z-pY((l#BL?^QBkdn#wT+)?z%{PJr^)ftp4zoI2Y07;!4^?60dvlNeKRO zDrO!HRNJ0-v$Mq?8P^>CS&pSC@$9<=du@+w{wsU7KXp8%3a20eWzpdh=9Qjr1KNjOt4Zszn3~NDo98XO$h0{RNPwO;PQ>iziRW7DeaU@_$4x>9@b~(EKZlqiqI=ePu{ZI;i zb9lDz=p7Qhj)`14yOq7R!>aD-WW8L1^QK6*XKNY z|L0b_We19PFI#or=&uQ)R`AUSR^Cui3l3t>h~ZZEs3;F>{k=q&U-h?-hwTVh z)ju{_?C&lqOn+E(6ahM$@Y5OWHM%5{1Y2_CwKXf%HPjrRR6eZTay!Zo`VR^_T9Q1@ zwQ1jcw{>hb`W|)ri!!W5@UkS{37s3ddQ(ZAX*(Y?zj@3{GRu10@)qz@Y=>xt!Rb5& zaFf=Vo?WG(YMX*XH#Gl-(^OIlR8nv)oOP4G*MLv7i?gv+l&M4{Pab| zW}(+()sm?cnqMIZV`nEW*=W+VJ4g9*3Pc)V;5JcyDKQAzsgv$CaQ(y?u88ZN-@(EA z^gL1Nz8)_(lz!2~{?2WtWGJ$KYG}5Tba%ghCJF8d zPyK*8ifMn3Eh6ay_4FBWG6Xz*qWlYe?#$G}xds&!EAiASnWy}NNb=^=>am#_t7$*P z0l?rOS2fYy)Rv_wk%@Ov+DEoQuCBEP&5n`I#Oy8!=<>D5AFFIAeD$yMiZfu4Y2jS* zpWUSe&etg?P~ij{=5F_ag;59T`Rc(Zq6TeVDLNqp-8!<~(*y-QWD;q?&YEQI>DWII`;`#jM6fmk zlOaSkN$F}gFt7t~rS<>DD#I!-mSdw21>vBMkkLaZen6^W*W!kMr>_v#Wc8IZU^&Wt zCE;MU;S3!=tKMc_O%o*2%R=IbF2tj6`wcTJoicp`Oilcp7nOrcq3J7MA%bZ+q6;=O z6BvKoPXWEnY?Xh6-GS~suE@o0dBbWDK7~85W)?oRaOsm;dZ27v)C3l~8R)#7S;E@X zJ>L9Izr;VMzPd>nugaRQzx=HenV@4LB+@OywYKrEPnRmnjg`*8Byw&TbxwCx!C4Yp za{|&mp4EdZ^JM2X58TGS zF?{j?K`sba+=;~AbG@RN*v~&_HJ9$l6Q}{2H_;-9sACjZ@O?xq4lbJ`#-T` z%xB2VA+s|2yYj+SEj!08bcdu<$xJBR!=i0}3|{(u7ItB@x5B2}iZ%jG9^K?Y088Lv zV*qYP{>ftcqcX$L$kLil#7@uB$l2P?TdV-Y0?@FM{4>#IW!Lb*`n$$g)-NiFS<_~2>?Ml_8}D-y=-!JylFUL(71jzSeR z@%V-}W*d)+A>k-R=3bZ1v*q=6A@2S0`UuoRyl51_fGWU6J1&O+MM!Ia4S|7_k`Ozf z6f%JVp<)z3f0$;@uj#yGhQZWAuu~MEfoR19oPpEH%s4nxco3jRl5A-e;yJ#lK}R~F zOk;f)dgqt_OGUoMVIFx1xASpioqk%M44O+RF}Xp5cxUX8)<9FHdn}BewMG+x9W+o` z(>N9P=u>7v3HZGDA}dYnG_Fy12|Kjsr-VUFU6P&+(-G?~32IBKtTDC*+ugnTl&TRI zRgz=%FC=EN4F?eU0%V~X3cVk_I58n%E>&Dej+zk8DC_+l0U#h|1;o^ps(p2SZ!SGE z8>;rX9i225AXF}5uP}@9ppNzW7oiz`qABq?6sm)m{ny?hqU6IYi_K2LNkS*qWuZmM z*!=SZCrT zJ@dM89F2gIgSq(L8Md3N9Se5{6D~1e(CX(zJs^6$0x<0-h6oge)hjpPEL{|i(W+Bv=fYHnUSQqt&=lQF?J=sB-v*CE z3kQV=QWe=i^lOU};jWTj*tgC(OMhCR^?3cM!!<9v#SVTc3xHn(?0;{+68_!Z_>Y>f z#IN3Htgo7|BuOAWvq^!{Mlp@=Scn4ZwaSu}0x_&C6cUsP>U6=A1S@gpyT*b&Z|}Eo z8Kv1B6YQHsQw!S-2E(>PaGOKk`_EbRl646=B&i(kSx22bSM4Uw-k(Q9G~bAx$wSPz zQ3fEmH=_1ZAm-u_#zAVi71t)mw7%K*o#|s8`nLp__=E4(4Re!mXFc^md0poL_a(bd z_-$3VFI9+*1{yK=Xu`jbxT6ZjsBqWpgMsjoyQ$1)Z^YsIBm>rYAvc&TN|8;g8^ z)dT`EsE^I5=_RcM_28}$hABqgtEZ(OK!~_46qwm@$?Fy(k}2x=3;44*&n=aHZL?Ua zHBB4Hw0?mhtBu2n9YvAe{HLH`1(jt;jmTumpw#eeB<8?o|ckT?nbt z5?y6sg>!`z1^87$`9Vx=(tg6is8A98Hf3r?CafMRO6@^&!h$#Ll zBP%N#U`dO>C9TaqVq1@2Hm9_?D46|4l#p%`uH}eS91|4Ds3}^q*Q}fJH?*7i`E`>8 z0nC(nwSKWo1|VI>3;A2aU=Fxi;ZxGVYY%Z+w3b+{9Xgs>L!RmE%62Tvqo@^iirF*4 zkZzx678L0CTP~#*L&8wnU`9k)InYUJcc)3>bLM+(2Jn+oNqa)h`z`UzX3Rx0%{&sr z)%>ia2D|A3C*Ux_SIcVHkH$%bAALKZCM`F)aL8;*mqNc{xf}|QQr(XqDXIu|LxgmD3D2K7i z*1L9SD24_`CybF?tLUUv%N=V&gY=!_)Es67TTN6KYu3q1vOaDM>y5XOf!+vwUmMPiz>q&TisA1^?hY$ zqoz$iIbgS;)WjX_T@up<&KAeL6A1&tPSU}rM615WK+2CbhcA_gC2XRd(0VBa5Y5z+ zg*Ff`ez_5^qE+r%jh-)E#!mPiH>MTv{=|4jB=89If5v3+5M+8wD)0zqu6hAwxEO^( za0WFI*NuP1bP=eY?-&H9a}{uJbbl9kYw%abF59hvw?}%vJ3|)}&FeSBT)2!cded?d zf|6w4?+Zaqv{^20#j~u_2R|!#0R_EA%4-pJeltv|3__doO;L%kZsRzLrmHHJkW?4!eJ=iy>-p z|9)vGCF$mfL1qb`VYoJ8IQRFT4ZIdKq0r%9P8Trb|I^X-pA}h3mR}8s$X-n_0Yw^A zk~Dtcgn>m67mH{fR03eW$ja|o7h;UO*1^W{um+G9uLtm}6DrHw&7(+I`22(k?~ zY2OboxtXFL*`4I3D^l4*mna<0vVcKvkFjd`8C-=1nzEHwZSGf@+yOCf(+vb~;|&II zV~)8(qa!d;E$P~f2m%>(ga}F}F9wF*sl0pujwJ*!an)=@b7{tSE_f8UhpaT{ZQ6;8 zq>Dq0v~=hpLB9-!dz!x%mBzxwK#0l5Lv;JAk;bB8L5)Pm%_d;Ew%m{BS>6$0cQN?&`DQx=m zafflRfSp63NGDWMq~#Y9S;TkG25EEpir&&=0-QKkd060#bSW_%#-yy3Ci8Ju*cT3W z1AFC*{XyZ)qhi3H(j-Qx8(@o?sdRayBwDjq0}Y z_~K3RZyYVS204kvJ|c*{{33N~u)6z5j2liu%{mZ8t&YUEl`~8SKat*Re?>|iVx8MK zvBp^FqWJ@mq4@KIHZdXl7c;^@Gu<@Qw*wUW@-)-iy^v;&GI5-qlQ6FJ)JHsWyrmy= zh=64rr61!5vJXr^P3^EBhC@fO8!)i1nw_yg$NrAow>%%l!CbszPT{)-{ph3q7-IbB zRsJ1*_6!I4xhJ_ksM50Z>oxMnSv|YxtafqI+erFecWClSCgCA^o~btd z+`b~vVE-`!4gLR0QvNls^W#JXOBwkS24;d7I=3JpX%+Q&C$~vStw1MDn3ae#H+Q(qx)UAciW~*HB%6qJ6I!ltXS7mcJ3JHKwA8rBG z$xbCcdrh&r-qAFU(=f1Ll+KWwkgB<7uXo@_OW`$9FJ8u^dd|x?M?xhdBbwMYgOFAi zwFsK5g_3vIW>c6YNS6KiOHDSnwytG!mtw=IE zi;iGgt(W?;6!NzkLFlz*MA*Y^#OPSEUK;^DPbaHIbHs!MfFL%bHd5qhY-nPjA50Vw`rloRTe`w%iS&c3e%Tem_du5Av>xU6hWp zU6u|nstbiD6}a>yCYpamrNQ~BHxxzt93@3GD|h&t7YI|Z&r`bD$PKo$i@8=@5bU&( z+ny~|o3!XDG78*gg+1A34!o~tIZjwC5lc=KQ8Ss$06+g3tTs6O9I#qdpru>!hBS3ITkWSr7$IB(mDaT1m=ZtOgFrWWbhGBJr7=^@&^-JG#~ zhuGM&0RCNJM77da2cDrv`7W1->`5hz%plyeEsK6tP{1ULRl;$3C9Cu63-b6^h*yKz zoq?JaL$$Z(YR=4Zo-!t=fP!R`U?Ik0MPXksuY@sG+of)ETYh+44TLEPGXd5~K=UvEuGmjjvTpBl2919@m7J9Cv$T zm`caG(0V;}BO*&F>oH+{>@8mHGjcO^7WOYXTeONstrL-kR_qKU|C?P?c}>$fQp+b( zlsJm%)CTe}PP;XYQ?oRP)t@*!)3Qg8ZJsm)ZsY#p0IqEKrx-DC-JKSlitUkQHouM^ zMQ@A~7{ir@?okcuJu}M?F%|NR#*c~vh!R)dJ|}c6JKOfN+iVZI1^Q?$dAi8}zv>Jf zuVl+JPtirOI+644cVp#9jA1Xz%w+c>7vDnLWTtULy99S)8hpxZq;awOB(J3d(Bv{j zrP<+JA;R$AbHC#@4#AH>pVW~3^#qA{GMGG=3bl79&HlE4PG^LL=MF4onX?Y7v%dT952DhV! zR+feMoelC^WPrEucyzt6zRMHdir*Ke_0rh zNGUab9+Sc=o9{N1oN~alVIeZ}F1MfZb}sy-&OM4KG`O9kIDBXfbYnKye8!u z4Lce*3F#wlj|w31dI@_A9MfZB%g)sI4nl>!3=r*gLf$}3tI1-#y^p>vjfN@0l8dFE zUb(@de$7ld!d*utZGk9UMwxAVwNc>GIm#8Le3D+HA~h*~>qW2pR4uAA-%^Y1lC*!e z?Z#@=Qg%&Qp}NvIT)8;W+WGvqvzyM*n$~#Lk)z?*=Ngqm<>FaBWZu5RdKrc4tQ=&O zRch6qmv`h?Rj@pUW}h)As5>;%Ckr}exMdp$<<=al^xMP^&7kh;LLXVJdnV1NJan&~9m4)hdy zj72d!uW)}|=CpSrzR_^%RAu%EOD+9KLWMaNUJwOj>;|B0;C}dhv{6OKLiCk=--T|V z@iY>sU#@zj1#N6EB$40=6Uch7^0S_QeiW2s>n8&vGs}r&mSodp$&ol;KH2(2QtkKd ztZ?vXc}}x6za7TLTL%*dzPv2ocaca053wbs<jcX!}3`U%fr+)`%pV z8talV^d2${%jgBt==x_4p=u1!YV;8`N%7U8IHdGNTfp$u+CQfrTtjK_)l|v8osHSh zNOXO`{c)cav^@b{>Whm(|05T}{r8?!G_`jAuYkk9l+?c%nd6sOv?hYg0|^W@2&{^z zZHYL~{S8SDmw2DwG?0E!{m{T$VHacG%;Xj5HlMSTDs=IS zYPCPD^E_?ZUsX*kd4K%I>Ve!GbIIH0%o=kk+U8h9S?__uz+&t|`@l0aWn@)UOs-8# z3)EX}R;(fFv4Z~pDmxdbrj9fKM_pkpc0o%-5v_8p$JZVOE4onJ|MKw8y}5VN z{W%`SbC_@b{P&-^f9CN|n#53@74qqtMuWc>2!t2cUYY$UeXwl4#S))YnH?MYCHMYl zT~zAZm2)9;^ybODt{T3}3FrN=TQ>c>v7p8NK|W^+qj&;g%GN^vY@58#E6SHN3p}m! zClpI|NXxPtc<=J6eQea)_?u;`atW&U#NU7{Z_g+wf1&ASyAq} zb9mc#>Q`U9m1tpg?&BXj{!sgd)y%n^gWQsuPS`-<5K73 zC-*1%xh?zhn*#ZU!oDLWbERT+ANN7uz=lA_9LLd*t<;-J+S|jnSe!O#UU0y-D)QZM z|FaiAnwy=rysPi1Y2Dk7=7GYi@n5ZOTV?j4YQe~`eOZ>$BSK%1oc*Ud7k;bLUndT_ zmAbq)5>VtAwnum5*~;~|hddsrj8*6Kwzs}>pnh$%YH-nzXye2u8)W0PADC?ZCC#yS zbNFGSr*0|h_Vq}F+e>cVsCrz!CvQOM|FpoOEW0fCRM7Akt##k+TQY6YI0&& z>p@S4OYv#EGF)eoI2RZkE_NoflqklRL~; zDP|Y&zdW?(p2FQrCW+9kwM{dZBi z9cT9MP8;ury4-O8_pdh%@|XUaa*EeHlDY4qqmkc)bwY8@9Ii#coMZCvMat{rg&pTF zT09S3@TKsmPg<34e^1zHkzK6op%>o%rKy#X-=+#zD{Y!eHywGYS3MS5)bgS<)izdS z^L?tk(^dD@M=gQ#%;Ig_9~$%e=B0nC^5i#i|67*bXcyR|XFROK-Lc|%|Mu~&^F#;l z@3`guH|XFll)YwWigv-Z3#1rA(Zk6{U?mheTYCsZLT4v$AD)Nvh)1j1-OY;E{-&Fi z#kJP9YA>6P_wEkH^0s=c6?(KQD{8!AS}kY2QTQbGY3!`YZ+DN(^X3z`HV}C~#BQ@@ z8**U6287-uq*t951J17kqWD??v|2SyQwRP z&#-6)!y!0x;9L&_2NJR1>;UoFv=EGqz?fWBo2p{S`91s)ri))*+A9Dzy9Ix5Ia6cu z_YUS}r_~pP$dz&Ei-ZnNx$b9n2*6J87_BJaXW$A9pJxU$O=YE7KFbTc%&>m+5v7&md4`D zvW&0ebrSHW0Z-MvP+u$FUAhZv^ZqN%FRB3E0B{>paVV97Z)?%rOBNo1rC0ZacW(uH zuZFAC7-8u|<}{p5xS0(~B9`d^FmdMwDSk_FVB)A6j;pdi++q*h0pLX;@=)C64WsAj3Ys;04m2 zYS8&B(Ak_+7)m?gzwA0Y%Oa)3`XY08$vNTm(gm~~)Ua^`3@12hv`i6!vqR98>nW#z zd<2}C>J{^#ZvBolaSfv#7QzkbcrLpg77j-&%LHwsKwDx911To&NfbG(7hF2fru?bjb$kIs?3xV4KT&gn^+vB*~upRDYZN&aOpzhOnWPAt| z*iE}FMjDN?LT6<6coA?_8e9t}9M?N|?{ppnX6Ida=EQnp;CZa!yrvLtuR2cT z6Q8qEskc7Rk!adqD$+Zh4LOsf)0X*xp$TcJNWBbg$m!e)bS=@eqSVpmC+Hyz;~0{} zks+@w9gpUVB#r`-;+drl&vaUv&PP)MQlqI`hqdwPIVkCDG?~r{QgJBxlV7;?Ox>LL}# zv_my>PS7oZ9+@T%Mw6m0)z1GdPKcg_rMBQ#uDu1OgV^-XfSw+t+NiHmdkdQ9Yw3J+ ze=T)jF*vD}&+P2zwnXZyTXgpS*rrR@6x|X8-Px# From d35e1bbd889ed09c5910b61ba52537ebf9eac1a8 Mon Sep 17 00:00:00 2001 From: Chuck Rasbold Date: Tue, 29 Jul 2008 14:48:25 -0700 Subject: [PATCH 18/95] 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/95] 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/95] 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/95] 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 897278fce0f080956134660ede78742e7da1c9fa Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Fri, 1 Aug 2008 10:06:45 -0700 Subject: [PATCH 22/95] 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type") Fixed few addP node type and narrow oop type problems. Reviewed-by: rasbold, never --- hotspot/src/share/vm/adlc/output_h.cpp | 13 ++++++++++ hotspot/src/share/vm/opto/addnode.cpp | 2 ++ hotspot/src/share/vm/opto/callGenerator.cpp | 6 +++++ hotspot/src/share/vm/opto/compile.cpp | 1 + hotspot/src/share/vm/opto/escape.cpp | 28 ++++++++++++++++++--- hotspot/src/share/vm/opto/escape.hpp | 2 +- hotspot/src/share/vm/opto/loopnode.cpp | 2 ++ hotspot/src/share/vm/opto/loopopts.cpp | 14 +++++++---- hotspot/src/share/vm/opto/memnode.cpp | 6 ++++- hotspot/src/share/vm/opto/subnode.cpp | 12 +++++++-- hotspot/src/share/vm/opto/type.cpp | 23 +++++++++-------- 11 files changed, 87 insertions(+), 22 deletions(-) diff --git a/hotspot/src/share/vm/adlc/output_h.cpp b/hotspot/src/share/vm/adlc/output_h.cpp index 78f16078381..04cddcd28c8 100644 --- a/hotspot/src/share/vm/adlc/output_h.cpp +++ b/hotspot/src/share/vm/adlc/output_h.cpp @@ -1848,6 +1848,19 @@ void ArchDesc::declareClasses(FILE *fp) { fprintf(fp," const Type *bottom_type() const { const Type *t = in(oper_input_base()+%d)->bottom_type(); return (req() <= oper_input_base()+%d) ? t : t->meet(in(oper_input_base()+%d)->bottom_type()); } // CMoveP\n", offset, offset+1, offset+1); } + else if( instr->_matrule && instr->_matrule->_rChild && !strcmp(instr->_matrule->_rChild->_opType,"CMoveN") ) { + int offset = 1; + // Special special hack to see if the Cmp? has been incorporated in the conditional move + MatchNode *rl = instr->_matrule->_rChild->_lChild; + if( rl && !strcmp(rl->_opType, "Binary") ) { + MatchNode *rlr = rl->_rChild; + if (rlr && strncmp(rlr->_opType, "Cmp", 3) == 0) + offset = 2; + } + // Special hack for ideal CMoveN; ideal type depends on inputs + fprintf(fp," const Type *bottom_type() const { const Type *t = in(oper_input_base()+%d)->bottom_type(); return (req() <= oper_input_base()+%d) ? t : t->meet(in(oper_input_base()+%d)->bottom_type()); } // CMoveN\n", + offset, offset+1, offset+1); + } else if( instr->needs_base_oop_edge(_globalNames) ) { // Special hack for ideal AddP. Bottom type is an oop IFF it has a // legal base-pointer input. Otherwise it is NOT an oop. diff --git a/hotspot/src/share/vm/opto/addnode.cpp b/hotspot/src/share/vm/opto/addnode.cpp index e5cc05b6b1f..f581f92493f 100644 --- a/hotspot/src/share/vm/opto/addnode.cpp +++ b/hotspot/src/share/vm/opto/addnode.cpp @@ -695,6 +695,8 @@ const Type *AddPNode::mach_bottom_type( const MachNode* n) { guarantee(tptr == NULL, "must be only one pointer operand"); tptr = et->isa_oopptr(); guarantee(tptr != NULL, "non-int operand must be pointer"); + if (tptr->higher_equal(tp->add_offset(tptr->offset()))) + tp = tptr; // Set more precise type for bailout continue; } if ( eti->_hi != eti->_lo ) goto bottom_out; diff --git a/hotspot/src/share/vm/opto/callGenerator.cpp b/hotspot/src/share/vm/opto/callGenerator.cpp index 3131cf6b333..72b04c5d024 100644 --- a/hotspot/src/share/vm/opto/callGenerator.cpp +++ b/hotspot/src/share/vm/opto/callGenerator.cpp @@ -464,6 +464,12 @@ JVMState* PredictedCallGenerator::generate(JVMState* jvms) { } } + if (kit.stopped()) { + // Instance exactly does not matches the desired type. + kit.set_jvms(slow_jvms); + return kit.transfer_exceptions_into_jvms(); + } + // fall through if the instance exactly matches the desired type kit.replace_in_map(receiver, exact_receiver); diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp index ec28d079955..18114bafc80 100644 --- a/hotspot/src/share/vm/opto/compile.cpp +++ b/hotspot/src/share/vm/opto/compile.cpp @@ -2111,6 +2111,7 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) { n->subsume_by( cmpN ); } } + break; #endif case Op_ModI: diff --git a/hotspot/src/share/vm/opto/escape.cpp b/hotspot/src/share/vm/opto/escape.cpp index fece33098fb..ef146637806 100644 --- a/hotspot/src/share/vm/opto/escape.cpp +++ b/hotspot/src/share/vm/opto/escape.cpp @@ -492,13 +492,13 @@ static Node* find_second_addp(Node* addp, Node* n) { // Adjust the type and inputs of an AddP which computes the // address of a field of an instance // -void ConnectionGraph::split_AddP(Node *addp, Node *base, PhaseGVN *igvn) { +bool ConnectionGraph::split_AddP(Node *addp, Node *base, PhaseGVN *igvn) { const TypeOopPtr *base_t = igvn->type(base)->isa_oopptr(); assert(base_t != NULL && base_t->is_known_instance(), "expecting instance oopptr"); const TypeOopPtr *t = igvn->type(addp)->isa_oopptr(); if (t == NULL) { // We are computing a raw address for a store captured by an Initialize - // compute an appropriate address type. + // compute an appropriate address type (cases #3 and #5). assert(igvn->type(addp) == TypeRawPtr::NOTNULL, "must be raw pointer"); assert(addp->in(AddPNode::Address)->is_Proj(), "base of raw address must be result projection from allocation"); int offs = (int)igvn->find_intptr_t_con(addp->in(AddPNode::Offset), Type::OffsetBot); @@ -508,6 +508,25 @@ void ConnectionGraph::split_AddP(Node *addp, Node *base, PhaseGVN *igvn) { int inst_id = base_t->instance_id(); assert(!t->is_known_instance() || t->instance_id() == inst_id, "old type must be non-instance or match new type"); + + // The type 't' could be subclass of 'base_t'. + // As result t->offset() could be large then base_t's size and it will + // cause the failure in add_offset() with narrow oops since TypeOopPtr() + // constructor verifies correctness of the offset. + // + // It could happend on subclass's branch (from the type profiling + // inlining) which was not eliminated during parsing since the exactness + // of the allocation type was not propagated to the subclass type check. + // + // Do nothing for such AddP node and don't process its users since + // this code branch will go away. + // + if (!t->is_known_instance() && + !t->klass()->equals(base_t->klass()) && + t->klass()->is_subtype_of(base_t->klass())) { + return false; // bail out + } + const TypeOopPtr *tinst = base_t->add_offset(t->offset())->is_oopptr(); // Do NOT remove the next call: ensure an new alias index is allocated // for the instance type @@ -542,6 +561,7 @@ void ConnectionGraph::split_AddP(Node *addp, Node *base, PhaseGVN *igvn) { } // Put on IGVN worklist since at least addp's type was changed above. record_for_optimizer(addp); + return true; } // @@ -969,7 +989,7 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) if (elem == _phantom_object) continue; // Assume the value was set outside this method. Node *base = get_map(elem); // CheckCastPP node - split_AddP(n, base, igvn); + if (!split_AddP(n, base, igvn)) continue; // wrong type tinst = igvn->type(base)->isa_oopptr(); } else if (n->is_Phi() || n->is_CheckCastPP() || @@ -1012,6 +1032,8 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) tn->set_type(tn_type); igvn->hash_insert(tn); record_for_optimizer(n); + } else { + continue; // wrong type } } } else { diff --git a/hotspot/src/share/vm/opto/escape.hpp b/hotspot/src/share/vm/opto/escape.hpp index 93cfd0ec89d..1ce0cc9cf29 100644 --- a/hotspot/src/share/vm/opto/escape.hpp +++ b/hotspot/src/share/vm/opto/escape.hpp @@ -286,7 +286,7 @@ private: // MemNode - new memory input for this node // ChecCastPP - allocation that this is a cast of // allocation - CheckCastPP of the allocation - void split_AddP(Node *addp, Node *base, PhaseGVN *igvn); + bool split_AddP(Node *addp, Node *base, PhaseGVN *igvn); PhiNode *create_split_phi(PhiNode *orig_phi, int alias_idx, GrowableArray &orig_phi_worklist, PhaseGVN *igvn, bool &new_created); PhiNode *split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray &orig_phi_worklist, PhaseGVN *igvn); Node *find_mem(Node *mem, int alias_idx, PhaseGVN *igvn); diff --git a/hotspot/src/share/vm/opto/loopnode.cpp b/hotspot/src/share/vm/opto/loopnode.cpp index c411cdc3451..7e853e6a1f8 100644 --- a/hotspot/src/share/vm/opto/loopnode.cpp +++ b/hotspot/src/share/vm/opto/loopnode.cpp @@ -2625,9 +2625,11 @@ void PhaseIdealLoop::build_loop_late_post( Node *n, const PhaseIdealLoop *verify case Op_LoadF: case Op_LoadI: case Op_LoadKlass: + case Op_LoadNKlass: case Op_LoadL: case Op_LoadS: case Op_LoadP: + case Op_LoadN: case Op_LoadRange: case Op_LoadD_unaligned: case Op_LoadL_unaligned: diff --git a/hotspot/src/share/vm/opto/loopopts.cpp b/hotspot/src/share/vm/opto/loopopts.cpp index 3ac320cbfc3..06aab460d9c 100644 --- a/hotspot/src/share/vm/opto/loopopts.cpp +++ b/hotspot/src/share/vm/opto/loopopts.cpp @@ -96,6 +96,10 @@ Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) { // our new node, even though we may throw the node away. // (Note: This tweaking with igvn only works because x is a new node.) _igvn.set_type(x, t); + // If x is a TypeNode, capture any more-precise type permanently into Node + // othewise it will be not updated during igvn->transform since + // igvn->type(x) is set to x->Value() already. + x->raise_bottom_type(t); Node *y = x->Identity(&_igvn); if( y != x ) { wins++; @@ -464,11 +468,11 @@ Node *PhaseIdealLoop::conditional_move( Node *region ) { case T_FLOAT: case T_DOUBLE: case T_ADDRESS: // (RawPtr) - case T_NARROWOOP: cost++; break; + case T_NARROWOOP: // Fall through case T_OBJECT: { // Base oops are OK, but not derived oops - const TypeOopPtr *tp = phi->type()->isa_oopptr(); + const TypeOopPtr *tp = phi->type()->make_ptr()->isa_oopptr(); // Derived pointers are Bad (tm): what's the Base (for GC purposes) of a // CMOVE'd derived pointer? It's a CMOVE'd derived base. Thus // CMOVE'ing a derived pointer requires we also CMOVE the base. If we @@ -499,11 +503,11 @@ Node *PhaseIdealLoop::conditional_move( Node *region ) { return NULL; // Too much speculative goo } } - // See if the Phi is used by a Cmp. This will likely Split-If, a - // higher-payoff operation. + // See if the Phi is used by a Cmp or Narrow oop Decode/Encode. + // This will likely Split-If, a higher-payoff operation. for (DUIterator_Fast kmax, k = phi->fast_outs(kmax); k < kmax; k++) { Node* use = phi->fast_out(k); - if( use->is_Cmp() ) + if( use->is_Cmp() || use->is_DecodeN() || use->is_EncodeP() ) return NULL; } } diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp index edbadc5a09b..dd9530885e9 100644 --- a/hotspot/src/share/vm/opto/memnode.cpp +++ b/hotspot/src/share/vm/opto/memnode.cpp @@ -1231,6 +1231,10 @@ Node *LoadNode::split_through_phi(PhaseGVN *phase) { // our new node, even though we may throw the node away. // (This tweaking with igvn only works because x is a new node.) igvn->set_type(x, t); + // If x is a TypeNode, capture any more-precise type permanently into Node + // othewise it will be not updated during igvn->transform since + // igvn->type(x) is set to x->Value() already. + x->raise_bottom_type(t); Node *y = x->Identity(igvn); if( y != x ) { wins++; @@ -1409,7 +1413,7 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const { // had an original form like p1:(AddP x x (LShiftL quux 3)), where the // expression (LShiftL quux 3) independently optimized to the constant 8. if ((t->isa_int() == NULL) && (t->isa_long() == NULL) - && Opcode() != Op_LoadKlass) { + && Opcode() != Op_LoadKlass && Opcode() != Op_LoadNKlass) { // t might actually be lower than _type, if _type is a unique // concrete subclass of abstract class t. // Make sure the reference is not into the header, by comparing diff --git a/hotspot/src/share/vm/opto/subnode.cpp b/hotspot/src/share/vm/opto/subnode.cpp index 90ad08700c3..ac7de63bf98 100644 --- a/hotspot/src/share/vm/opto/subnode.cpp +++ b/hotspot/src/share/vm/opto/subnode.cpp @@ -681,7 +681,11 @@ Node *CmpPNode::Ideal( PhaseGVN *phase, bool can_reshape ) { // Now check for LoadKlass on left. Node* ldk1 = in(1); - if (ldk1->Opcode() != Op_LoadKlass) + if (ldk1->is_DecodeN()) { + ldk1 = ldk1->in(1); + if (ldk1->Opcode() != Op_LoadNKlass ) + return NULL; + } else if (ldk1->Opcode() != Op_LoadKlass ) return NULL; // Take apart the address of the LoadKlass: Node* adr1 = ldk1->in(MemNode::Address); @@ -702,7 +706,11 @@ Node *CmpPNode::Ideal( PhaseGVN *phase, bool can_reshape ) { // Check for a LoadKlass from primary supertype array. // Any nested loadklass from loadklass+con must be from the p.s. array. - if (ldk2->Opcode() != Op_LoadKlass) + if (ldk2->is_DecodeN()) { + // Keep ldk2 as DecodeN since it could be used in CmpP below. + if (ldk2->in(1)->Opcode() != Op_LoadNKlass ) + return NULL; + } else if (ldk2->Opcode() != Op_LoadKlass) return NULL; // Verify that we understand the situation diff --git a/hotspot/src/share/vm/opto/type.cpp b/hotspot/src/share/vm/opto/type.cpp index 3a77c9da4f0..e850d018e8d 100644 --- a/hotspot/src/share/vm/opto/type.cpp +++ b/hotspot/src/share/vm/opto/type.cpp @@ -804,6 +804,7 @@ const Type *TypeF::xmeet( const Type *t ) const { case InstPtr: case KlassPtr: case AryPtr: + case NarrowOop: case Int: case Long: case DoubleTop: @@ -2263,6 +2264,7 @@ const Type *TypeOopPtr::xmeet( const Type *t ) const { case DoubleTop: case DoubleCon: case DoubleBot: + case NarrowOop: case Bottom: // Ye Olde Default return Type::BOTTOM; case Top: @@ -3465,7 +3467,7 @@ bool TypeNarrowOop::empty(void) const { return _ooptype->empty(); } -//------------------------------meet------------------------------------------- +//------------------------------xmeet------------------------------------------ // Compute the MEET of two types. It returns a new Type object. const Type *TypeNarrowOop::xmeet( const Type *t ) const { // Perform a fast test for common case; meeting the same types together. @@ -3483,6 +3485,13 @@ const Type *TypeNarrowOop::xmeet( const Type *t ) const { case DoubleTop: case DoubleCon: case DoubleBot: + case AnyPtr: + case RawPtr: + case OopPtr: + case InstPtr: + case KlassPtr: + case AryPtr: + case Bottom: // Ye Olde Default return Type::BOTTOM; case Top: @@ -3499,16 +3508,9 @@ const Type *TypeNarrowOop::xmeet( const Type *t ) const { default: // All else is a mistake typerr(t); - case RawPtr: - case AnyPtr: - case OopPtr: - case InstPtr: - case KlassPtr: - case AryPtr: - typerr(t); - return Type::BOTTOM; - } // End of switch + + return this; } const Type *TypeNarrowOop::xdual() const { // Compute dual right now. @@ -3702,6 +3704,7 @@ const Type *TypeKlassPtr::xmeet( const Type *t ) const { case DoubleTop: case DoubleCon: case DoubleBot: + case NarrowOop: case Bottom: // Ye Olde Default return Type::BOTTOM; case Top: From 3da24841be56bdf693567d487310833d836e1684 Mon Sep 17 00:00:00 2001 From: Xiaobin Lu Date: Fri, 1 Aug 2008 15:12:34 -0700 Subject: [PATCH 23/95] 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 24/95] 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 25/95] 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 26/95] 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 27/95] 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 28/95] 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 29/95] 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 30/95] 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 31/95] 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 32/95] 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 33/95] 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 34/95] 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 35/95] 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 36/95] 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 37/95] 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 38/95] 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 39/95] 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 40/95] 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 41/95] 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 42/95] 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 43/95] 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 1e49d39e6b7b2b43f51779c730135f2fd8fd7dcc Mon Sep 17 00:00:00 2001 From: Chuck Rasbold Date: Thu, 14 Aug 2008 10:15:29 -0700 Subject: [PATCH 44/95] 6732154: REG: Printing an Image using image/gif doc flavor crashes the VM, Solsparc Delay transform call until uses of t2 are constructed Reviewed-by: never --- hotspot/src/share/vm/opto/divnode.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/opto/divnode.cpp b/hotspot/src/share/vm/opto/divnode.cpp index 90e198d0763..591456f788a 100644 --- a/hotspot/src/share/vm/opto/divnode.cpp +++ b/hotspot/src/share/vm/opto/divnode.cpp @@ -264,8 +264,14 @@ static Node *long_by_long_mulhi( PhaseGVN *phase, Node *dividend, jlong magic_co Node *t1 = phase->transform(new (phase->C, 3) URShiftLNode(lolo_product, phase->intcon(N / 2))); Node *t2 = phase->transform(new (phase->C, 3) AddLNode(hilo_product, t1)); - Node *t3 = phase->transform(new (phase->C, 3) RShiftLNode(t2, phase->intcon(N / 2))); - Node *t4 = phase->transform(new (phase->C, 3) AndLNode(t2, phase->longcon(0xFFFFFFFF))); + + // Construct both t3 and t4 before transforming so t2 doesn't go dead + // prematurely. + Node *t3 = new (phase->C, 3) RShiftLNode(t2, phase->intcon(N / 2)); + Node *t4 = new (phase->C, 3) AndLNode(t2, phase->longcon(0xFFFFFFFF)); + t3 = phase->transform(t3); + t4 = phase->transform(t4); + Node *t5 = phase->transform(new (phase->C, 3) AddLNode(t4, lohi_product)); Node *t6 = phase->transform(new (phase->C, 3) RShiftLNode(t5, phase->intcon(N / 2))); Node *t7 = phase->transform(new (phase->C, 3) AddLNode(t3, hihi_product)); From 0e04930c24e8f74e546a92249cdf872ffeb6fe23 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Thu, 14 Aug 2008 11:18:53 -0700 Subject: [PATCH 45/95] 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 46/95] 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 47/95] 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 48/95] 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 49/95] 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 50/95] 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 51/95] 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 45f8e241e3d324748fae0f074a89c862ded4269b Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Mon, 18 Aug 2008 23:17:51 -0700 Subject: [PATCH 52/95] 6732194: Data corruption dependent on -server/-client/-Xbatch Rematerializing nodes results in incorrect inputs Reviewed-by: rasbold --- hotspot/src/share/vm/opto/chaitin.cpp | 6 +++--- hotspot/src/share/vm/opto/chaitin.hpp | 5 ++++- hotspot/src/share/vm/opto/coalesce.cpp | 4 ++-- hotspot/src/share/vm/opto/ifg.cpp | 2 +- hotspot/src/share/vm/opto/reg_split.cpp | 14 +++++++++++--- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/hotspot/src/share/vm/opto/chaitin.cpp b/hotspot/src/share/vm/opto/chaitin.cpp index 5d7efdb7637..74a0fce9014 100644 --- a/hotspot/src/share/vm/opto/chaitin.cpp +++ b/hotspot/src/share/vm/opto/chaitin.cpp @@ -43,7 +43,7 @@ void LRG::dump( ) const { if( _degree_valid ) tty->print( "%d ", _eff_degree ); else tty->print("? "); - if( _def == NodeSentinel ) { + if( is_multidef() ) { tty->print("MultiDef "); if (_defs != NULL) { tty->print("("); @@ -765,7 +765,7 @@ void PhaseChaitin::gather_lrg_masks( bool after_aggressive ) { // if the LRG is an unaligned pair, we will have to spill // so clear the LRG's register mask if it is not already spilled if ( !n->is_SpillCopy() && - (lrg._def == NULL || lrg._def == NodeSentinel || !lrg._def->is_SpillCopy()) && + (lrg._def == NULL || lrg.is_multidef() || !lrg._def->is_SpillCopy()) && lrgmask.is_misaligned_Pair()) { lrg.Clear(); } @@ -1282,7 +1282,7 @@ uint PhaseChaitin::Select( ) { // Live range is live and no colors available else { assert( lrg->alive(), "" ); - assert( !lrg->_fat_proj || lrg->_def == NodeSentinel || + assert( !lrg->_fat_proj || lrg->is_multidef() || lrg->_def->outcnt() > 0, "fat_proj cannot spill"); assert( !orig_mask.is_AllStack(), "All Stack does not spill" ); diff --git a/hotspot/src/share/vm/opto/chaitin.hpp b/hotspot/src/share/vm/opto/chaitin.hpp index 273fb03206f..9c7cc593e40 100644 --- a/hotspot/src/share/vm/opto/chaitin.hpp +++ b/hotspot/src/share/vm/opto/chaitin.hpp @@ -156,6 +156,8 @@ public: // Alive if non-zero, dead if zero bool alive() const { return _def != NULL; } + bool is_multidef() const { return _def == NodeSentinel; } + bool is_singledef() const { return _def != NodeSentinel; } #ifndef PRODUCT void dump( ) const; @@ -320,7 +322,8 @@ class PhaseChaitin : public PhaseRegAlloc { uint split_DEF( Node *def, Block *b, int loc, uint max, Node **Reachblock, Node **debug_defs, GrowableArray splits, int slidx ); uint split_USE( Node *def, Block *b, Node *use, uint useidx, uint max, bool def_down, bool cisc_sp, GrowableArray splits, int slidx ); int clone_projs( Block *b, uint idx, Node *con, Node *copy, uint &maxlrg ); - Node *split_Rematerialize( Node *def, Block *b, uint insidx, uint &maxlrg, GrowableArray splits, int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru ); + Node *split_Rematerialize(Node *def, Block *b, uint insidx, uint &maxlrg, GrowableArray splits, + int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru); // True if lidx is used before any real register is def'd in the block bool prompt_use( Block *b, uint lidx ); Node *get_spillcopy_wide( Node *def, Node *use, uint uidx ); diff --git a/hotspot/src/share/vm/opto/coalesce.cpp b/hotspot/src/share/vm/opto/coalesce.cpp index 20e9bd17992..b7e8a85dc61 100644 --- a/hotspot/src/share/vm/opto/coalesce.cpp +++ b/hotspot/src/share/vm/opto/coalesce.cpp @@ -604,8 +604,8 @@ void PhaseConservativeCoalesce::union_helper( Node *lr1_node, Node *lr2_node, ui // If both are single def, then src_def powers one live range // and def_copy powers the other. After merging, src_def powers // the combined live range. - lrgs(lr1)._def = (lrgs(lr1)._def == NodeSentinel || - lrgs(lr2)._def == NodeSentinel ) + lrgs(lr1)._def = (lrgs(lr1).is_multidef() || + lrgs(lr2).is_multidef() ) ? NodeSentinel : src_def; lrgs(lr2)._def = NULL; // No def for lrg 2 lrgs(lr2).Clear(); // Force empty mask for LRG 2 diff --git a/hotspot/src/share/vm/opto/ifg.cpp b/hotspot/src/share/vm/opto/ifg.cpp index 2c6cd665fea..e7f55aa5b09 100644 --- a/hotspot/src/share/vm/opto/ifg.cpp +++ b/hotspot/src/share/vm/opto/ifg.cpp @@ -594,7 +594,7 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) { // Insure high score for immediate-use spill copies so they get a color if( n->is_SpillCopy() - && lrgs(r)._def != NodeSentinel // MultiDef live range can still split + && lrgs(r).is_singledef() // MultiDef live range can still split && n->outcnt() == 1 // and use must be in this block && _cfg._bbs[n->unique_out()->_idx] == b ) { // All single-use MachSpillCopy(s) that immediately precede their diff --git a/hotspot/src/share/vm/opto/reg_split.cpp b/hotspot/src/share/vm/opto/reg_split.cpp index 5101eb2e75a..a562eacc26a 100644 --- a/hotspot/src/share/vm/opto/reg_split.cpp +++ b/hotspot/src/share/vm/opto/reg_split.cpp @@ -284,7 +284,7 @@ Node *PhaseChaitin::split_Rematerialize( Node *def, Block *b, uint insidx, uint // Check for single-def (LRG cannot redefined) uint lidx = n2lidx(in); if( lidx >= _maxlrg ) continue; // Value is a recent spill-copy - if( lrgs(lidx)._def != NodeSentinel ) continue; + if (lrgs(lidx).is_singledef()) continue; Block *b_def = _cfg._bbs[def->_idx]; int idx_def = b_def->find_node(def); @@ -311,12 +311,20 @@ Node *PhaseChaitin::split_Rematerialize( Node *def, Block *b, uint insidx, uint uint lidx = Find_id(in); // Walk backwards thru spill copy node intermediates - if( walkThru ) + if (walkThru) { while ( in->is_SpillCopy() && lidx >= _maxlrg ) { in = in->in(1); lidx = Find_id(in); } + if (lidx < _maxlrg && lrgs(lidx).is_multidef()) { + // walkThru found a multidef LRG, which is unsafe to use, so + // just keep the original def used in the clone. + in = spill->in(i); + lidx = Find_id(in); + } + } + if( lidx < _maxlrg && lrgs(lidx).reg() >= LRG::SPILL_REG ) { Node *rdef = Reachblock[lrg2reach[lidx]]; if( rdef ) spill->set_req(i,rdef); @@ -505,7 +513,7 @@ uint PhaseChaitin::Split( uint maxlrg ) { // Do not bother splitting or putting in Phis for single-def // rematerialized live ranges. This happens alot to constants // with long live ranges. - if( lrgs(lidx)._def != NodeSentinel && + if( lrgs(lidx).is_singledef() && lrgs(lidx)._def->rematerialize() ) { // reset the Reaches & UP entries Reachblock[slidx] = lrgs(lidx)._def; From ae4e7551248a449b5b132b5ce7f4929b67e8d509 Mon Sep 17 00:00:00 2001 From: Chuck Rasbold Date: Tue, 19 Aug 2008 07:25:02 -0700 Subject: [PATCH 53/95] 6730716: nulls from two unrelated classes compare not equal Check for not-nullness after proving that types are unrelated Reviewed-by: kvn, never --- hotspot/src/share/vm/opto/subnode.cpp | 46 ++++++++++++++++++++------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/hotspot/src/share/vm/opto/subnode.cpp b/hotspot/src/share/vm/opto/subnode.cpp index ac7de63bf98..774aff9f430 100644 --- a/hotspot/src/share/vm/opto/subnode.cpp +++ b/hotspot/src/share/vm/opto/subnode.cpp @@ -633,20 +633,31 @@ const Type *CmpPNode::sub( const Type *t1, const Type *t2 ) const { kps != 1 && // both or neither are klass pointers !klass0->is_interface() && // do not trust interfaces !klass1->is_interface()) { + bool unrelated_classes = false; // See if neither subclasses the other, or if the class on top - // is precise. In either of these cases, the compare must fail. + // is precise. In either of these cases, the compare is known + // to fail if at least one of the pointers is provably not null. if (klass0->equals(klass1) || // if types are unequal but klasses are !klass0->is_java_klass() || // types not part of Java language? !klass1->is_java_klass()) { // types not part of Java language? // Do nothing; we know nothing for imprecise types } else if (klass0->is_subtype_of(klass1)) { - // If klass1's type is PRECISE, then we can fail. - if (xklass1) return TypeInt::CC_GT; + // If klass1's type is PRECISE, then classes are unrelated. + unrelated_classes = xklass1; } else if (klass1->is_subtype_of(klass0)) { - // If klass0's type is PRECISE, then we can fail. - if (xklass0) return TypeInt::CC_GT; + // If klass0's type is PRECISE, then classes are unrelated. + unrelated_classes = xklass0; } else { // Neither subtypes the other - return TypeInt::CC_GT; // ...so always fail + unrelated_classes = true; + } + if (unrelated_classes) { + // The oops classes are known to be unrelated. If the joined PTRs of + // two oops is not Null and not Bottom, then we are sure that one + // of the two oops is non-null, and the comparison will always fail. + TypePtr::PTR jp = r0->join_ptr(r1->_ptr); + if (jp != TypePtr::Null && jp != TypePtr::BotPTR) { + return TypeInt::CC_GT; + } } } } @@ -777,20 +788,31 @@ const Type *CmpNNode::sub( const Type *t1, const Type *t2 ) const { kps != 1 && // both or neither are klass pointers !klass0->is_interface() && // do not trust interfaces !klass1->is_interface()) { + bool unrelated_classes = false; // See if neither subclasses the other, or if the class on top - // is precise. In either of these cases, the compare must fail. + // is precise. In either of these cases, the compare is known + // to fail if at least one of the pointers is provably not null. if (klass0->equals(klass1) || // if types are unequal but klasses are !klass0->is_java_klass() || // types not part of Java language? !klass1->is_java_klass()) { // types not part of Java language? // Do nothing; we know nothing for imprecise types } else if (klass0->is_subtype_of(klass1)) { - // If klass1's type is PRECISE, then we can fail. - if (xklass1) return TypeInt::CC_GT; + // If klass1's type is PRECISE, then classes are unrelated. + unrelated_classes = xklass1; } else if (klass1->is_subtype_of(klass0)) { - // If klass0's type is PRECISE, then we can fail. - if (xklass0) return TypeInt::CC_GT; + // If klass0's type is PRECISE, then classes are unrelated. + unrelated_classes = xklass0; } else { // Neither subtypes the other - return TypeInt::CC_GT; // ...so always fail + unrelated_classes = true; + } + if (unrelated_classes) { + // The oops classes are known to be unrelated. If the joined PTRs of + // two oops is not Null and not Bottom, then we are sure that one + // of the two oops is non-null, and the comparison will always fail. + TypePtr::PTR jp = r0->join_ptr(r1->_ptr); + if (jp != TypePtr::Null && jp != TypePtr::BotPTR) { + return TypeInt::CC_GT; + } } } } From 731dd43ab4324229228e889c8e15e3652ac37423 Mon Sep 17 00:00:00 2001 From: Kumar Srinivasan Date: Tue, 19 Aug 2008 07:50:03 -0700 Subject: [PATCH 54/95] 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 b00baea4a1e924e862db1c06e143fd06fc333d4b Mon Sep 17 00:00:00 2001 From: Antonios Printezis Date: Tue, 19 Aug 2008 17:55:15 -0400 Subject: [PATCH 55/95] 6736341: PermGen size is insufficient for jconsole Removing two buggy methods that should not be used, but ended up being used due to a re-organization in the class hierarchy. Reviewed-by: jmasa, ysr, kamg, coleenp --- .../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 6804a4e8ef68108e29b56d5f4326e7149d5172cd Mon Sep 17 00:00:00 2001 From: "Y. Srinivas Ramakrishna" Date: Wed, 20 Aug 2008 15:41:36 -0700 Subject: [PATCH 56/95] 6739357: CMS: Switch off CMSPrecleanRefLists1 until 6722113 can be fixed Temporarily switch off the precleaning of Reference lists completely until related issues are fixed in 6722113. Reviewed-by: jmasa, poonam, tonyp --- hotspot/src/share/vm/runtime/globals.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 51f59293b85..f06fa3cef72 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -1443,7 +1443,7 @@ class CommandLineFlags { "CMSPrecleanNumerator:CMSPrecleanDenominator yields convergence" \ " ratio") \ \ - product(bool, CMSPrecleanRefLists1, true, \ + product(bool, CMSPrecleanRefLists1, false, \ "Preclean ref lists during (initial) preclean phase") \ \ product(bool, CMSPrecleanRefLists2, false, \ From befe056b42cae6ae1068e50403f5b663b00aeb60 Mon Sep 17 00:00:00 2001 From: Jon Masamitsu Date: Wed, 20 Aug 2008 23:05:04 -0700 Subject: [PATCH 57/95] 6728478: Assertion at parallel promotion from young to old generation The fix avoids a call to address_for_index() in this particular situation where it is not known if the passed index is in bounds. Reviewed-by: tonyp --- .../share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp | 2 +- hotspot/src/share/vm/memory/blockOffsetTable.hpp | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp b/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp index 94377a3beb4..d4c641bf028 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp @@ -229,7 +229,7 @@ void ParGCAllocBufferWithBOT::retire(bool end_of_gc, bool retain) { HeapWord* first_card_start = _bsa->address_for_index(first_card_index); if (first_card_start < pre_top) { HeapWord* second_card_start = - _bsa->address_for_index(first_card_index + 1); + _bsa->inc_by_region_size(first_card_start); // Ensure enough room to fill with the smallest block second_card_start = MAX2(second_card_start, pre_top + AlignmentReserve); diff --git a/hotspot/src/share/vm/memory/blockOffsetTable.hpp b/hotspot/src/share/vm/memory/blockOffsetTable.hpp index fc76fc9208c..be9ec01bf30 100644 --- a/hotspot/src/share/vm/memory/blockOffsetTable.hpp +++ b/hotspot/src/share/vm/memory/blockOffsetTable.hpp @@ -199,6 +199,12 @@ public: // "index" in "_offset_array". HeapWord* address_for_index(size_t index) const; + // Return the address "p" incremented by the size of + // a region. This method does not align the address + // returned to the start of a region. It is a simple + // primitive. + HeapWord* inc_by_region_size(HeapWord* p) const { return p + N_words; } + // Shared space support void serialize(SerializeOopClosure* soc, HeapWord* start, HeapWord* end); }; From b9c79ae21317385648046c0d119865cf39144d8d Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Fri, 22 Aug 2008 11:46:29 +0100 Subject: [PATCH 58/95] 6733837: Recent work on javac diagnostic affected javac output Problems with diagnostic path and tab character in the source code Reviewed-by: darcy, jjg --- .../tools/javac/api/DiagnosticFormatter.java | 3 +- .../util/AbstractDiagnosticFormatter.java | 4 +- .../javac/util/BasicDiagnosticFormatter.java | 4 +- .../tools/javac/util/DiagnosticSource.java | 4 +- .../sun/tools/javac/util/JCDiagnostic.java | 2 +- .../classes/com/sun/tools/javac/util/Log.java | 2 +- .../javac/util/RawDiagnosticFormatter.java | 8 +-- .../tools/javac/api/6733837/T6733837.java | 72 +++++++++++++++++++ 8 files changed, 83 insertions(+), 16 deletions(-) create mode 100644 langtools/test/tools/javac/api/6733837/T6733837.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/api/DiagnosticFormatter.java b/langtools/src/share/classes/com/sun/tools/javac/api/DiagnosticFormatter.java index 03bc2fe9468..6fd51b146b1 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/api/DiagnosticFormatter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/api/DiagnosticFormatter.java @@ -73,9 +73,10 @@ public interface DiagnosticFormatter> { * * @param diag diagnostic to be formatted * @param l locale object to be used for i18n + * @param fullname whether the source fullname should be printed * @return string representation of the diagnostic source */ - public String formatSource(D diag, Locale l); + public String formatSource(D diag, boolean fullname, Locale l); /** * Controls the way in which a diagnostic position is displayed. diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java b/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java index 54844470bcf..c4daa885e7e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java @@ -94,9 +94,9 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter } } - public String formatSource(JCDiagnostic d,Locale l) { + public String formatSource(JCDiagnostic d, boolean fullname, Locale l) { assert (d.getSource() != null); - return d.getSource().getName(); + return fullname ? d.getSourceName() : d.getSource().getName(); } /** diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java b/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java index 84b41bfbef4..c2499f1cd5a 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java @@ -108,11 +108,11 @@ public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter { protected String formatMeta(char c, JCDiagnostic d, Locale l) { switch (c) { case 'b': - return formatSource(d, l); + return formatSource(d, false, l); case 'e': return formatPosition(d, END, l); case 'f': - return formatSource(d, l); + return formatSource(d, true, l); case 'l': return formatPosition(d, LINE, l); case 'c': diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/DiagnosticSource.java b/langtools/src/share/classes/com/sun/tools/javac/util/DiagnosticSource.java index c30d0a5cb2e..3c573191a5e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/DiagnosticSource.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/DiagnosticSource.java @@ -81,7 +81,7 @@ public class DiagnosticSource { * for the current source file. Zero is returned if no column exists * for the given position. */ - public int getColumnNumber(int pos) { + public int getColumnNumber(int pos, boolean expandTabs) { try { if (findLine(pos)) { int column = 0; @@ -89,7 +89,7 @@ public class DiagnosticSource { if (bp >= bufLen) { return 0; } - if (buf[bp] == '\t') { + if (buf[bp] == '\t' && expandTabs) { column = (column / TabInc * TabInc) + TabInc; } else { column++; 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 acc2328a5cf..2ecac0850e8 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 @@ -296,7 +296,7 @@ public class JCDiagnostic implements Diagnostic { line = column = -1; else { line = source.getLineNumber(n); - column = source.getColumnNumber(n); + column = source.getColumnNumber(n, true); } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java index e92d54438ce..d4d7c123cc6 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java @@ -244,7 +244,7 @@ public class Log extends AbstractLog { String line = (source == null ? null : source.getLine(pos)); if (line == null) return; - int col = source.getColumnNumber(pos); + int col = source.getColumnNumber(pos, false); printLines(writer, line); for (int i = 0; i < col - 1; i++) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java b/langtools/src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java index 22f4fe62fd3..3d51e248dfe 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java @@ -50,7 +50,7 @@ public class RawDiagnosticFormatter extends AbstractDiagnosticFormatter { try { StringBuffer buf = new StringBuffer(); if (d.getPosition() != Position.NOPOS) { - buf.append(formatSource(d, null)); + buf.append(formatSource(d, false, null)); buf.append(':'); buf.append(formatPosition(d, LINE, null)); buf.append(':'); @@ -69,12 +69,6 @@ public class RawDiagnosticFormatter extends AbstractDiagnosticFormatter { } } - @Override - public String formatSource(JCDiagnostic d,Locale l) { - assert(d.getSource() != null); - return d.getSource().getName(); - } - @Override protected String formatArgument(JCDiagnostic diag, Object arg, Locale l) { String s; diff --git a/langtools/test/tools/javac/api/6733837/T6733837.java b/langtools/test/tools/javac/api/6733837/T6733837.java new file mode 100644 index 00000000000..8ed7d4922d6 --- /dev/null +++ b/langtools/test/tools/javac/api/6733837/T6733837.java @@ -0,0 +1,72 @@ +/* + * 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 6733837 + * @summary Compiler API ignores locale settings + * @author Maurizio Cimadamore + * @library ../lib + */ + +import java.io.StringWriter; +import java.io.PrintWriter; +import java.net.URI; +import java.util.Arrays; +import java.util.List; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import static javax.tools.JavaFileObject.Kind; +import com.sun.source.util.JavacTask; + +public class T6733837 extends ToolTester { + + public static void main(String... args) { + new T6733837().exec(); + } + + public void exec() { + JavaFileObject sfo = new SimpleJavaFileObject(URI.create(""),Kind.SOURCE) { + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return "\tclass ErroneousWithTab"; + } + @Override + public String getName() { + return "RELATIVEPATH"; + } + }; + StringWriter sw = new StringWriter(); + PrintWriter out = new PrintWriter(sw); + List files = Arrays.asList(sfo); + task = tool.getTask(sw, fm, null, null, null, files); + try { + ((JavacTask)task).analyze(); + } + catch (Throwable t) { + throw new Error("Compiler threw an exception"); + } + System.err.println(sw.toString()); + if (sw.toString().contains("RELATIVEPATH")) + throw new Error("Bad source name in diagnostic"); + } +} From 2697216f3a1cc53ea17f7d822858df39d13cb2f7 Mon Sep 17 00:00:00 2001 From: Matthias Klose Date: Tue, 26 Aug 2008 15:49:40 -0700 Subject: [PATCH 59/95] 6741642: bad enum definition in ciTypeFlow.hpp Reviewed-by: rasbold, martin --- hotspot/src/share/vm/ci/ciTypeFlow.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/ci/ciTypeFlow.hpp b/hotspot/src/share/vm/ci/ciTypeFlow.hpp index 2235a90a1df..9b5193ba54b 100644 --- a/hotspot/src/share/vm/ci/ciTypeFlow.hpp +++ b/hotspot/src/share/vm/ci/ciTypeFlow.hpp @@ -127,7 +127,7 @@ public: // Used as a combined index for locals and temps enum Cell { - Cell_0 + Cell_0, Cell_max = INT_MAX }; // A StateVector summarizes the type information at some From 26c780da7283862317f01e6f43b280d2fde32c42 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Wed, 27 Aug 2008 00:21:55 -0700 Subject: [PATCH 60/95] 5108146: Merge i486 and amd64 cpu directories 6459804: Want client (c1) compiler for x86_64 (amd64) for faster start-up Reviewed-by: kvn --- .../solaris/makefiles/reorder_COMPILER1_amd64 | 5450 +++++++++ .../solaris/makefiles/reorder_COMPILER1_i486 | 226 +- .../cpu/sparc/vm/c1_LIRGenerator_sparc.cpp | 3 +- hotspot/src/cpu/sparc/vm/relocInfo_sparc.cpp | 6 + .../src/cpu/sparc/vm/sharedRuntime_sparc.cpp | 14 +- ...assembler_x86_64.cpp => assembler_x86.cpp} | 9802 ++++++++++------- ...assembler_x86_32.hpp => assembler_x86.hpp} | 1540 ++- ...64.inline.hpp => assembler_x86.inline.hpp} | 39 +- hotspot/src/cpu/x86/vm/assembler_x86_32.cpp | 5001 --------- .../cpu/x86/vm/assembler_x86_32.inline.hpp | 64 - hotspot/src/cpu/x86/vm/assembler_x86_64.hpp | 1477 --- hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp | 19 +- hotspot/src/cpu/x86/vm/c1_Defs_x86.hpp | 31 +- hotspot/src/cpu/x86/vm/c1_FrameMap_x86.cpp | 123 +- hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp | 41 +- .../src/cpu/x86/vm/c1_LIRAssembler_x86.cpp | 752 +- .../src/cpu/x86/vm/c1_LIRAssembler_x86.hpp | 11 +- .../src/cpu/x86/vm/c1_LIRGenerator_x86.cpp | 60 +- hotspot/src/cpu/x86/vm/c1_LinearScan_x86.hpp | 13 +- .../src/cpu/x86/vm/c1_MacroAssembler_x86.cpp | 111 +- .../src/cpu/x86/vm/c1_MacroAssembler_x86.hpp | 11 +- hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp | 674 +- hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp | 785 +- hotspot/src/cpu/x86/vm/dump_x86_32.cpp | 20 +- hotspot/src/cpu/x86/vm/dump_x86_64.cpp | 28 +- hotspot/src/cpu/x86/vm/frame_x86.cpp | 3 +- hotspot/src/cpu/x86/vm/frame_x86.inline.hpp | 4 +- hotspot/src/cpu/x86/vm/icache_x86.cpp | 4 +- hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp | 360 +- hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp | 31 +- hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp | 368 +- hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp | 73 +- .../src/cpu/x86/vm/interpreterRT_x86_32.cpp | 8 +- .../src/cpu/x86/vm/interpreterRT_x86_64.cpp | 88 +- hotspot/src/cpu/x86/vm/interpreter_x86_32.cpp | 20 +- hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp | 236 +- .../src/cpu/x86/vm/jniFastGetField_x86_32.cpp | 86 +- .../src/cpu/x86/vm/jniFastGetField_x86_64.cpp | 32 +- hotspot/src/cpu/x86/vm/nativeInst_x86.cpp | 178 +- hotspot/src/cpu/x86/vm/nativeInst_x86.hpp | 127 +- hotspot/src/cpu/x86/vm/relocInfo_x86.cpp | 72 +- hotspot/src/cpu/x86/vm/runtime_x86_32.cpp | 32 +- .../src/cpu/x86/vm/sharedRuntime_x86_32.cpp | 543 +- .../src/cpu/x86/vm/sharedRuntime_x86_64.cpp | 488 +- .../src/cpu/x86/vm/stubGenerator_x86_32.cpp | 597 +- .../src/cpu/x86/vm/stubGenerator_x86_64.cpp | 685 +- .../src/cpu/x86/vm/stubRoutines_x86_32.cpp | 6 +- .../src/cpu/x86/vm/stubRoutines_x86_32.hpp | 4 +- .../src/cpu/x86/vm/stubRoutines_x86_64.cpp | 22 +- .../src/cpu/x86/vm/stubRoutines_x86_64.hpp | 4 +- .../cpu/x86/vm/templateInterpreter_x86_32.cpp | 332 +- .../cpu/x86/vm/templateInterpreter_x86_64.cpp | 459 +- .../src/cpu/x86/vm/templateTable_x86_32.cpp | 727 +- .../src/cpu/x86/vm/templateTable_x86_32.hpp | 2 +- .../src/cpu/x86/vm/templateTable_x86_64.cpp | 403 +- hotspot/src/cpu/x86/vm/vm_version_x86_32.cpp | 66 +- hotspot/src/cpu/x86/vm/vm_version_x86_64.cpp | 30 +- hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp | 38 +- hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp | 34 +- hotspot/src/cpu/x86/vm/x86_32.ad | 309 +- hotspot/src/cpu/x86/vm/x86_64.ad | 207 +- ...nux_x86_32.cpp => assembler_linux_x86.cpp} | 45 +- .../linux_x86/vm/assembler_linux_x86_64.cpp | 67 - ...s_x86_32.cpp => assembler_solaris_x86.cpp} | 134 +- .../vm/assembler_solaris_x86_64.cpp | 87 - .../os_cpu/solaris_x86/vm/solaris_x86_32.ad | 12 +- ...s_x86_32.cpp => assembler_windows_x86.cpp} | 40 +- .../vm/assembler_windows_x86_64.cpp | 67 - .../os_cpu/windows_x86/vm/os_windows_x86.cpp | 2 +- hotspot/src/share/vm/c1/c1_FrameMap.cpp | 2 +- hotspot/src/share/vm/c1/c1_LIR.cpp | 11 +- hotspot/src/share/vm/c1/c1_LIR.hpp | 155 +- hotspot/src/share/vm/c1/c1_LIRAssembler.cpp | 8 +- hotspot/src/share/vm/c1/c1_LIRAssembler.hpp | 6 +- hotspot/src/share/vm/c1/c1_LIRGenerator.cpp | 2 +- hotspot/src/share/vm/c1/c1_LinearScan.cpp | 73 +- hotspot/src/share/vm/c1/c1_LinearScan.hpp | 2 +- hotspot/src/share/vm/c1/c1_Runtime1.cpp | 15 - hotspot/src/share/vm/code/relocInfo.hpp | 2 + hotspot/src/share/vm/includeDB_compiler1 | 3 +- hotspot/src/share/vm/includeDB_compiler2 | 4 +- hotspot/src/share/vm/includeDB_core | 74 +- hotspot/src/share/vm/includeDB_features | 2 +- hotspot/src/share/vm/runtime/vmStructs.cpp | 4 +- hotspot/src/share/vm/utilities/macros.hpp | 8 + 85 files changed, 18308 insertions(+), 15496 deletions(-) create mode 100644 hotspot/make/solaris/makefiles/reorder_COMPILER1_amd64 rename hotspot/src/cpu/x86/vm/{assembler_x86_64.cpp => assembler_x86.cpp} (58%) rename hotspot/src/cpu/x86/vm/{assembler_x86_32.hpp => assembler_x86.hpp} (63%) rename hotspot/src/cpu/x86/vm/{assembler_x86_64.inline.hpp => assembler_x86.inline.hpp} (74%) delete mode 100644 hotspot/src/cpu/x86/vm/assembler_x86_32.cpp delete mode 100644 hotspot/src/cpu/x86/vm/assembler_x86_32.inline.hpp delete mode 100644 hotspot/src/cpu/x86/vm/assembler_x86_64.hpp rename hotspot/src/os_cpu/linux_x86/vm/{assembler_linux_x86_32.cpp => assembler_linux_x86.cpp} (63%) delete mode 100644 hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86_64.cpp rename hotspot/src/os_cpu/solaris_x86/vm/{assembler_solaris_x86_32.cpp => assembler_solaris_x86.cpp} (50%) delete mode 100644 hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86_64.cpp rename hotspot/src/os_cpu/windows_x86/vm/{assembler_windows_x86_32.cpp => assembler_windows_x86.cpp} (78%) delete mode 100644 hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86_64.cpp diff --git a/hotspot/make/solaris/makefiles/reorder_COMPILER1_amd64 b/hotspot/make/solaris/makefiles/reorder_COMPILER1_amd64 new file mode 100644 index 00000000000..fdc435bbf27 --- /dev/null +++ b/hotspot/make/solaris/makefiles/reorder_COMPILER1_amd64 @@ -0,0 +1,5450 @@ +data = R0x2000; +text = LOAD ?RXO; + + +# Test Null +text: .text%__cplus_fini_at_exit: CCrti.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: arguments.o; +text: .text%__1cQAgentLibraryList2t6M_v_: arguments.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_AllocTable.o; +text: .text%__1cFRInfo2t6M_v_: c1_AllocTable.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_AllocTable_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_AllocTable_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CacheLocals.o; +text: .text%__1cFRInfo2t6M_v_: c1_CacheLocals.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CacheLocals_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_CacheLocals_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Canonicalizer.o; +text: .text%__1cFRInfo2t6M_v_: c1_Canonicalizer.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CodeGenerator.o; +text: .text%__1cFRInfo2t6M_v_: c1_CodeGenerator.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CodeGenerator_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_CodeGenerator_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CodeStubs_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_CodeStubs_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Compilation.o; +text: .text%__1cFRInfo2t6M_v_: c1_Compilation.o; +text: .text%__1cMelapsedTimer2t6M_v_: c1_Compilation.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Compiler.o; +text: .text%__1cFRInfo2t6M_v_: c1_Compiler.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_FrameMap.o; +text: .text%__1cFRInfo2t6M_v_: c1_FrameMap.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_FrameMap_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_FrameMap_x86.o; +text: .text%__1cKc1_RegMask2t6M_v_: c1_FrameMap_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_GraphBuilder.o; +text: .text%__1cFRInfo2t6M_v_: c1_GraphBuilder.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_IR.o; +text: .text%__1cFRInfo2t6M_v_: c1_IR.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Instruction.o; +text: .text%__1cFRInfo2t6M_v_: c1_Instruction.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_InstructionPrinter.o; +text: .text%__1cFRInfo2t6M_v_: c1_InstructionPrinter.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Items.o; +text: .text%__1cFRInfo2t6M_v_: c1_Items.o; +text: .text%__1cIHintItem2t6MpnJValueType_i_v_: c1_Items.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Items_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_Items_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIR.o; +text: .text%__1cFRInfo2t6M_v_: c1_LIR.o; +text: .text%__1cLLIR_OprFactHillegal6F_pnLLIR_OprDesc__: c1_LIR.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIRAssembler.o; +text: .text%__1cFRInfo2t6M_v_: c1_LIRAssembler.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIRAssembler_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_LIRAssembler_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIREmitter.o; +text: .text%__1cFRInfo2t6M_v_: c1_LIREmitter.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIREmitter_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_LIREmitter_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIROptimizer.o; +text: .text%__1cFRInfo2t6M_v_: c1_LIROptimizer.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Loops.o; +text: .text%__1cFRInfo2t6M_v_: c1_Loops.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_MacroAssembler_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_MacroAssembler_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Optimizer.o; +text: .text%__1cFRInfo2t6M_v_: c1_Optimizer.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_RInfo.o; +text: .text%__1cFRInfo2t6M_v_: c1_RInfo.o; +text: .text%__1cKc1_RegMask2t6M_v_: c1_RInfo.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_RInfo_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_RInfo_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_RegAlloc.o; +text: .text%__1cFRInfo2t6M_v_: c1_RegAlloc.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_RegAlloc_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_RegAlloc_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Runtime1.o; +text: .text%__1cFRInfo2t6M_v_: c1_Runtime1.o; +text: .text%__1cIiEntries2t6M_v_; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Runtime1_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_Runtime1_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_ScanBlocks.o; +text: .text%__1cFRInfo2t6M_v_: c1_ScanBlocks.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_ValueMap.o; +text: .text%__1cFRInfo2t6M_v_: c1_ValueMap.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_ValueSet.o; +text: .text%__1cFRInfo2t6M_v_: c1_ValueSet.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_ValueStack.o; +text: .text%__1cFRInfo2t6M_v_: c1_ValueStack.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: codeBlob.o; +text: .text%__1cFRInfo2t6M_v_: codeBlob.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: codeCache.o; +text: .text%__1cICHeapObj2n6FI_pv_; +text: .text%__1cCosGmalloc6FI_pv_; +text: .text%__1cICodeHeap2t6M_v_; +text: .text%__1cMVirtualSpace2t6M_v_; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: compilationPolicy.o; +text: .text%__1cMelapsedTimer2t6M_v_: compilationPolicy.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: compileBroker.o; +text: .text%__1cMelapsedTimer2t6M_v_: compileBroker.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: compiledIC.o; +text: .text%__1cFRInfo2t6M_v_: compiledIC.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: deoptimization.o; +text: .text%__1cFRInfo2t6M_v_: deoptimization.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: fprofiler.o; +text: .text%__1cMelapsedTimer2t6M_v_: fprofiler.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: frame.o; +text: .text%__1cFRInfo2t6M_v_: frame.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: frame_x86.o; +text: .text%__1cFRInfo2t6M_v_: frame_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: genCollectedHeap.o; +text: .text%__1cTAssertIsPermClosure2t6M_v_: genCollectedHeap.o; +text: .text%__1cRAlwaysTrueClosure2t6M_v_: genCollectedHeap.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: generateOopMap.o; +text: .text%__1cNCellTypeStateLmake_bottom6F_0_: generateOopMap.o; +text: .text%__1cNCellTypeStateImake_any6Fi_0_: generateOopMap.o; +text: .text%__1cNCellTypeStateImake_top6F_0_: generateOopMap.o; +text: .text%__1cMelapsedTimer2t6M_v_: generateOopMap.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: interpreter.o; +text: .text%__1cKEntryPoint2t6M_v_; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: interpreter_x86.o; +text: .text%__1cFRInfo2t6M_v_: interpreter_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: java.o; +text: .text%__1cFRInfo2t6M_v_: java.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: jvmtiEnvBase.o; +text: .text%__1cWNonPrintingResourceObj2n6FInLResourceObjPallocation_type__pv_: jvmtiEnvBase.o; +text: .text%__1cLResourceObj2n6FIn0APallocation_type__pv_; +text: .text%__1cNGrowableArray4CpnMJvmtiEnvBase__2t6Mii_v_: jvmtiEnvBase.o; +text: .text%__1cUGenericGrowableArray2t6Mii_v_; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: jvmtiEventController.o; +text: .text%__1cRJvmtiEventEnabled2t6M_v_; +text: .text%__1cRJvmtiEventEnabledFclear6M_v_; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: jvmtiImpl.o; +text: .text%__1cWNonPrintingResourceObj2n6FInLResourceObjPallocation_type__pv_: jvmtiImpl.o; +text: .text%__1cNGrowableArray4CpnPJvmtiRawMonitor__2t6Mii_v_: jvmtiImpl.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: jvmtiTagMap.o; +text: .text%__1cJMemRegion2t6M_v_: jvmtiTagMap.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: klassVtable.o; +text: .text%__1cFRInfo2t6M_v_: klassVtable.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: management.o; +text: .text%__1cJTimeStamp2t6M_v_: management.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: markSweep.o; +text: .text%__1cJMarkSweepSMarkAndPushClosure2t6M_v_: markSweep.o; +text: .text%__1cJMarkSweepRFollowRootClosure2t6M_v_: markSweep.o; +text: .text%__1cJMarkSweepSFollowStackClosure2t6M_v_: markSweep.o; +text: .text%__1cJMarkSweepUAdjustPointerClosure2t6Mi_v_: markSweep.o; +text: .text%__1cJMarkSweepOIsAliveClosure2t6M_v_: markSweep.o; +text: .text%__1cJMarkSweepQKeepAliveClosure2t6M_v_: markSweep.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: memoryService.o; +text: .text%__1cWNonPrintingResourceObj2n6FInLResourceObjPallocation_type__pv_: memoryService.o; +text: .text%__1cNGrowableArray4CpnKMemoryPool__2t6Mii_v_: memoryService.o; +text: .text%__1cNGrowableArray4CpnNMemoryManager__2t6Mii_v_: memoryService.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: methodOop.o; +text: .text%__1cFRInfo2t6M_v_: methodOop.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: nativeInst_x86.o; +text: .text%__1cFRInfo2t6M_v_: nativeInst_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: nmethod.o; +text: .text%__1cFRInfo2t6M_v_: nmethod.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: oopMap.o; +text: .text%__1cQDoNothingClosure2t6M_v_: oopMap.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: os_solaris.o; +text: .text%__1cFRInfo2t6M_v_: os_solaris.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: os_solaris_x86.o; +text: .text%__1cFRInfo2t6M_v_: os_solaris_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: parGCAllocBuffer.o; +text: .text%__1cMarrayOopDescLheader_size6FnJBasicType__i_: parGCAllocBuffer.o; +text: .text%__1cRalign_object_size6Fi_i_: parGCAllocBuffer.o; +text: .text%__1cHoopDescLheader_size6F_i_: parGCAllocBuffer.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: psAdaptiveSizePolicy.o; +text: .text%__1cMelapsedTimer2t6M_v_: psAdaptiveSizePolicy.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: psMarkSweep.o; +text: .text%__1cMelapsedTimer2t6M_v_: psMarkSweep.o; +text: .text%__1cTPSAlwaysTrueClosure2t6M_v_: psMarkSweep.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: psPromotionLAB.o; +text: .text%__1cMarrayOopDescLheader_size6FnJBasicType__i_: psPromotionLAB.o; +text: .text%__1cRalign_object_size6Fi_i_: psPromotionLAB.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: psScavenge.o; +text: .text%__1cMelapsedTimer2t6M_v_: psScavenge.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: relocInfo.o; +text: .text%__1cQRelocationHolder2t6M_v_: relocInfo.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: runtimeService.o; +text: .text%__1cJTimeStamp2t6M_v_: runtimeService.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: safepoint.o; +text: .text%__1cFRInfo2t6M_v_: safepoint.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: safepoint_solaris_x86.o; +text: .text%__1cFRInfo2t6M_v_: safepoint_solaris_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: sharedHeap.o; +text: .text%__1cTAssertIsPermClosure2t6M_v_: sharedHeap.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: sharedRuntime.o; +text: .text%__1cFRInfo2t6M_v_: sharedRuntime.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: tenuredGeneration.o; +text: .text%__1cRCardTableModRefBSbCpar_chunk_heapword_alignment6F_I_: tenuredGeneration.o; +text: .text%__1cEMIN24CI_6FTA0_0_: tenuredGeneration.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: vframeArray.o; +text: .text%__1cFRInfo2t6M_v_: vframeArray.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: vmStructs.o; +text: .text%__1cFRInfo2t6M_v_: vmStructs.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: vm_version.o; +text: .text%__1cTAbstract_VM_VersionKvm_release6F_pkc_; +text: .text%__1cTAbstract_VM_VersionXinternal_vm_info_string6F_pkc_; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: vtableStubs_x86.o; +text: .text%__1cFRInfo2t6M_v_: vtableStubs_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIROptimizer_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_LIROptimizer_x86.o; +text: .text%JNI_CreateJavaVM; +text: .text%__1cCosVatomic_xchg_bootstrap6Fipoi_i_; +text: .text%__1cHThreadsJcreate_vm6FpnOJavaVMInitArgs_pi_i_; +text: .text%__1cHThreadsYis_supported_jni_version6Fi_C_; +text: .text%__1cMostream_init6F_v_; +text: .text%__1cMoutputStream2t6Mi_v_; +text: .text%__1cCosEinit6F_v_; +text: .text%__1cCosLinit_random6Fl_v_; +text: .text%__1cCosHSolarisWinitialize_system_info6F_v_; +text: .text%__1cOThreadCriticalKinitialize6F_v_; +text: .text%__1cCosMvm_page_size6F_i_; +text: .text%__1cJArgumentsWinit_system_properties6F_v_; +text: .text%__1cJArgumentsQPropertyList_add6FppnOSystemProperty_2_v_; +text: .text%__1cTAbstract_VM_VersionHvm_name6F_pkc_; +text: .text%__1cTAbstract_VM_VersionJvm_vendor6F_pkc_; +text: .text%__1cTAbstract_VM_VersionOvm_info_string6F_pkc_; +text: .text%__1cCosbDinit_system_properties_values6F_v_; +text: .text%__1cCosIjvm_path6Fpci_v_; +text: .text%__1cCosNset_boot_path6Fcc_i_; +text: .text%__1cJArgumentsFparse6FpknOJavaVMInitArgs__i_; +text: .text%__1cMmatch_option6FpknMJavaVMOption_pkcp4_i_: arguments.o; +text: .text%__1cJArgumentsVprocess_settings_file6Fpkcii_i_; +text: .text%__1cJArgumentsSparse_vm_init_args6FpknOJavaVMInitArgs__i_; +text: .text%__1cMSysClassPath2t6Mpkc_v_; +text: .text%__1cJArgumentsbSparse_java_tool_options_environment_variable6FpnMSysClassPath_pi_i_; +text: .text%__1cCosGgetenv6Fpkcpci_i_; +text: .text%__1cJArgumentsWparse_each_vm_init_arg6FpknOJavaVMInitArgs_pnMSysClassPath_pi_i_; +text: .text%__1cMmatch_option6FpknMJavaVMOption_ppkc5i_i_: arguments.o; +text: .text%__1cJArgumentsMadd_property6Fpkc_i_; +text: .text%__1cJArgumentsXPropertyList_unique_add6FppnOSystemProperty_pkcpc_v_; +text: .text%__1cCosEfree6Fpv_v_; +text: .text%__1cJArgumentsbNparse_java_options_environment_variable6FpnMSysClassPath_pi_i_; +text: .text%__1cJArgumentsVfinalize_vm_init_args6FpnMSysClassPath_i_i_; +text: .text%__1cMSysClassPathPexpand_endorsed6M_v_; +text: .text%__1cJArgumentsMget_property6Fpkc_2_; +text: .text%__1cJArgumentsWPropertyList_get_value6FpnOSystemProperty_pkc_4_; +text: .text%__1cMSysClassPathQadd_jars_to_path6Fpcpkc_1_; +text: .text%__1cJArgumentsZcheck_vm_args_consistency6F_i_; +text: .text%__1cJArgumentsRverify_percentage6FIpkc_i_; +text: .text%__1cMSysClassPath2T6M_v_; +text: .text%__1cMSysClassPathNreset_item_at6Mi_v_: arguments.o; +text: .text%__1cJArgumentsbOparse_java_compiler_environment_variable6F_v_; +text: .text%__1cJArgumentsVset_parallel_gc_flags6F_v_; +text: .text%__1cJArgumentsbBset_cms_and_parnew_gc_flags6F_v_; +text: .text%__1cJArgumentsTset_parnew_gc_flags6F_v_; +text: .text%__1cSCommandLineFlagsExKis_default6FnPCommandLineFlag__i_; +text: .text%__1cJArgumentsUset_ergonomics_flags6F_v_; +text: .text%__1cCosXis_server_class_machine6F_i_; +text: .text%__1cJTimeStampJupdate_to6Mx_v_; +text: .text%__1cCosOjavaTimeMillis6F_x_; +text: .text%__1cJTraceTime2t6MpkciipnMoutputStream__v_; +text: .text%__1cCosGinit_26F_i_; +text: .text%__1cCosHSolarisKmmap_chunk6FpcIii_2_; +text: .text%__1cCosXnon_memory_address_word6F_pc_; +text: .text%__1cCosHSolarisRmpss_sanity_check6F_v_; +text: .text%__1cCosHSolarisOset_mpss_range6FpcII_i_; +text: .text%__1cCosPuncommit_memory6FpcI_i_; +text: .text%__1cCosHSolarisOlibthread_init6F_v_; +text: .text%__1cOisT2_libthread6F_i_; +text: .text%__1cRlwp_priocntl_init6F_i_: os_solaris.o; +text: .text%__1cNpriocntl_stub6FinGidtype_lipc_l_: os_solaris.o; +text: .text%__1cOresolve_symbol6Fpkc_pC_: os_solaris.o; +text: .text%__1cCosHSolarisQsignal_sets_init6F_v_; +text: .text%__1cCosHSolarisOis_sig_ignored6Fi_i_; +text: .text%__1cCosHSolarisPinit_signal_mem6F_v_; +text: .text%__1cCosHSolarisXinstall_signal_handlers6F_v_; +text: .text%__1cCosHSolarisSset_signal_handler6Fiii_v_; +text: .text%__1cCosHSolarisUsynchronization_init6F_v_; +text: .text%__1cDhpiKinitialize6F_i_; +text: .text%__1cDhpiYinitialize_get_interface6FpnIvm_calls__v_; +text: .text%__1cQostream_init_log6F_v_; +text: .text%__1cNdefaultStreamMhas_log_file6M_i_; +text: .text%__1cRis_error_reported6F_i_; +text: .text%__1cNdefaultStreamEinit6M_v_; +text: .text%__1cSThreadLocalStorageEinit6F_v_; +text: .text%__1cSThreadLocalStorageHpd_init6F_v_; +text: .text%__1cCosbDallocate_thread_local_storage6F_i_; +text: .text%__1cSThreadLocalStoragebCgenerate_code_for_get_thread6F_v_; +text: .text%__1cRAllocateTLSOffset6F_v_: threadLS_solaris_x86.o; +text: .text%__1cPvm_init_globals6F_v_; +text: .text%__1cScheck_ThreadShadow6F_v_; +text: .text%__1cRcheck_basic_types6F_v_; +text: .text%__1cNeventlog_init6F_v_; +text: .text%__1cKmutex_init6F_v_; +text: .text%__1cFMutex2t6Mipkci_v_; +text: .text%lwp_cond_init: os_solaris.o; +text: .text%lwp_mutex_init: os_solaris.o; +text: .text%__1cHMonitor2t6Mipkci_v_; +text: .text%__1cOchunkpool_init6F_v_; +text: .text%__1cPperfMemory_init6F_v_; +text: .text%__1cKPerfMemoryKinitialize6F_v_; +text: .text%__1cCosZvm_allocation_granularity6F_i_; +text: .text%__1cKPerfMemoryUcreate_memory_region6FI_v_; +text: .text%__1cUcreate_shared_memory6FI_pc_: perfMemory_solaris.o; +text: .text%__1cSmmap_create_shared6FI_pc_: perfMemory_solaris.o; +text: .text%__1cCosScurrent_process_id6F_i_; +text: .text%__1cNget_user_name6Fl_pc_: perfMemory_solaris.o; +text: .text%__1cQget_user_tmp_dir6Fpkc_pc_: perfMemory_solaris.o; +text: .text%__1cCosSget_temp_directory6F_pkc_; +text: .text%__1cWget_sharedmem_filename6Fpkci_pc_: perfMemory_solaris.o; +text: .text%__1cbBcleanup_sharedmem_resources6Fpkc_v_: perfMemory_solaris.o; +text: .text%__1cTis_directory_secure6Fpkc_i_: perfMemory_solaris.o; +text: .text%lstat: perfMemory_solaris.o; +text: .text%__1cPfilename_to_pid6Fpkc_l_: perfMemory_solaris.o; +text: .text%__1cbAcreate_sharedmem_resources6Fpkc1I_i_: perfMemory_solaris.o; +text: .text%__1cRmake_user_tmp_dir6Fpkc_i_: perfMemory_solaris.o; +text: .text%__1cKJavaThread2t6M_v_; +text: .text%__1cGThread2t6M_v_; +text: .text%__1cFArena2t6M_v_; +text: .text%__1cFChunk2n6FII_pv_; +text: .text%__1cOThreadCritical2t6M_v_; +text: .text%__1cOThreadCritical2T6M_v_; +text: .text%__1cFChunk2t6MI_v_; +text: .text%__1cKHandleMarkKinitialize6MpnGThread__v_; +text: .text%__1cKJavaThreadKinitialize6M_v_; +text: .text%__1cNjni_functions6F_pknTJNINativeInterface___; +text: .text%__1cQThreadStatistics2t6M_v_; +text: .text%__1cGParker2t6M_v_; +text: .text%__1cWThreadLocalAllocBufferKinitialize6M_v_; +text: .text%__1cWThreadLocalAllocBufferKinitialize6MpnIHeapWord_22_v_; +text: .text%__1cWThreadLocalAllocBufferMinitial_size6F_I_; +text: .text%__1cWThreadLocalAllocBufferVinitialize_statistics6M_v_; +text: .text%__1cMFlatProfilerJis_active6F_i_; +text: .text%__1cUThreadSafepointStateGcreate6FpnKJavaThread__v_; +text: .text%__1cUThreadSafepointState2t6MpnKJavaThread__v_; +text: .text%__1cGThreadbArecord_stack_base_and_size6M_v_; +text: .text%__1cCosScurrent_stack_base6F_pC_; +text: .text%__1cCosScurrent_stack_size6F_I_; +text: .text%__1cGThreadbFinitialize_thread_local_storage6M_v_; +text: .text%__1cSThreadLocalStorageKset_thread6FpnGThread__v_; +text: .text%__1cSThreadLocalStorageNpd_set_thread6FpnGThread__v_; +text: .text%__1cCosbBthread_local_storage_at_put6Fipv_v_; +text: .text%__1cSThreadLocalStorageSset_thread_in_slot6FpnGThread__v_; +text: .text%get_thread; +text: .text%__1cSThreadLocalStoragebBget_thread_via_cache_slowly6FIi_pnGThread__; +text: .text%__1cSThreadLocalStoragePget_thread_slow6F_pnGThread__; +text: .text%__1cCosXthread_local_storage_at6Fi_pv_; +text: .text%__1cCosVcurrent_stack_pointer6F_pC_; +text: .text%__1cCosRinitialize_thread6F_v_; +text: .text%__1cNReservedSpaceUpage_align_size_down6FI_I_; +text: .text%__1cCosHSolarisVinit_thread_fpu_state6F_v_; +text: .text%__1cOJNIHandleBlockOallocate_block6FpnGThread__p0_; +text: .text%__1cFMutexbClock_without_safepoint_check6M_v_; +text: .text%__1cFMutexGunlock6M_v_; +text: .text%__1cGThreadWset_as_starting_thread6M_i_; +text: .text%__1cCosScreate_main_thread6FpnGThread__i_; +text: .text%__1cQcreate_os_thread6FpnGThread_I_pnIOSThread__: os_solaris.o; +text: .text%__1cIOSThread2t6MpFpv_i1_v_; +text: .text%__1cIOSThreadNpd_initialize6M_v_; +text: .text%__1cCosHSolarisPhotspot_sigmask6FpnGThread__v_; +text: .text%__1cCosHSolarisRunblocked_signals6F_pnIsigset_t__; +text: .text%__1cGThreadMis_VM_thread6kM_i_: thread.o; +text: .text%__1cCosHSolarisKvm_signals6F_pnIsigset_t__; +text: .text%__1cKJavaThreadYcreate_stack_guard_pages6M_v_; +text: .text%__1cCosNcommit_memory6FpcI_i_; +text: .text%__1cCosMguard_memory6FpcI_i_; +text: .text%__1cMinit_globals6F_i_; +text: .text%__1cPmanagement_init6F_v_; +text: .text%__1cKManagementEinit6F_v_; +text: .text%__1cNExceptionMark2t6MrpnGThread__v_; +text: .text%__1cPPerfDataManagerUcreate_long_variable6FnJCounterNS_pkcnIPerfDataFUnits_xpnGThread__pnQPerfLongVariable__; +text: .text%__1cIPerfLong2t6MnJCounterNS_pkcnIPerfDataFUnits_n0CLVariability__v_; +text: .text%__1cIPerfData2t6MnJCounterNS_pkcn0AFUnits_n0ALVariability__v_; +text: .text%__1cIPerfDataMcreate_entry6MnJBasicType_II_v_; +text: .text%__1cKPerfMemoryFalloc6FI_pc_; +text: .text%__1cFMutexElock6M_v_; +text: .text%__1cFMutexElock6MpnGThread__v_; +text: .text%__1cKPerfMemoryMmark_updated6F_v_; +text: .text%__1cCosLelapsedTime6F_d_; +text: .text%__1cMgetTimeNanos6F_x_: os_solaris.o; +text: .text%__1cPoldgetTimeNanos6F_x_: os_solaris.o; +text: .text%__1cPPerfDataManagerIadd_item6FpnIPerfData_i_v_; +text: .text%__1cMPerfDataList2t6Mi_v_; +text: .text%__1cCosbCis_thread_cpu_time_supported6F_i_; +text: .text%__1cNExceptionMark2T6M_v_; +text: .text%__1cNThreadServiceEinit6F_v_; +text: .text%__1cPPerfDataManagerTcreate_long_counter6FnJCounterNS_pkcnIPerfDataFUnits_xpnGThread__pnPPerfLongCounter__; +text: .text%__1cORuntimeServiceEinit6F_v_; +text: .text%__1cTClassLoadingServiceEinit6F_v_; +text: .text%__1cKvtune_init6F_v_; +text: .text%__1cObytecodes_init6F_v_; +text: .text%__1cJBytecodesKinitialize6F_v_; +text: .text%__1cJBytecodesDdef6Fn0AECode_pkc33nJBasicType_iii_v_; +text: .text%__1cJBytecodesDdef6Fn0AECode_pkc33nJBasicType_ii1i_v_; +text: .text%__1cJBytecodesNpd_initialize6F_v_; +text: .text%__1cQclassLoader_init6F_v_; +text: .text%__1cLClassLoaderKinitialize6F_v_; +text: .text%__1cLClassLoaderQload_zip_library6F_v_; +text: .text%__1cCosTnative_java_library6F_pv_; +text: .text%JVM_GetInterfaceVersion; +text: .text%__1cHThreadsbMis_supported_jni_version_including_1_16Fi_C_; +text: .text%__1cKHandleMark2T6M_v_; +text: .text%__1cLClassLoaderbBsetup_bootstrap_search_path6F_v_; +text: .text%__1cCosGstrdup6Fpkc_pc_; +text: .text%__1cLClassLoaderbCupdate_class_path_entry_list6Fpkc_v_; +text: .text%__1cCosEstat6FpkcpnEstat__i_; +text: .text%stat: os_solaris.o; +text: .text%__1cLClassLoaderXcreate_class_path_entry6FpcnEstat_ppnOClassPathEntry__v_; +text: .text%__1cLClassLoaderSget_canonical_path6Fpc1i_i_; +text: .text%JVM_RawMonitorCreate; +text: .text%JVM_NativePath; +text: .text%JVM_RawMonitorEnter; +text: .text%__1cFMutexMjvm_raw_lock6M_v_; +text: .text%JVM_RawMonitorExit; +text: .text%__1cFMutexOjvm_raw_unlock6M_v_; +text: .text%JVM_Open; +text: .text%JVM_Lseek; +text: .text%JVM_Close; +text: .text%__1cDhpiFclose6Fi_i_: jvm.o; +text: .text%__1cRClassPathZipEntry2t6Mppvpc_v_; +text: .text%__1cOClassPathEntry2t6M_v_; +text: .text%__1cLClassLoaderLadd_to_list6FpnOClassPathEntry__v_; +text: .text%__1cOcodeCache_init6F_v_; +text: .text%__1cJCodeCacheKinitialize6F_v_; +text: .text%__1cICodeHeapHreserve6MIII_i_; +text: .text%__1cLlog2_intptr6Fi_i_: heap.o; +text: .text%__1cYalign_to_allocation_size6FI_I_: heap.o; +text: .text%__1cNReservedSpace2t6MI_v_; +text: .text%__1cNReservedSpaceKinitialize6MIIipc_v_; +text: .text%__1cCosOreserve_memory6FIpc_1_; +text: .text%__1cMVirtualSpaceKinitialize6MnNReservedSpace_I_i_; +text: .text%__1cMVirtualSpaceJexpand_by6MI_i_; +text: .text%__1cMVirtualSpaceQuncommitted_size6kM_I_; +text: .text%__1cMVirtualSpaceNreserved_size6kM_I_; +text: .text%__1cMVirtualSpaceOcommitted_size6kM_I_; +text: .text%__1cCosNcommit_memory6FpcII_i_; +text: .text%__1cSalign_to_page_size6FI_I_: heap.o; +text: .text%__1cICodeHeapFclear6M_v_; +text: .text%__1cICodeHeapTmark_segmap_as_free6MII_v_; +text: .text%__1cNMemoryServiceZadd_code_heap_memory_pool6FpnICodeHeap__v_; +text: .text%__1cMCodeHeapPool2t6MpnICodeHeap_pkci_v_; +text: .text%__1cICodeHeapIcapacity6kM_I_; +text: .text%__1cICodeHeapMmax_capacity6kM_I_; +text: .text%__1cKMemoryPool2t6Mpkcn0AIPoolType_IIii_v_; +text: .text%__1cNMemoryManagerbDget_code_cache_memory_manager6F_p0_; +text: .text%__1cNMemoryManager2t6M_v_; +text: .text%__1cNMemoryManagerIadd_pool6MpnKMemoryPool__v_; +text: .text%__1cKMemoryPoolLadd_manager6MpnNMemoryManager__v_; +text: .text%__1cLicache_init6F_v_; +text: .text%__1cPVM_Version_init6F_v_; +text: .text%__1cKVM_VersionKinitialize6F_v_; +text: .text%__1cKBufferBlobGcreate6Fpkci_p0_; +text: .text%__1cKJavaThreadOis_Java_thread6kM_i_: thread.o; +text: .text%__1cRalign_code_offset6Fi_I_; +text: .text%__1cICodeHeapLheader_size6F_I_; +text: .text%__1cKBufferBlob2n6FII_pv_; +text: .text%__1cJCodeCacheIallocate6Fi_pnICodeBlob__; +text: .text%__1cICodeHeapIallocate6MI_pv_; +text: .text%__1cICodeHeapPsearch_freelist6MI_pnJFreeBlock__; +text: .text%__1cICodeHeapTmark_segmap_as_used6MII_v_; +text: .text%__1cKBufferBlob2t6Mpkci_v_; +text: .text%__1cICodeBlob2t6Mpkcii_v_; +text: .text%__1cICodeBlobMset_oop_maps6MpnJOopMapSet__v_; +text: .text%__1cNMemoryServiceXtrack_memory_pool_usage6FpnKMemoryPool__v_; +text: .text%__1cKMemoryPoolYrecord_peak_memory_usage6M_v_; +text: .text%__1cMCodeHeapPoolQget_memory_usage6M_nLMemoryUsage__; +text: .text%__1cMCodeHeapPoolNused_in_bytes6M_I_: memoryPool.o; +text: .text%__1cICodeHeapSallocated_capacity6kM_I_; +text: .text%__1cKMemoryPoolImax_size6kM_I_: memoryPool.o; +text: .text%__1cXresource_allocate_bytes6FI_pc_; +text: .text%__1cKCodeBuffer2t6MpCi_v_; +text: .text%__1cRAbstractAssembler2t6MpnKCodeBuffer__v_; +text: .text%__1cYVM_Version_StubGeneratorTgenerate_getPsrInfo6M_pC_: vm_version_x86.o; +text: .text%__1cMStubCodeMark2t6MpnRStubCodeGenerator_pkc4_v_; +text: .text%__1cRStubCodeGeneratorLstub_prolog6MpnMStubCodeDesc__v_; +text: .text%__1cJAssemblerFpushl6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerEmovl6MpnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerGpushfd6M_v_; +text: .text%__1cJAssemblerEpopl6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerExorl6MpnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerKemit_arith6MiipnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerExorl6MpnMRegisterImpl_i_v_; +text: .text%__1cJAssemblerKemit_arith6MiipnMRegisterImpl_i_v_; +text: .text%__1cJAssemblerFpopfd6M_v_; +text: .text%__1cJAssemblerEcmpl6MpnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerDjcc6Mn0AJCondition_rnFLabel_nJrelocInfoJrelocType__v_; +text: .text%__1cJAssemblerFcpuid6M_v_; +text: .text%__1cJAssemblerDorl6MpnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerEmovl6MpnMRegisterImpl_i_v_; +text: .text%__1cJAssemblerDjmp6MrnFLabel_nJrelocInfoJrelocType__v_; +text: .text%__1cRAbstractAssemblerEbind6MrnFLabel__v_; +text: .text%__1cRAbstractAssemblerHbind_to6MrnFLabel_i_v_; +text: .text%__1cMDisplacementEbind6MrnFLabel_ipnRAbstractAssembler__v_; +text: .text%__1cJAssemblerEmovl6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cJAssemblerMemit_operand6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cJAssemblerMemit_operand6MpnMRegisterImpl_22nHAddressLScaleFactor_irknQRelocationHolder__v_; +text: .text%__1cKRelocationEtype6M_nJrelocInfoJrelocType__: relocInfo.o; +text: .text%__1cJAssemblerEmovl6MnHAddress_pnMRegisterImpl__v_; +text: .text%__1cJAssemblerDret6Mi_v_; +text: .text%__1cMStubCodeMark2T6M_v_; +text: .text%__1cRAbstractAssemblerFflush6M_v_; +text: .text%__1cRStubCodeGeneratorLstub_epilog6MpnMStubCodeDesc__v_; +text: .text%__1cFVTuneNregister_stub6FpkcpC3_v_; +text: .text%__1cFForteNregister_stub6FpkcpC3_v_; +text: .text%__1cKVM_VersionWget_processor_features6F_v_; +text: .text%__1cCosMsupports_sse6F_i_; +text: .text%__1cVcheck_for_sse_support6F_v_: os_solaris_x86.o; +text: .text%jio_snprintf; +text: .text%jio_vsnprintf; +text: .text%__1cPlocal_vsnprintf6FpcIpkcpv_i_; +text: .text%__1cSstubRoutines_init16F_v_; +text: .text%__1cMStubRoutinesLinitialize16F_v_; +text: .text%__1cWStubGenerator_generate6FpnKCodeBuffer_i_v_; +text: .text%__1cNStubGeneratorbAgenerate_forward_exception6M_pC_: stubGenerator_x86.o; +text: .text%__1cOMacroAssemblerMcall_VM_leaf6MpCpnMRegisterImpl__v_; +text: .text%__1cOMacroAssemblerMcall_VM_leaf6MpCi_v_; +text: .text%__1cOMacroAssemblerRcall_VM_leaf_base6MpCi_v_; +text: .text%__1cJAssemblerEcall6MpCnJrelocInfoJrelocType__v_; +text: .text%__1cJAssemblerJemit_data6MinJrelocInfoJrelocType_i_v_; +text: .text%__1cKRelocationLspec_simple6FnJrelocInfoJrelocType__nQRelocationHolder__; +text: .text%__1cPBoundRelocationLunpack_data6MnJrelocInfoJrelocType__v_: relocInfo.o; +text: .text%__1cKRelocationLunpack_data6M_v_: codeBlob.o; +text: .text%__1cJAssemblerJemit_data6MirknQRelocationHolder_i_v_; +text: .text%__1cKCodeBufferIrelocate6MpCrknQRelocationHolder_i_v_; +text: .text%__1cXruntime_call_RelocationEtype6M_nJrelocInfoJrelocType__: codeBlob.o; +text: .text%__1cOMacroAssemblerJincrement6MpnMRegisterImpl_i_v_; +text: .text%__1cJAssemblerEaddl6MpnMRegisterImpl_i_v_; +text: .text%__1cOMacroAssemblerKget_thread6MpnMRegisterImpl__v_; +text: .text%__1cSThreadLocalStorageTpd_getTlsAccessMode6F_n0AQpd_tlsAccessMode__; +text: .text%__1cJAssemblerFpushl6Mi_v_; +text: .text%__1cJAssemblerEleal6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cJAssemblerEmovl6MnHAddress_i_v_; +text: .text%__1cOMacroAssemblerKverify_oop6MpnMRegisterImpl_pkc_v_; +text: .text%__1cJAssemblerDjmp6MpnMRegisterImpl_nJrelocInfoJrelocType__v_; +text: .text%__1cNStubGeneratorSgenerate_call_stub6MrpC_1_: stubGenerator_x86.o; +text: .text%__1cOMacroAssemblerFenter6M_v_; +text: .text%__1cJAssemblerEsubl6MpnMRegisterImpl_i_v_; +text: .text%__1cJAssemblerFtestl6MpnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerEdecl6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerEcall6MpnMRegisterImpl_nJrelocInfoJrelocType__v_; +text: .text%__1cJAssemblerEcmpl6MpnMRegisterImpl_i_v_; +text: .text%__1cJAssemblerGfstp_s6MnHAddress__v_; +text: .text%__1cJAssemblerGfstp_d6MnHAddress__v_; +text: .text%__1cNStubGeneratorYgenerate_catch_exception6M_pC_: stubGenerator_x86.o; +text: .text%__1cJAssemblerDjmp6MpCnJrelocInfoJrelocType__v_; +text: .text%__1cNStubGeneratorUgenerate_atomic_xchg6M_pC_: stubGenerator_x86.o; +text: .text%__1cJAssemblerExchg6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cJAssemblerGpushad6M_v_; +text: .text%__1cJAssemblerFpopad6M_v_; +text: .text%__1cNStubGeneratorYgenerate_get_previous_fp6M_pC_: stubGenerator_x86.o; +text: .text%__1cNStubGeneratorUgenerate_d2i_wrapper6MpC_1_: stubGenerator_x86.o; +text: .text%__1cOMacroAssemblerOpush_FPU_state6M_v_; +text: .text%__1cJAssemblerGfnsave6MnHAddress__v_; +text: .text%__1cJAssemblerFfwait6M_v_; +text: .text%__1cJAssemblerFfld_d6MnHAddress__v_; +text: .text%__1cJAssemblerFfst_d6MnHAddress__v_; +text: .text%__1cOMacroAssemblerPempty_FPU_stack6M_v_; +text: .text%__1cJAssemblerFffree6Mi_v_; +text: .text%__1cJAssemblerLemit_farith6Miii_v_; +text: .text%__1cOMacroAssemblerNpop_FPU_state6M_v_; +text: .text%__1cJAssemblerGfrstor6MnHAddress__v_; +text: .text%__1cNStubGeneratorUcreate_control_words6M_v_: stubGenerator_x86.o; +text: .text%__1cJTraceTime2T6M_v_; +text: .text%__1cNcarSpace_init6F_v_; +text: .text%__1cICarSpaceEinit6F_v_; +text: .text%__1cNuniverse_init6F_i_; +text: .text%__1cLJavaClassesbAcompute_hard_coded_offsets6F_v_; +text: .text%__1cLFileMapInfoKinitialize6M_i_; +text: .text%__1cLFileMapInfoNfail_continue6MpkcE_v_; +text: .text%__1cLFileMapInfoFclose6M_v_; +text: .text%__1cIUniversePinitialize_heap6F_i_; +text: .text%__1cPMarkSweepPolicy2t6M_v_; +text: .text%__1cbCTwoGenerationCollectorPolicyQinitialize_flags6M_v_; +text: .text%__1cbCTwoGenerationCollectorPolicyMrem_set_name6M_nJGenRemSetEName__: collectorPolicy.o; +text: .text%__1cJGenRemSetYmax_alignment_constraint6Fn0AEName__I_; +text: .text%__1cRCardTableModRefBSbBct_max_alignment_constraint6F_I_; +text: .text%__1cbCTwoGenerationCollectorPolicyUinitialize_size_info6M_v_; +text: .text%__1cPMarkSweepPolicyWinitialize_generations6M_v_; +text: .text%__1cbCTwoGenerationCollectorPolicyVnumber_of_generations6M_i_: collectorPolicy.o; +text: .text%__1cXPermanentGenerationSpec2t6MnHPermGenEName_IIIIII_v_; +text: .text%__1cQGCPolicyCounters2t6Mpkcii_v_; +text: .text%__1cPPerfDataManagerMcounter_name6Fpkc2_pc_; +text: .text%__1cPPerfDataManagerWcreate_string_constant6FnJCounterNS_pkc3pnGThread__pnSPerfStringConstant__; +text: .text%__1cSPerfStringConstant2t6MnJCounterNS_pkc3_v_; +text: .text%__1cNPerfByteArray2t6MnJCounterNS_pkcnIPerfDataFUnits_n0CLVariability_i_v_; +text: .text%__1cKPerfStringKset_string6Mpkc_v_; +text: .text%__1cPPerfDataManagerUcreate_long_constant6FnJCounterNS_pkcnIPerfDataFUnits_xpnGThread__pnQPerfLongConstant__; +text: .text%__1cQGenCollectedHeap2t6MpnPCollectorPolicy__v_; +text: .text%__1cKSharedHeap2t6MpnPCollectorPolicy__v_; +text: .text%__1cNCollectedHeap2t6M_v_; +text: .text%__1cHGCCauseJto_string6Fn0AFCause__pkc_; +text: .text%__1cPPerfDataManagerWcreate_string_variable6FnJCounterNS_pkci3pnGThread__pnSPerfStringVariable__; +text: .text%__1cMSubTasksDone2t6Mi_v_; +text: .text%__1cMSubTasksDoneFclear6M_v_; +text: .text%__1cMSubTasksDoneFvalid6M_i_; +text: .text%__1cQGenCollectedHeapKinitialize6M_i_; +text: .text%__1cPCollectorPolicyLgenerations6M_ppnOGenerationSpec__: collectorPolicy.o; +text: .text%__1cPCollectorPolicyUpermanent_generation6M_pnXPermanentGenerationSpec__: collectorPolicy.o; +text: .text%__1cXPermanentGenerationSpecFalign6MI_v_; +text: .text%__1cQGenCollectedHeapIallocate6MIpnXPermanentGenerationSpec_pIpipnNReservedSpace__pc_; +text: .text%__1cOGenerationSpecRn_covered_regions6kM_i_: collectorPolicy.o; +text: .text%__1cNReservedSpace2t6MIIipc_v_; +text: .text%__1cPCollectorPolicyOcreate_rem_set6MnJMemRegion_i_pnJGenRemSet__; +text: .text%__1cbCTwoGenerationCollectorPolicyQbarrier_set_name6M_nKBarrierSetEName__: collectorPolicy.o; +text: .text%__1cLCardTableRS2t6MnJMemRegion_i_v_; +text: .text%__1cRCardTableModRefBS2t6MnJMemRegion_i_v_; +text: .text%__1cNReservedSpaceYallocation_align_size_up6FI_I_; +text: .text%__1cJMemRegion2t6M_v_: cardTableModRefBS.o; +text: .text%__1cKSharedHeapPset_barrier_set6MpnKBarrierSet__v_; +text: .text%__1cNReservedSpaceKfirst_part6MIii_0_; +text: .text%__1cNReservedSpace2t6MpcI_v_; +text: .text%__1cOGenerationSpecEinit6MnNReservedSpace_ipnJGenRemSet__pnKGeneration__; +text: .text%__1cQDefNewGeneration2t6MnNReservedSpace_Iipkc_v_; +text: .text%__1cKGeneration2t6MnNReservedSpace_Ii_v_; +text: .text%__1cIageTable2t6Mi_v_; +text: .text%__1cIageTableFclear6M_v_; +text: .text%__1cFArenaEgrow6MI_pv_; +text: .text%__1cFChunkJnext_chop6M_v_; +text: .text%__1cFChunkEchop6M_v_; +text: .text%__1cFChunk2k6Fpv_v_; +text: .text%__1cRCardTableModRefBSVresize_covered_region6MnJMemRegion__v_; +text: .text%__1cRCardTableModRefBSbCfind_covering_region_by_base6MpnIHeapWord__i_; +text: .text%__1cRCardTableModRefBSbAlargest_prev_committed_end6kMi_pnIHeapWord__; +text: .text%__1cWSequentialSubTasksDoneFclear6M_v_; +text: .text%__1cSGenerationCounters2t6MpkciipnMVirtualSpace__v_; +text: .text%__1cPPerfDataManagerKname_space6Fpkci_pc_; +text: .text%__1cRCollectorCounters2t6Mpkci_v_; +text: .text%__1cOCSpaceCounters2t6MpkciIpnPContiguousSpace_pnSGenerationCounters__v_; +text: .text%__1cPPerfDataManagerKname_space6Fpkc2i_pc_; +text: .text%__1cPPerfDataManagerUcreate_long_variable6FnJCounterNS_pkcnIPerfDataFUnits_pnUPerfLongSampleHelper_pnGThread__pnQPerfLongVariable__; +text: .text%__1cPPerfLongVariant2t6MnJCounterNS_pkcnIPerfDataFUnits_n0CLVariability_pnUPerfLongSampleHelper__v_; +text: .text%__1cPPerfLongVariantGsample6M_v_; +text: .text%__1cZContiguousSpaceUsedHelperLtake_sample6M_x_: cSpaceCounters.o; +text: .text%__1cPContiguousSpaceEused6kM_I_: space.o; +text: .text%__1cQDefNewGenerationYcompute_space_boundaries6MI_v_; +text: .text%__1cQCompactibleSpaceKinitialize6MnJMemRegion_i_v_; +text: .text%__1cFSpaceKinitialize6MnJMemRegion_i_v_; +text: .text%__1cFSpaceKset_bottom6MpnIHeapWord__v_: space.o; +text: .text%__1cJEdenSpaceHset_end6MpnIHeapWord__v_: space.o; +text: .text%__1cJEdenSpaceFclear6M_v_; +text: .text%__1cPContiguousSpaceFclear6M_v_; +text: .text%__1cFSpaceFclear6M_v_; +text: .text%__1cFSpaceHset_end6MpnIHeapWord__v_: space.o; +text: .text%__1cQDefNewGenerationPupdate_counters6M_v_; +text: .text%__1cSGenerationCountersKupdate_all6M_v_: generationCounters.o; +text: .text%__1cNReservedSpaceJlast_part6MI_0_; +text: .text%__1cRTenuredGeneration2t6MnNReservedSpace_IipnJGenRemSet__v_; +text: .text%__1cOCardGeneration2t6MnNReservedSpace_IipnJGenRemSet__v_; +text: .text%__1cWBlockOffsetSharedArray2t6MnJMemRegion_I_v_; +text: .text%__1cWBlockOffsetSharedArrayGresize6MI_v_; +text: .text%__1cNReservedSpaceSpage_align_size_up6FI_I_; +text: .text%__1cLCardTableRSVresize_covered_region6MnJMemRegion__v_; +text: .text%__1cLCardTableRSKis_aligned6MpnIHeapWord__i_: cardTableRS.o; +text: .text%__1cHGCStats2t6M_v_; +text: .text%__1cWOffsetTableContigSpace2t6MpnWBlockOffsetSharedArray_nJMemRegion__v_; +text: .text%__1cQBlockOffsetArray2t6MpnWBlockOffsetSharedArray_nJMemRegion_i_v_; +text: .text%__1cWOffsetTableContigSpaceKset_bottom6MpnIHeapWord__v_; +text: .text%__1cQBlockOffsetArrayGresize6MI_v_: blockOffsetTable.o; +text: .text%__1cWOffsetTableContigSpaceHset_end6MpnIHeapWord__v_; +text: .text%__1cWOffsetTableContigSpaceFclear6M_v_; +text: .text%__1cbBBlockOffsetArrayContigSpaceUinitialize_threshold6M_pnIHeapWord__; +text: .text%__1cUGenericGrowableArrayEgrow6Mi_v_; +text: .text%__1cXPermanentGenerationSpecEinit6MnNReservedSpace_IpnJGenRemSet__pnHPermGen__; +text: .text%__1cRCompactingPermGen2t6MnNReservedSpace_1IpnJGenRemSet_pnXPermanentGenerationSpec__v_; +text: .text%__1cUCompactingPermGenGen2t6MnNReservedSpace_1IipnJGenRemSet_pnPContiguousSpace_pnXPermanentGenerationSpec__v_; +text: .text%__1cUCompactingPermGenGenbFinitialize_performance_counters6M_v_; +text: .text%__1cbCOneContigSpaceCardGenerationIcapacity6kM_I_; +text: .text%__1cPCollectorPolicybFis_concurrent_mark_sweep_policy6M_i_: collectorPolicy.o; +text: .text%__1cWThreadLocalAllocBufferWstartup_initialization6F_v_; +text: .text%__1cPGlobalTLABStats2t6M_v_; +text: .text%__1cPGlobalTLABStatsKinitialize6M_v_; +text: .text%__1cXAdaptiveWeightedAverageGsample6Mf_v_; +text: .text%__1cXAdaptiveWeightedAverageYcompute_adaptive_average6Mff_f_; +text: .text%__1cQGenCollectedHeapNtlab_capacity6kM_I_; +text: .text%__1cQDefNewGenerationYsupports_tlab_allocation6kM_i_: defNewGeneration.o; +text: .text%__1cQDefNewGenerationNtlab_capacity6kM_I_: defNewGeneration.o; +text: .text%__1cKGenerationYsupports_tlab_allocation6kM_i_: tenuredGeneration.o; +text: .text%__1cWThreadLocalAllocBufferImax_size6F_I_; +text: .text%__1cOBasicHashtable2t6Mii_v_: universe.o; +text: .text%__1cLClassLoaderZcreate_package_info_table6F_v_; +text: .text%__1cOBasicHashtable2t6Mii_v_: classLoader.o; +text: .text%__1cQinterpreter_init6F_v_; +text: .text%__1cTAbstractInterpreterKinitialize6F_v_; +text: .text%__1cNTemplateTableKinitialize6F_v_; +text: .text%__1cNTemplateTableDdef6FnJBytecodesECode_inITosState_3pF_vc_v_; +text: .text%__1cNTemplateTableDdef6FnJBytecodesECode_inITosState_3pFi_vi_v_; +text: .text%__1cITemplateKinitialize6MinITosState_1pFi_vi_v_; +text: .text%__1cNTemplateTableDdef6FnJBytecodesECode_inITosState_3pFn0AJOperation__v4_v_; +text: .text%__1cNTemplateTableDdef6FnJBytecodesECode_inITosState_3pFn0AJCondition__v4_v_; +text: .text%__1cNTemplateTableDdef6FnJBytecodesECode_inITosState_3pF3_v3_v_; +text: .text%__1cNTemplateTableNpd_initialize6F_v_; +text: .text%__1cRInvocationCounterMreinitialize6Fi_v_; +text: .text%__1cRInvocationCounterDdef6Fn0AFState_ipFnMmethodHandle_pnGThread__pC_v_; +text: .text%__1cJStubQdDueue2t6MpnNStubInterface_ipnFMutex_pkc_v_; +text: .text%__1cICodeHeapJexpand_by6MI_i_; +text: .text%__1cJStubQdDueueOregister_queue6Fp0_v_; +text: .text%__1cUInterpreterGenerator2t6MpnJStubQdDueue__v_; +text: .text%__1cbCAbstractInterpreterGenerator2t6MpnJStubQdDueue__v_; +text: .text%__1cbCAbstractInterpreterGeneratorMgenerate_all6M_v_; +text: .text%__1cLCodeletMark2t6MrpnZInterpreterMacroAssembler_pkcinJBytecodesECode__v_: interpreter.o; +text: .text%__1cJStubQdDueueHrequest6Mi_pnEStub__; +text: .text%__1cbBInterpreterCodeletInterfaceRcode_size_to_size6kMi_i_: interpreter.o; +text: .text%__1cbBInterpreterCodeletInterfaceKinitialize6MpnEStub_i_v_: interpreter.o; +text: .text%__1cSInterpreterCodeletKinitialize6MpkcinJBytecodesECode__v_; +text: .text%__1cbCAbstractInterpreterGeneratorTgenerate_error_exit6Mpkc_pC_; +text: .text%__1cOMacroAssemblerEstop6Mpkc_v_; +text: .text%__1cJAssemblerEcall6MrnFLabel_nJrelocInfoJrelocType__v_; +text: .text%__1cJAssemblerDhlt6M_v_; +text: .text%__1cOMacroAssemblerFalign6Mi_v_; +text: .text%__1cJAssemblerDnop6M_v_; +text: .text%__1cJStubQdDueueGcommit6Mi_v_; +text: .text%__1cbCAbstractInterpreterGeneratorZgenerate_return_entry_for6MnITosState_i_pC_; +text: .text%__1cZInterpreterMacroAssemblerbAget_cache_and_index_at_bcp6MpnMRegisterImpl_2i_v_; +text: .text%__1cOMacroAssemblerSload_unsigned_word6MpnMRegisterImpl_nHAddress__i_; +text: .text%__1cJAssemblerGmovzxw6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cJAssemblerEshll6MpnMRegisterImpl_i_v_; +text: .text%__1cJAssemblerEandl6MpnMRegisterImpl_i_v_; +text: .text%__1cZInterpreterMacroAssemblerNdispatch_next6MnITosState_i_v_; +text: .text%__1cOMacroAssemblerSload_unsigned_byte6MpnMRegisterImpl_nHAddress__i_; +text: .text%__1cJAssemblerGmovzxb6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cZInterpreterMacroAssemblerNdispatch_base6MnITosState_ppCi_v_; +text: .text%__1cZInterpreterMacroAssemblerKverify_FPU6MinITosState__v_; +text: .text%__1cZInterpreterMacroAssemblerKverify_oop6MpnMRegisterImpl_nITosState__v_; +text: .text%__1cJAssemblerDjmp6MnHAddress__v_; +text: .text%__1cOMacroAssemblerKverify_FPU6Mipkc_v_; +text: .text%__1cKEntryPoint2t6MpC11111111_v_; +text: .text%__1cJAssemblerEincl6MpnMRegisterImpl__v_; +text: .text%__1cbCAbstractInterpreterGeneratorYgenerate_deopt_entry_for6MnITosState_i_pC_; +text: .text%__1cJAssemblerEcmpl6MnHAddress_i_v_; +text: .text%__1cOMacroAssemblerHcall_VM6MpnMRegisterImpl_pCi_v_; +text: .text%__1cOMacroAssemblerOcall_VM_helper6MpnMRegisterImpl_pCii_v_; +text: .text%__1cZInterpreterMacroAssemblerMcall_VM_base6MpnMRegisterImpl_22pCii_v_; +text: .text%__1cOMacroAssemblerMcall_VM_base6MpnMRegisterImpl_22pCii_v_; +text: .text%__1cZInterpreterMacroAssemblerZcheck_and_handle_popframe6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerDjcc6Mn0AJCondition_pCnJrelocInfoJrelocType__v_; +text: .text%__1cTAbstractInterpreterSBasicType_as_index6FnJBasicType__i_; +text: .text%__1cbCAbstractInterpreterGeneratorbBgenerate_result_handler_for6MnJBasicType__pC_; +text: .text%__1cOMacroAssemblerGc2bool6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerEsetb6Mn0AJCondition_pnMRegisterImpl__v_; +text: .text%__1cOMacroAssemblerQsign_extend_byte6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerGmovsxb6MpnMRegisterImpl_2_v_; +text: .text%__1cOMacroAssemblerRsign_extend_short6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerGmovsxw6MpnMRegisterImpl_2_v_; +text: .text%__1cSInterpreterRuntimeZSignatureHandlerGeneratorEtemp6F_pnMRegisterImpl__; +text: .text%__1cZInterpreterMacroAssemblerDpop6MnITosState__v_; +text: .text%__1cbCAbstractInterpreterGeneratorbFgenerate_slow_signature_handler6M_pC_; +text: .text%__1cOMacroAssemblerHcall_VM6MpnMRegisterImpl_pC222i_v_; +text: .text%__1cTAbstractInterpreterRTosState_as_index6FnITosState__i_; +text: .text%__1cTAbstractInterpreterMreturn_entry6FnITosState_i_pC_; +text: .text%__1cKEntryPointFentry6kMnITosState__pC_; +text: .text%__1cbCAbstractInterpreterGeneratorZgenerate_continuation_for6MnITosState__pC_; +text: .text%__1cbCAbstractInterpreterGeneratorZgenerate_safept_entry_for6MnITosState_pC_2_; +text: .text%__1cZInterpreterMacroAssemblerEpush6MnITosState__v_; +text: .text%__1cZInterpreterMacroAssemblerMdispatch_via6MnITosState_ppC_v_; +text: .text%__1cbCAbstractInterpreterGeneratorYgenerate_throw_exception6M_v_; +text: .text%__1cOMacroAssemblerHcall_VM6MpnMRegisterImpl_pC2i_v_; +text: .text%__1cJAssemblerDorl6MpnMRegisterImpl_i_v_; +text: .text%__1cZInterpreterMacroAssemblerSsuper_call_VM_leaf6MpCpnMRegisterImpl__v_; +text: .text%__1cJAssemblerEsubl6MpnMRegisterImpl_2_v_; +text: .text%__1cZInterpreterMacroAssemblerSsuper_call_VM_leaf6MpCpnMRegisterImpl_33_v_; +text: .text%__1cZInterpreterMacroAssemblerRremove_activation6MnITosState_pnMRegisterImpl_iii_v_; +text: .text%__1cJAssemblerFtestl6MpnMRegisterImpl_i_v_; +text: .text%__1cZInterpreterMacroAssemblerNunlock_object6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerElock6M_v_; +text: .text%__1cJAssemblerHcmpxchg6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cHAddress2t6MinJrelocInfoJrelocType__v_; +text: .text%__1cOMacroAssemblerFleave6M_v_; +text: .text%__1cbCAbstractInterpreterGeneratorbMgenerate_ArrayIndexOutOfBounds_handler6Mpkc_pC_; +text: .text%__1cOMacroAssemblerHcall_VM6MpnMRegisterImpl_pC22i_v_; +text: .text%__1cbCAbstractInterpreterGeneratorbHgenerate_exception_handler_common6Mpkc2i_pC_; +text: .text%__1cbCAbstractInterpreterGeneratorbJgenerate_StackOverflowError_handler6M_pC_; +text: .text%__1cbCAbstractInterpreterGeneratorVgenerate_method_entry6MnTAbstractInterpreterKMethodKind__pC_; +text: .text%__1cUInterpreterGeneratorbEgenerate_asm_interpreter_entry6Mi_pC_; +text: .text%__1cUInterpreterGeneratorXcheck_for_compiled_code6MrnFLabel__v_; +text: .text%__1cUInterpreterGeneratorbDgenerate_stack_overflow_check6M_v_; +text: .text%__1cJAssemblerEaddl6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cJAssemblerEsubl6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cUInterpreterGeneratorUgenerate_fixed_frame6Mi_v_; +text: .text%__1cUInterpreterGeneratorVgenerate_counter_incr6MpnFLabel_22_v_; +text: .text%__1cJAssemblerEaddl6MpnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerEcmpl6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cbCAbstractInterpreterGeneratorXbang_stack_shadow_pages6Mi_v_; +text: .text%__1cOMacroAssemblerWbang_stack_with_offset6Mi_v_: interp_masm_x86.o; +text: .text%__1cZInterpreterMacroAssemblerTnotify_method_entry6M_v_; +text: .text%__1cUInterpreterGeneratorZgenerate_counter_overflow6MpC_v_; +text: .text%__1cJAssemblerEnegl6MpnMRegisterImpl__v_; +text: .text%__1cUInterpreterGeneratorbAgenerate_run_compiled_code6M_v_; +text: .text%__1cZInterpreterMacroAssemblerNsuper_call_VM6MpnMRegisterImpl_2pC22_v_; +text: .text%__1cUInterpreterGeneratorLlock_method6M_v_; +text: .text%__1cZInterpreterMacroAssemblerLlock_object6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerDorl6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cUInterpreterGeneratorUgenerate_empty_entry6M_pC_; +text: .text%__1cUInterpreterGeneratorXgenerate_accessor_entry6M_pC_; +text: .text%__1cJAssemblerEshrl6MpnMRegisterImpl_i_v_; +text: .text%__1cLlog2_intptr6Fi_i_: interpreter_x86.o; +text: .text%__1cOMacroAssemblerQload_signed_byte6MpnMRegisterImpl_nHAddress__i_; +text: .text%__1cJAssemblerGmovsxb6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cOMacroAssemblerQload_signed_word6MpnMRegisterImpl_nHAddress__i_; +text: .text%__1cJAssemblerGmovsxw6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cUInterpreterGeneratorXgenerate_abstract_entry6M_pC_; +text: .text%__1cUInterpreterGeneratorTgenerate_math_entry6MnTAbstractInterpreterKMethodKind__pC_; +text: .text%__1cOMacroAssemblerGsincos6Miii_v_; +text: .text%__1cJAssemblerFfld_s6Mi_v_; +text: .text%__1cJAssemblerEfabs6M_v_; +text: .text%__1cOMacroAssemblerEfcmp6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerHfucomip6Mi_v_; +text: .text%__1cOMacroAssemblerEfpop6M_v_; +text: .text%__1cJAssemblerHfincstp6M_v_; +text: .text%__1cJAssemblerEfsin6M_v_; +text: .text%__1cJAssemblerEfcos6M_v_; +text: .text%__1cJAssemblerFfsqrt6M_v_; +text: .text%__1cUInterpreterGeneratorVgenerate_native_entry6Mi_pC_; +text: .text%__1cNSharedRuntimebWnative_method_throw_unsatisfied_link_error_entry6F_pC_; +text: .text%__1cJAssemblerGmembar6M_v_; +text: .text%__1cJAssemblerEaddl6MnHAddress_i_v_; +text: .text%__1cJAssemblerSemit_arith_operand6MipnMRegisterImpl_nHAddress_i_v_; +text: .text%__1cZInterpreterMacroAssemblerSnotify_method_exit6MnITosState__v_; +text: .text%__1cbCAbstractInterpreterGeneratorbEset_entry_points_for_all_bytes6M_v_; +text: .text%__1cbCAbstractInterpreterGeneratorQset_entry_points6MnJBytecodesECode__v_; +text: .text%__1cbCAbstractInterpreterGeneratorWset_short_entry_points6MpnITemplate_rpC44444444_v_; +text: .text%__1cbCAbstractInterpreterGeneratorVset_vtos_entry_points6MpnITemplate_rpC44444444_v_; +text: .text%__1cbCAbstractInterpreterGeneratorVgenerate_and_dispatch6MpnITemplate_nITosState__v_; +text: .text%__1cITemplateIbytecode6kM_nJBytecodesECode__; +text: .text%__1cZInterpreterMacroAssemblerPdispatch_prolog6MnITosState_i_v_; +text: .text%__1cITemplateIgenerate6MpnZInterpreterMacroAssembler__v_; +text: .text%__1cNTemplateTableDnop6F_v_; +text: .text%__1cNTemplateTableKtransition6FnITosState_1_v_; +text: .text%__1cZInterpreterMacroAssemblerPdispatch_epilog6MnITosState_i_v_; +text: .text%__1cNDispatchTableJset_entry6MirnKEntryPoint__v_; +text: .text%__1cNTemplateTableLaconst_null6F_v_; +text: .text%__1cNTemplateTableGiconst6Fi_v_; +text: .text%__1cNTemplateTableGlconst6Fi_v_; +text: .text%__1cNTemplateTableGfconst6Fi_v_; +text: .text%__1cJAssemblerEfldz6M_v_; +text: .text%__1cJAssemblerEfld16M_v_; +text: .text%__1cJAssemblerFfaddp6Mi_v_; +text: .text%__1cNTemplateTableGdconst6Fi_v_; +text: .text%__1cNTemplateTableGbipush6F_v_; +text: .text%__1cNTemplateTableGsipush6F_v_; +text: .text%__1cJAssemblerFbswap6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerEsarl6MpnMRegisterImpl_i_v_; +text: .text%__1cNTemplateTableDldc6Fi_v_; +text: .text%__1cJAssemblerEmovb6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cNTemplateTableHcall_VM6FpnMRegisterImpl_pC2_v_; +text: .text%__1cJAssemblerFfld_s6MnHAddress__v_; +text: .text%__1cZInterpreterMacroAssemblerbGget_unsigned_2_byte_index_at_bcp6MpnMRegisterImpl_i_v_; +text: .text%__1cNTemplateTableGldc2_w6F_v_; +text: .text%__1cJAssemblerEcmpb6MnHAddress_i_v_; +text: .text%__1cNTemplateTableFiload6F_v_; +text: .text%__1cNTemplateTableMlocals_index6FpnMRegisterImpl_i_v_; +text: .text%__1cbCAbstractInterpreterGeneratorUset_wide_entry_point6MpnITemplate_rpC_v_; +text: .text%__1cNTemplateTableKwide_iload6F_v_; +text: .text%__1cNTemplateTableRlocals_index_wide6FpnMRegisterImpl__v_; +text: .text%__1cNTemplateTableFlload6F_v_; +text: .text%__1cNTemplateTableKwide_lload6F_v_; +text: .text%__1cNTemplateTableFfload6F_v_; +text: .text%__1cNTemplateTableKwide_fload6F_v_; +text: .text%__1cNTemplateTableFdload6F_v_; +text: .text%__1cNTemplateTableKwide_dload6F_v_; +text: .text%__1cNTemplateTableFaload6F_v_; +text: .text%__1cNTemplateTableKwide_aload6F_v_; +text: .text%__1cNTemplateTableFiload6Fi_v_; +text: .text%__1cNTemplateTableFlload6Fi_v_; +text: .text%__1cNTemplateTableFfload6Fi_v_; +text: .text%__1cNTemplateTableFdload6Fi_v_; +text: .text%__1cNTemplateTableHaload_06F_v_; +text: .text%__1cNTemplateTableFaload6Fi_v_; +text: .text%__1cNTemplateTableGiaload6F_v_; +text: .text%__1cNTemplateTableLindex_check6FpnMRegisterImpl_2_v_; +text: .text%__1cOMacroAssemblerKnull_check6MpnMRegisterImpl_i_v_; +text: .text%__1cOMacroAssemblerZneeds_explicit_null_check6Fi_i_; +text: .text%__1cNTemplateTableGlaload6F_v_; +text: .text%__1cNTemplateTableGfaload6F_v_; +text: .text%__1cNTemplateTableGdaload6F_v_; +text: .text%__1cNTemplateTableGaaload6F_v_; +text: .text%__1cNTemplateTableGbaload6F_v_; +text: .text%__1cNTemplateTableGcaload6F_v_; +text: .text%__1cNTemplateTableGsaload6F_v_; +text: .text%__1cNTemplateTableGistore6F_v_; +text: .text%__1cNTemplateTableLwide_istore6F_v_; +text: .text%__1cNTemplateTableGlstore6F_v_; +text: .text%__1cNTemplateTableLwide_lstore6F_v_; +text: .text%__1cNTemplateTableGfstore6F_v_; +text: .text%__1cNTemplateTableLwide_fstore6F_v_; +text: .text%__1cNTemplateTableGdstore6F_v_; +text: .text%__1cNTemplateTableLwide_dstore6F_v_; +text: .text%__1cNTemplateTableGastore6F_v_; +text: .text%__1cNTemplateTableLwide_astore6F_v_; +text: .text%__1cNTemplateTableGistore6Fi_v_; +text: .text%__1cNTemplateTableGlstore6Fi_v_; +text: .text%__1cNTemplateTableGfstore6Fi_v_; +text: .text%__1cNTemplateTableGdstore6Fi_v_; +text: .text%__1cNTemplateTableGastore6Fi_v_; +text: .text%__1cNTemplateTableHiastore6F_v_; +text: .text%__1cNTemplateTableHlastore6F_v_; +text: .text%__1cNTemplateTableHfastore6F_v_; +text: .text%__1cNTemplateTableHdastore6F_v_; +text: .text%__1cNTemplateTableHaastore6F_v_; +text: .text%__1cZInterpreterMacroAssemblerRprofile_checkcast6MipnMRegisterImpl__v_; +text: .text%__1cZInterpreterMacroAssemblerRgen_subtype_check6MpnMRegisterImpl_rnFLabel__v_; +text: .text%__1cJAssemblerKrepne_scan6M_v_; +text: .text%__1cOMacroAssemblerLstore_check6MpnMRegisterImpl__v_; +text: .text%__1cOMacroAssemblerSstore_check_part_16MpnMRegisterImpl__v_; +text: .text%__1cOMacroAssemblerSstore_check_part_26MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerEmovb6MnHAddress_i_v_; +text: .text%__1cNTemplateTableHbastore6F_v_; +text: .text%__1cJAssemblerEmovb6MnHAddress_pnMRegisterImpl__v_; +text: .text%__1cNTemplateTableHcastore6F_v_; +text: .text%__1cJAssemblerEmovw6MnHAddress_pnMRegisterImpl__v_; +text: .text%__1cNTemplateTableHsastore6F_v_; +text: .text%__1cNTemplateTableDpop6F_v_; +text: .text%__1cNTemplateTableEpop26F_v_; +text: .text%__1cNTemplateTableDdup6F_v_; +text: .text%__1cJAssemblerFpushl6MnHAddress__v_; +text: .text%__1cNTemplateTableGdup_x16F_v_; +text: .text%__1cNTemplateTableGdup_x26F_v_; +text: .text%__1cNTemplateTableEdup26F_v_; +text: .text%__1cNTemplateTableHdup2_x16F_v_; +text: .text%__1cNTemplateTableHdup2_x26F_v_; +text: .text%__1cNTemplateTableEswap6F_v_; +text: .text%__1cNTemplateTableEiop26Fn0AJOperation__v_; +text: .text%__1cNTemplateTableElop26Fn0AJOperation__v_; +text: .text%__1cJAssemblerEadcl6MpnMRegisterImpl_2_v_; +text: .text%__1cNTemplateTableEfop26Fn0AJOperation__v_; +text: .text%__1cJAssemblerGfadd_s6MnHAddress__v_; +text: .text%__1cZInterpreterMacroAssemblerGf2ieee6M_v_; +text: .text%__1cNTemplateTableEdop26Fn0AJOperation__v_; +text: .text%__1cJAssemblerGfadd_d6MnHAddress__v_; +text: .text%__1cZInterpreterMacroAssemblerGd2ieee6M_v_; +text: .text%__1cJAssemblerEsbbl6MpnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerHfsubr_s6MnHAddress__v_; +text: .text%__1cJAssemblerHfsubr_d6MnHAddress__v_; +text: .text%__1cJAssemblerFimull6MpnMRegisterImpl_2_v_; +text: .text%__1cNTemplateTableElmul6F_v_; +text: .text%__1cOMacroAssemblerElmul6Mii_v_; +text: .text%__1cJAssemblerEmull6MnHAddress__v_; +text: .text%__1cJAssemblerEmull6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerGfmul_s6MnHAddress__v_; +text: .text%__1cJAssemblerGfmul_d6MnHAddress__v_; +text: .text%__1cJAssemblerFfld_x6MnHAddress__v_; +text: .text%__1cJAssemblerFfmulp6Mi_v_; +text: .text%__1cNTemplateTableEidiv6F_v_; +text: .text%__1cOMacroAssemblerPcorrected_idivl6MpnMRegisterImpl__i_; +text: .text%__1cJAssemblerEcdql6M_v_; +text: .text%__1cJAssemblerFidivl6MpnMRegisterImpl__v_; +text: .text%__1cNTemplateTableEldiv6F_v_; +text: .text%__1cZInterpreterMacroAssemblerRcall_VM_leaf_base6MpCi_v_; +text: .text%__1cJAssemblerHfdivr_s6MnHAddress__v_; +text: .text%__1cJAssemblerHfdivr_d6MnHAddress__v_; +text: .text%__1cJAssemblerGfdivrp6Mi_v_; +text: .text%__1cNTemplateTableEirem6F_v_; +text: .text%__1cNTemplateTableElrem6F_v_; +text: .text%__1cOMacroAssemblerFfremr6MpnMRegisterImpl__v_; +text: .text%__1cOMacroAssemblerIsave_eax6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerFfprem6M_v_; +text: .text%__1cJAssemblerJfnstsw_ax6M_v_; +text: .text%__1cJAssemblerEsahf6M_v_; +text: .text%__1cOMacroAssemblerLrestore_eax6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerEfxch6Mi_v_; +text: .text%__1cNTemplateTableEineg6F_v_; +text: .text%__1cNTemplateTableElneg6F_v_; +text: .text%__1cOMacroAssemblerElneg6MpnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerEadcl6MpnMRegisterImpl_i_v_; +text: .text%__1cNTemplateTableEfneg6F_v_; +text: .text%__1cJAssemblerEfchs6M_v_; +text: .text%__1cNTemplateTableEdneg6F_v_; +text: .text%__1cJAssemblerEshll6MpnMRegisterImpl__v_; +text: .text%__1cNTemplateTableElshl6F_v_; +text: .text%__1cOMacroAssemblerElshl6MpnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerFshldl6MpnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerEsarl6MpnMRegisterImpl__v_; +text: .text%__1cNTemplateTableElshr6F_v_; +text: .text%__1cOMacroAssemblerElshr6MpnMRegisterImpl_2i_v_; +text: .text%__1cJAssemblerFshrdl6MpnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerEshrl6MpnMRegisterImpl__v_; +text: .text%__1cNTemplateTableFlushr6F_v_; +text: .text%__1cJAssemblerEandl6MpnMRegisterImpl_2_v_; +text: .text%__1cNTemplateTableEiinc6F_v_; +text: .text%__1cJAssemblerEaddl6MnHAddress_pnMRegisterImpl__v_; +text: .text%__1cNTemplateTableJwide_iinc6F_v_; +text: .text%__1cNTemplateTableHconvert6F_v_; +text: .text%__1cOMacroAssemblerLextend_sign6MpnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerGfild_s6MnHAddress__v_; +text: .text%__1cJAssemblerGfild_d6MnHAddress__v_; +text: .text%__1cNTemplateTableElcmp6F_v_; +text: .text%__1cOMacroAssemblerIlcmp2int6MpnMRegisterImpl_222_v_; +text: .text%__1cNTemplateTableJfloat_cmp6Fi_v_; +text: .text%__1cNTemplateTableJfloat_cmp6Fii_v_; +text: .text%__1cOMacroAssemblerIfcmp2int6MpnMRegisterImpl_i_v_; +text: .text%__1cNTemplateTableKdouble_cmp6Fi_v_; +text: .text%__1cNTemplateTableHif_0cmp6Fn0AJCondition__v_; +text: .text%__1cFj_not6FnNTemplateTableJCondition__nJAssemblerJCondition__: templateTable_x86.o; +text: .text%__1cNTemplateTableGbranch6Fii_v_; +text: .text%__1cZInterpreterMacroAssemblerUprofile_taken_branch6MpnMRegisterImpl_2_v_; +text: .text%__1cZInterpreterMacroAssemblerNdispatch_only6MnITosState__v_; +text: .text%__1cZInterpreterMacroAssemblerYprofile_not_taken_branch6MpnMRegisterImpl__v_; +text: .text%__1cNTemplateTableHif_icmp6Fn0AJCondition__v_; +text: .text%__1cNTemplateTableHif_acmp6Fn0AJCondition__v_; +text: .text%__1cNTemplateTableF_goto6F_v_; +text: .text%__1cNTemplateTableDjsr6F_v_; +text: .text%__1cZInterpreterMacroAssemblerWdispatch_only_noverify6MnITosState__v_; +text: .text%__1cNTemplateTableDret6F_v_; +text: .text%__1cZInterpreterMacroAssemblerLprofile_ret6MpnMRegisterImpl_2_v_; +text: .text%__1cNTemplateTableIwide_ret6F_v_; +text: .text%__1cNTemplateTableLtableswitch6F_v_; +text: .text%__1cZInterpreterMacroAssemblerTprofile_switch_case6MpnMRegisterImpl_22_v_; +text: .text%__1cZInterpreterMacroAssemblerWprofile_switch_default6MpnMRegisterImpl__v_; +text: .text%__1cNTemplateTableMlookupswitch6F_v_; +text: .text%__1cNTemplateTableH_return6FnITosState__v_; +text: .text%__1cNTemplateTableJgetstatic6Fi_v_; +text: .text%__1cNTemplateTableSgetfield_or_static6Fii_v_; +text: .text%__1cNTemplateTableZload_field_cp_cache_entry6FipnMRegisterImpl_22i_v_; +text: .text%__1cNTemplateTableXresolve_cache_and_index6FipnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerHfistp_d6MnHAddress__v_; +text: .text%__1cNTemplateTableJputstatic6Fi_v_; +text: .text%__1cNTemplateTableSputfield_or_static6Fii_v_; +text: .text%__1cNTemplateTableUjvmti_post_field_mod6Fii_v_; +text: .text%__1cOMacroAssemblerLstore_check6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cNTemplateTableQvolatile_barrier6F_v_; +text: .text%__1cNTemplateTableIgetfield6Fi_v_; +text: .text%__1cNTemplateTableOpatch_bytecode6FnJBytecodesECode_pnMRegisterImpl_4i_v_; +text: .text%__1cNTemplateTableIputfield6Fi_v_; +text: .text%__1cNTemplateTableNinvokevirtual6Fi_v_; +text: .text%__1cNTemplateTableOprepare_invoke6FpnMRegisterImpl_2inJBytecodesECode__v_; +text: .text%__1cNTemplateTablebAload_invoke_cp_cache_entry6FipnMRegisterImpl_22ii_v_; +text: .text%__1cNTemplateTableUinvokevirtual_helper6FpnMRegisterImpl_22_v_; +text: .text%__1cZInterpreterMacroAssemblerSprofile_final_call6MpnMRegisterImpl__v_; +text: .text%__1cZInterpreterMacroAssemblerUprofile_virtual_call6MpnMRegisterImpl_22_v_; +text: .text%__1cNTemplateTableNinvokespecial6Fi_v_; +text: .text%__1cZInterpreterMacroAssemblerMprofile_call6MpnMRegisterImpl__v_; +text: .text%__1cNTemplateTableMinvokestatic6Fi_v_; +text: .text%__1cNTemplateTablePinvokeinterface6Fi_v_; +text: .text%__1cOMacroAssemblerIround_to6MpnMRegisterImpl_i_v_; +text: .text%__1cbCAbstractInterpreterGeneratorRset_unimplemented6Mi_v_; +text: .text%__1cNTemplateTableE_new6F_v_; +text: .text%__1cQGenCollectedHeapItop_addr6kM_ppnIHeapWord__; +text: .text%__1cQDefNewGenerationItop_addr6kM_ppnIHeapWord__; +text: .text%__1cQGenCollectedHeapIend_addr6kM_ppnIHeapWord__; +text: .text%__1cQDefNewGenerationIend_addr6kM_ppnIHeapWord__; +text: .text%__1cOMacroAssemblerJdecrement6MpnMRegisterImpl_i_v_; +text: .text%__1cNTemplateTableHcall_VM6FpnMRegisterImpl_pC22_v_; +text: .text%__1cNTemplateTableInewarray6F_v_; +text: .text%__1cNTemplateTableJanewarray6F_v_; +text: .text%__1cNTemplateTableHcall_VM6FpnMRegisterImpl_pC222_v_; +text: .text%__1cNTemplateTableLarraylength6F_v_; +text: .text%__1cNTemplateTableGathrow6F_v_; +text: .text%__1cNTemplateTableJcheckcast6F_v_; +text: .text%__1cNTemplateTableHcall_VM6FpnMRegisterImpl_pC_v_; +text: .text%__1cNTemplateTableKinstanceof6F_v_; +text: .text%__1cNTemplateTableMmonitorenter6F_v_; +text: .text%__1cJAssemblerFcmovl6Mn0AJCondition_pnMRegisterImpl_3_v_; +text: .text%__1cNTemplateTableLmonitorexit6F_v_; +text: .text%__1cNTemplateTableEwide6F_v_; +text: .text%__1cNTemplateTableOmultianewarray6F_v_; +text: .text%__1cNTemplateTableKif_nullcmp6Fn0AJCondition__v_; +text: .text%__1cNTemplateTableGgoto_w6F_v_; +text: .text%__1cNTemplateTableFjsr_w6F_v_; +text: .text%__1cNTemplateTableL_breakpoint6F_v_; +text: .text%__1cZInterpreterMacroAssemblerUdispatch_only_normal6MnITosState__v_; +text: .text%__1cNTemplateTableQfast_accessfield6FnITosState__v_; +text: .text%__1cNTemplateTablePfast_storefield6FnITosState__v_; +text: .text%__1cNTemplateTableZjvmti_post_fast_field_mod6F_v_; +text: .text%__1cNTemplateTableMfast_xaccess6FnITosState__v_; +text: .text%__1cNTemplateTableKfast_iload6F_v_; +text: .text%__1cNTemplateTableLfast_iload26F_v_; +text: .text%__1cNTemplateTableMfast_icaload6F_v_; +text: .text%__1cNTemplateTableRfast_invokevfinal6Fi_v_; +text: .text%__1cNTemplateTableRfast_linearswitch6F_v_; +text: .text%__1cNTemplateTableRfast_binaryswitch6F_v_; +text: .text%__1cNTemplateTableSshouldnotreachhere6F_v_; +text: .text%__1cbCAbstractInterpreterGeneratorbCset_safepoints_for_all_bytes6M_v_; +text: .text%__1cWinvocationCounter_init6F_v_; +text: .text%__1cOmarksweep_init6F_v_; +text: .text%__1cQaccessFlags_init6F_v_; +text: .text%__1cStemplateTable_init6F_v_; +text: .text%__1cVInterfaceSupport_init6F_v_; +text: .text%__1cOuniverse2_init6F_v_; +text: .text%__1cIUniverseHgenesis6FpnGThread__v_; +text: .text%__1cIUniverseYcompute_base_vtable_size6F_v_; +text: .text%__1cLClassLoaderVcompute_Object_vtable6F_i_; +text: .text%__1cKklassKlassMcreate_klass6FpnGThread__pnMklassOopDesc__; +text: .text%__1cFKlassVbase_create_klass_oop6FrnLKlassHandle_irknKKlass_vtbl_pnGThread__pnMklassOopDesc__; +text: .text%__1cKklassKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: klassKlass.o; +text: .text%__1cKKlass_vtbl2n6FIrnLKlassHandle_ipnGThread__pv_; +text: .text%__1cNCollectedHeapWpermanent_obj_allocate6FnLKlassHandle_ipnGThread__pnHoopDesc__: klass.o; +text: .text%__1cKSharedHeapWpermanent_mem_allocate6MI_pnIHeapWord__: genCollectedHeap.o; +text: .text%__1cRCompactingPermGenMmem_allocate6MI_pnIHeapWord__; +text: .text%__1cbCOneContigSpaceCardGenerationIallocate6MIii_pnIHeapWord__: compactingPermGenGen.o; +text: .text%__1cWOffsetTableContigSpaceIallocate6MI_pnIHeapWord__: space.o; +text: .text%__1cPContiguousSpaceIallocate6MI_pnIHeapWord__; +text: .text%__1cbBBlockOffsetArrayContigSpaceLalloc_block6MpnIHeapWord_2_v_: blockOffsetTable.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: klass.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: klass.o; +text: .text%__1cRCardTableModRefBSEkind6M_nKBarrierSetEName__: cardTableModRefBS.o; +text: .text%__1cFKlassMset_subklass6MpnMklassOopDesc__v_; +text: .text%__1cFKlassQset_next_sibling6MpnMklassOopDesc__v_; +text: .text%__1cKklassKlassOset_alloc_size6MI_v_: klassKlass.o; +text: .text%__1cParrayKlassKlassMcreate_klass6FpnGThread__pnMklassOopDesc__; +text: .text%__1cFKlassRbase_create_klass6FrnLKlassHandle_irknKKlass_vtbl_pnGThread__1_; +text: .text%__1cParrayKlassKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: arrayKlassKlass.o; +text: .text%__1cKklassKlassOset_alloc_size6MI_v_: arrayKlassKlass.o; +text: .text%__1cPjava_lang_ClassNcreate_mirror6FnLKlassHandle_pnGThread__pnHoopDesc__; +text: .text%__1cFKlassWcompute_modifier_flags6kMpnGThread__i_; +text: .text%__1cSobjArrayKlassKlassMcreate_klass6FpnGThread__pnMklassOopDesc__; +text: .text%__1cSobjArrayKlassKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: objArrayKlassKlass.o; +text: .text%__1cKklassKlassOset_alloc_size6MI_v_: objArrayKlassKlass.o; +text: .text%__1cSinstanceKlassKlassMcreate_klass6FpnGThread__pnMklassOopDesc__; +text: .text%__1cSinstanceKlassKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: instanceKlassKlass.o; +text: .text%__1cKklassKlassOset_alloc_size6MI_v_: instanceKlassKlass.o; +text: .text%__1cTtypeArrayKlassKlassMcreate_klass6FpnGThread__pnMklassOopDesc__; +text: .text%__1cTtypeArrayKlassKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: typeArrayKlassKlass.o; +text: .text%__1cbBBlockOffsetArrayContigSpaceQalloc_block_work6MpnIHeapWord_2_v_; +text: .text%__1cKklassKlassOset_alloc_size6MI_v_: typeArrayKlassKlass.o; +text: .text%__1cLsymbolKlassMcreate_klass6FpnGThread__pnMklassOopDesc__; +text: .text%__1cLsymbolKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: symbolKlass.o; +text: .text%__1cLsymbolKlassOset_alloc_size6MI_v_: symbolKlass.o; +text: .text%__1cKoopFactoryKnew_symbol6FpkcipnGThread__pnNsymbolOopDesc__; +text: .text%__1cLSymbolTableGlookup6FpkcipnGThread__pnNsymbolOopDesc__; +text: .text%__1cJHashtableLhash_symbol6Fpkci_I_: symbolTable.o; +text: .text%__1cLSymbolTableGlookup6MipkciI_pnNsymbolOopDesc__; +text: .text%__1cLSymbolTableJbasic_add6MipCiIpnGThread__pnNsymbolOopDesc__; +text: .text%__1cLsymbolKlassPallocate_symbol6MpCipnGThread__pnNsymbolOopDesc__; +text: .text%__1cNCollectedHeapWpermanent_obj_allocate6FnLKlassHandle_ipnGThread__pnHoopDesc__: symbolKlass.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: symbolKlass.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: symbolKlass.o; +text: .text%__1cJHashtableJnew_entry6MIpnHoopDesc__pnOHashtableEntry__; +text: .text%__1cOBasicHashtableJnew_entry6MI_pnTBasicHashtableEntry__; +text: .text%__1cOtypeArrayKlassMcreate_klass6FnJBasicType_ipnGThread__pnMklassOopDesc__; +text: .text%__1cOtypeArrayKlassNexternal_name6FnJBasicType__pkc_; +text: .text%__1cKarrayKlassXbase_create_array_klass6FrknKKlass_vtbl_inLKlassHandle_pnGThread__nQarrayKlassHandle__; +text: .text%__1cOtypeArrayKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: typeArrayKlass.o; +text: .text%__1cKarrayKlassOset_alloc_size6MI_v_: typeArrayKlass.o; +text: .text%__1cLAccessFlagsPatomic_set_bits6Mi_v_; +text: .text%__1cLlog2_intptr6Fi_i_: typeArrayKlass.o; +text: .text%__1cKarrayKlassbBcomplete_create_array_klass6FnQarrayKlassHandle_nLKlassHandle_pnGThread__v_; +text: .text%__1cFKlassRinitialize_supers6MpnMklassOopDesc_pnGThread__v_; +text: .text%__1cKarrayKlassYcompute_secondary_supers6MipnGThread__pnPobjArrayOopDesc__; +text: .text%__1cKarrayKlassGvtable6kM_pnLklassVtable__; +text: .text%__1cLklassVtableRinitialize_vtable6MpnGThread__v_; +text: .text%__1cKarrayKlassKjava_super6kM_pnMklassOopDesc__; +text: .text%__1cKarrayKlassWcompute_modifier_flags6kMpnGThread__i_; +text: .text%__1cLmethodKlassMcreate_klass6FpnGThread__pnMklassOopDesc__; +text: .text%__1cLmethodKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: methodKlass.o; +text: .text%__1cLmethodKlassOset_alloc_size6MI_v_: methodKlass.o; +text: .text%__1cQconstMethodKlassMcreate_klass6FpnGThread__pnMklassOopDesc__; +text: .text%__1cQconstMethodKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: constMethodKlass.o; +text: .text%__1cQconstMethodKlassOset_alloc_size6MI_v_: constMethodKlass.o; +text: .text%__1cPmethodDataKlassMcreate_klass6FpnGThread__pnMklassOopDesc__; +text: .text%__1cPmethodDataKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: methodDataKlass.o; +text: .text%__1cPmethodDataKlassOset_alloc_size6MI_v_: methodDataKlass.o; +text: .text%__1cRconstantPoolKlassMcreate_klass6FpnGThread__pnMklassOopDesc__; +text: .text%__1cRconstantPoolKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: constantPoolKlass.o; +text: .text%__1cKarrayKlassOset_alloc_size6MI_v_: constantPoolKlass.o; +text: .text%__1cWconstantPoolCacheKlassMcreate_klass6FpnGThread__pnMklassOopDesc__; +text: .text%__1cWconstantPoolCacheKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: cpCacheKlass.o; +text: .text%__1cKarrayKlassOset_alloc_size6MI_v_: cpCacheKlass.o; +text: .text%__1cVcompiledICHolderKlassMcreate_klass6FpnGThread__pnMklassOopDesc__; +text: .text%__1cVcompiledICHolderKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: compiledICHolderKlass.o; +text: .text%__1cVcompiledICHolderKlassOset_alloc_size6MI_v_: compiledICHolderKlass.o; +text: .text%__1cSobjArrayKlassKlassbEallocate_system_objArray_klass6MpnGThread__pnMklassOopDesc__; +text: .text%__1cSobjArrayKlassKlassXallocate_objArray_klass6MinLKlassHandle_pnGThread__pnMklassOopDesc__; +text: .text%__1cSobjArrayKlassKlassbCallocate_objArray_klass_impl6FnYobjArrayKlassKlassHandle_inLKlassHandle_pnGThread__pnMklassOopDesc__; +text: .text%__1cFKlassNoop_is_symbol6kM_i_: typeArrayKlass.o; +text: .text%__1cNsymbolOopDescLas_C_string6kM_pc_; +text: .text%__1cNsymbolOopDescLas_C_string6kMpci_1_; +text: .text%__1cFKlassPoop_is_instance6kM_i_: typeArrayKlass.o; +text: .text%__1cNobjArrayKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: objArrayKlass.o; +text: .text%__1cKarrayKlassOset_alloc_size6MI_v_: objArrayKlass.o; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: typeArrayKlass.o; +text: .text%__1cLlog2_intptr6Fi_i_: objArrayKlassKlass.o; +text: .text%__1cNobjArrayKlassYcompute_secondary_supers6MipnGThread__pnPobjArrayOopDesc__; +text: .text%__1cNobjArrayKlassWcompute_modifier_flags6kMpnGThread__i_; +text: .text%__1cKoopFactoryXnew_permanent_byteArray6FipnGThread__pnQtypeArrayOopDesc__; +text: .text%__1cOtypeArrayKlassSallocate_permanent6MipnGThread__pnQtypeArrayOopDesc__; +text: .text%__1cNCollectedHeapYpermanent_array_allocate6FnLKlassHandle_iipnGThread__pnHoopDesc__: typeArrayKlass.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: typeArrayKlass.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: typeArrayKlass.o; +text: .text%__1cKoopFactoryYnew_permanent_shortArray6FipnGThread__pnQtypeArrayOopDesc__; +text: .text%__1cKoopFactoryWnew_permanent_intArray6FipnGThread__pnQtypeArrayOopDesc__; +text: .text%__1cKoopFactoryTnew_system_objArray6FipnGThread__pnPobjArrayOopDesc__; +text: .text%__1cNCollectedHeapYpermanent_array_allocate6FnLKlassHandle_iipnGThread__pnHoopDesc__: oopFactory.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: oopFactory.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: oopFactory.o; +text: .text%__1cJvmSymbolsKinitialize6FpnGThread__v_; +text: .text%__1cNsymbolOopDescGequals6kMpkci_i_; +text: .text%__1cQSystemDictionaryKinitialize6FpnGThread__v_; +text: .text%__1cKDictionary2t6Mi_v_; +text: .text%__1cOBasicHashtable2t6Mii_v_: dictionary.o; +text: .text%__1cQPlaceholderTable2t6Mi_v_; +text: .text%__1cOBasicHashtable2t6Mii_v_: placeholders.o; +text: .text%__1cVLoaderConstraintTable2t6Mi_v_; +text: .text%__1cOBasicHashtable2t6Mii_v_: loaderConstraints.o; +text: .text%__1cQSystemDictionarybCinitialize_preloaded_classes6FpnGThread__v_; +text: .text%__1cQSystemDictionaryPresolve_or_fail6FnMsymbolHandle_ipnGThread__pnMklassOopDesc__; +text: .text%__1cQSystemDictionaryPresolve_or_fail6FnMsymbolHandle_nGHandle_2ipnGThread__pnMklassOopDesc__; +text: .text%__1cQSystemDictionaryPresolve_or_null6FnMsymbolHandle_nGHandle_2pnGThread__pnMklassOopDesc__; +text: .text%__1cQSystemDictionarybEresolve_instance_class_or_null6FnMsymbolHandle_nGHandle_2pnGThread__pnMklassOopDesc__; +text: .text%__1cVjava_lang_ClassLoaderbBnon_reflection_class_loader6FpnHoopDesc__2_; +text: .text%__1cPTwoOopHashtableMcompute_hash6MnMsymbolHandle_nGHandle__I_: systemDictionary.o; +text: .text%__1cHoopDescSslow_identity_hash6M_i_; +text: .text%__1cSObjectSynchronizerXidentity_hash_value_for6FnGHandle__i_; +text: .text%__1cNget_next_hash6F_i_: synchronizer.o; +text: .text%__1cCosGrandom6F_l_; +text: .text%__1cKDictionaryEfind6MiInMsymbolHandle_nGHandle_2pnGThread__pnMklassOopDesc__; +text: .text%__1cKDictionaryJget_entry6MiInMsymbolHandle_nGHandle__pnPDictionaryEntry__; +text: .text%__1cQSystemDictionarybAcompute_loader_lock_object6FnGHandle_pnGThread__1_; +text: .text%__1cMObjectLocker2t6MnGHandle_pnGThread__v_; +text: .text%__1cSObjectSynchronizerKfast_enter6FnGHandle_pnJBasicLock_pnGThread__v_; +text: .text%__1cQSystemDictionaryKfind_class6FiInMsymbolHandle_nGHandle__pnMklassOopDesc__; +text: .text%__1cKDictionaryKfind_class6MiInMsymbolHandle_nGHandle__pnMklassOopDesc__; +text: .text%__1cQPlaceholderTableKfind_entry6MiInMsymbolHandle_nGHandle__pnNsymbolOopDesc__; +text: .text%__1cQPlaceholderTableJadd_entry6MiInMsymbolHandle_nGHandle__v_; +text: .text%__1cQPlaceholderTableJnew_entry6MipnNsymbolOopDesc_pnHoopDesc__pnQPlaceholderEntry__; +text: .text%__1cQSystemDictionaryTload_instance_class6FnMsymbolHandle_nGHandle_pnGThread__nTinstanceKlassHandle__; +text: .text%__1cQSystemDictionaryRload_shared_class6FnMsymbolHandle_nGHandle_pnGThread__nTinstanceKlassHandle__; +text: .text%__1cQSystemDictionaryRfind_shared_class6FnMsymbolHandle__pnMklassOopDesc__; +text: .text%__1cQSystemDictionaryRload_shared_class6FnTinstanceKlassHandle_nGHandle_pnGThread__1_; +text: .text%__1cLClassLoaderOload_classfile6FnMsymbolHandle_pnGThread__nTinstanceKlassHandle__; +text: .text%__1cFVTuneQstart_class_load6F_v_; +text: .text%__1cJEventMark2t6MpkcE_v_: classLoader.o; +text: .text%__1cSThreadProfilerMark2t6Mn0AGRegion__v_; +text: .text%__1cMstringStream2t6MI_v_; +text: .text%__1cMstringStreamFwrite6MpkcI_v_; +text: .text%__1cMoutputStreamPupdate_position6MpkcI_v_; +text: .text%__1cMstringStreamJas_string6M_pc_; +text: .text%__1cMelapsedTimerFstart6M_v_; +text: .text%__1cCosPelapsed_counter6F_x_; +text: .text%__1cRClassPathZipEntryLopen_stream6Mpkc_pnPClassFileStream__; +text: .text%__1cPClassFileStream2t6MpCipc_v_; +text: .text%__1cMelapsedTimerEstop6M_v_; +text: .text%__1cPClassFileParserOparseClassFile6MnMsymbolHandle_nGHandle_2r1pnGThread__nTinstanceKlassHandle__; +text: .text%__1cIVerifierRshould_verify_for6FpnHoopDesc__i_; +text: .text%__1cPClassFileStreamGget_u46MpnGThread__I_; +text: .text%__1cPClassFileStreamGget_u26MpnGThread__H_; +text: .text%__1cIVerifierQrelax_verify_for6FpnHoopDesc__i_; +text: .text%__1cVjava_lang_ClassLoaderRis_trusted_loader6FpnHoopDesc__i_; +text: .text%__1cQSystemDictionarySjava_system_loader6F_pnHoopDesc__; +text: .text%__1cPClassFileParserTparse_constant_pool6MpnGThread__nSconstantPoolHandle__; +text: .text%__1cPClassFileParserOcheck_property6MipkcipnGThread__v_; +text: .text%__1cKoopFactoryQnew_constantPool6FipnGThread__pnTconstantPoolOopDesc__; +text: .text%__1cRconstantPoolKlassIallocate6MipnGThread__pnTconstantPoolOopDesc__; +text: .text%__1cNCollectedHeapYpermanent_array_allocate6FnLKlassHandle_iipnGThread__pnHoopDesc__: constantPoolKlass.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: constantPoolKlass.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: constantPoolKlass.o; +text: .text%__1cPClassFileParserbBparse_constant_pool_entries6MnSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cPClassFileStreamGget_u16MpnGThread__C_; +text: .text%__1cPClassFileParserbFparse_constant_pool_class_entry6MnSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cPClassFileParserbJparse_constant_pool_methodref_entry6MnSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cPClassFileParserbGparse_constant_pool_string_entry6MnSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cPClassFileParserbHparse_constant_pool_integer_entry6MnSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cPClassFileParserbEparse_constant_pool_utf8_entry6MnSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cPClassFileParserRverify_legal_utf86MpkCipnGThread__v_; +text: .text%__1cPClassFileStreamHskip_u16MipnGThread__v_; +text: .text%__1cPClassFileParserbLparse_constant_pool_nameandtype_entry6MnSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cTconstantPoolOopDescSklass_ref_index_at6Mi_i_; +text: .text%__1cTconstantPoolOopDescbAname_and_type_ref_index_at6Mi_i_; +text: .text%__1cTconstantPoolOopDescRname_ref_index_at6Mi_i_; +text: .text%__1cTconstantPoolOopDescWsignature_ref_index_at6Mi_i_; +text: .text%__1cPClassFileParserbCverify_legal_class_modifiers6MipnGThread__v_; +text: .text%__1cPClassFileParserQparse_interfaces6MnSconstantPoolHandle_nGHandle_2pnGThread__nOobjArrayHandle__; +text: .text%__1cPClassFileParserMparse_fields6MnSconstantPoolHandle_ipnUFieldAllocationCount_pnOobjArrayHandle_pnGThread__nPtypeArrayHandle__; +text: .text%__1cUinitialize_hashtable6FppnLNameSigHash__v_; +text: .text%__1cPclear_hashtable6FppnLNameSigHash__v_; +text: .text%__1cPClassFileParserNparse_methods6MnSconstantPoolHandle_ipnLAccessFlags_ppnPobjArrayOopDesc_66pnGThread__nOobjArrayHandle__; +text: .text%__1cPClassFileParserMparse_method6MnSconstantPoolHandle_ipnLAccessFlags_pnPtypeArrayHandle_55pnGThread__nMmethodHandle__; +text: .text%__1cPClassFileParserYverify_legal_method_name6MnMsymbolHandle_pnGThread__v_; +text: .text%__1cPClassFileParserbDverify_legal_method_modifiers6MiinMsymbolHandle_pnGThread__v_; +text: .text%__1cPClassFileParserWparse_linenumber_table6MIIpipnGThread__pC_; +text: .text%__1cbFCompressedLineNumberWriteStream2t6Mi_v_; +text: .text%__1cVCompressedWriteStream2t6Mi_v_; +text: .text%__1cQCompressedStream2t6MpCi_v_; +text: .text%__1cbFCompressedLineNumberWriteStreamKwrite_pair6Mii_v_; +text: .text%__1cVCompressedWriteStreamJwrite_int6Mi_v_: methodOop.o; +text: .text%__1cKoopFactoryKnew_method6FinLAccessFlags_iiipnGThread__pnNmethodOopDesc__; +text: .text%__1cKoopFactoryPnew_constMethod6FiiiipnGThread__pnSconstMethodOopDesc__; +text: .text%__1cQconstMethodKlassIallocate6MiiiipnGThread__pnSconstMethodOopDesc__; +text: .text%__1cSconstMethodOopDescLobject_size6Fiiii_i_; +text: .text%__1cNCollectedHeapWpermanent_obj_allocate6FnLKlassHandle_ipnGThread__pnHoopDesc__: constMethodKlass.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: constMethodKlass.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: constMethodKlass.o; +text: .text%__1cSconstMethodOopDescZset_inlined_tables_length6Miii_v_; +text: .text%__1cLmethodKlassIallocate6MnRconstMethodHandle_nLAccessFlags_pnGThread__pnNmethodOopDesc__; +text: .text%__1cNmethodOopDescLobject_size6Fi_i_; +text: .text%__1cNCollectedHeapWpermanent_obj_allocate6FnLKlassHandle_ipnGThread__pnHoopDesc__: methodKlass.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: methodKlass.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: methodKlass.o; +text: .text%__1cNmethodOopDescJinit_code6M_v_; +text: .text%__1cRInvocationCounterEinit6M_v_; +text: .text%__1cRInvocationCounterFreset6M_v_; +text: .text%__1cRInvocationCounterJset_state6Mn0AFState__v_; +text: .text%__1cLmethodKlassIoop_size6kMpnHoopDesc__i_; +text: .text%__1cNmethodOopDescbAcompute_size_of_parameters6MpnGThread__v_; +text: .text%__1cRSignatureIterator2t6MnMsymbolHandle__v_; +text: .text%__1cRSignatureIteratorSiterate_parameters6M_v_; +text: .text%__1cRSignatureIteratorGexpect6Mc_v_; +text: .text%__1cSconstMethodOopDescbBcompressed_linenumber_table6kM_pC_; +text: .text%__1cPClassFileParserUassemble_annotations6MpCi1ipnGThread__nPtypeArrayHandle__; +text: .text%__1cNmethodOopDescVclear_native_function6M_v_; +text: .text%__1cNmethodOopDescTset_native_function6MpC_v_; +text: .text%__1cNmethodOopDescVset_signature_handler6MpC_v_; +text: .text%__1cVCompressedWriteStreamEgrow6M_v_; +text: .text%__1cRSignatureIteratorKparse_type6M_i_; +text: .text%__1cNSignatureInfoJdo_object6Mii_v_: frame.o; +text: .text%__1cUArgumentSizeComputerDset6MinJBasicType__v_: frame.o; +text: .text%__1cPClassFileParserYparse_checked_exceptions6MpHInSconstantPoolHandle_pnGThread__1_; +text: .text%__1cPClassFileStreamHskip_u26MipnGThread__v_; +text: .text%__1cSconstMethodOopDescbEchecked_exceptions_length_addr6kM_pH_; +text: .text%__1cSconstMethodOopDescYchecked_exceptions_start6kM_pnXCheckedExceptionElement__; +text: .text%__1cXcopy_u2_with_conversion6FpH0i_v_: classFileParser.o; +text: .text%__1cNSignatureInfoHdo_long6M_v_: frame.o; +text: .text%__1cNSignatureInfoGdo_int6M_v_: frame.o; +text: .text%__1cPClassFileParserbDcompute_transitive_interfaces6MnTinstanceKlassHandle_nOobjArrayHandle_pnGThread__2_; +text: .text%__1cPClassFileParserMsort_methods6MnOobjArrayHandle_111pnGThread__nPtypeArrayHandle__; +text: .text%__1cNmethodOopDescMsort_methods6FpnPobjArrayOopDesc_222_v_; +text: .text%method_compare: methodOop.o; +text: .text%__1cLklassVtablebKcompute_vtable_size_and_num_mirandas6Fri1pnMklassOopDesc_pnPobjArrayOopDesc_nLAccessFlags_pnHoopDesc_pnNsymbolOopDesc_5_v_; +text: .text%__1cLklassVtableWneeds_new_vtable_entry6FpnNmethodOopDesc_pnMklassOopDesc_pnHoopDesc_pnNsymbolOopDesc_nLAccessFlags__i_; +text: .text%__1cLklassVtableQget_num_mirandas6FpnMklassOopDesc_pnPobjArrayOopDesc_4_i_; +text: .text%__1cLklassVtableMget_mirandas6FpnNGrowableArray4CpnNmethodOopDesc___pnMklassOopDesc_pnPobjArrayOopDesc_8_v_; +text: .text%__1cLklassItableTcompute_itable_size6FnOobjArrayHandle__i_; +text: .text%__1cUvisit_all_interfaces6FpnPobjArrayOopDesc_pnXInterfaceVisiterClosure__v_; +text: .text%__1cPClassFileParserUcompute_oop_map_size6MnTinstanceKlassHandle_ii_i_; +text: .text%__1cKoopFactoryRnew_instanceKlass6FiiiinNReferenceType_pnGThread__pnMklassOopDesc__; +text: .text%__1cSinstanceKlassKlassXallocate_instance_klass6MiiiinNReferenceType_pnGThread__pnMklassOopDesc__; +text: .text%__1cNinstanceKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: instanceKlass.o; +text: .text%__1cNinstanceKlassOset_alloc_size6MI_v_: instanceKlass.o; +text: .text%__1cNinstanceKlassQinit_implementor6M_v_; +text: .text%__1cNinstanceKlassWcompute_modifier_flags6kMpnGThread__i_; +text: .text%__1cTconstantPoolOopDescNklass_name_at6Mi_pnNsymbolOopDesc__; +text: .text%__1cFKlassMoop_is_klass6kM_i_: symbolKlass.o; +text: .text%__1cPClassFileParserbAparse_classfile_attributes6MnSconstantPoolHandle_nTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cPClassFileParserbKparse_classfile_sourcefile_attribute6MnSconstantPoolHandle_nTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cNinstanceKlassWdo_local_static_fields6MpFpnPfieldDescriptor_pnGThread__v4_v_; +text: .text%__1cNinstanceKlassbBdo_local_static_fields_impl6FnTinstanceKlassHandle_pFpnPfieldDescriptor_pnGThread__v5_v_; +text: .text%__1cNinstanceKlassYcompute_secondary_supers6MipnGThread__pnPobjArrayOopDesc__; +text: .text%__1cLklassItableZsetup_itable_offset_table6FnTinstanceKlassHandle__v_; +text: .text%__1cPClassFileParserNfill_oop_maps6MnTinstanceKlassHandle_ii_v_; +text: .text%__1cFKlassKsuperklass6kM_pnNinstanceKlass__; +text: .text%__1cPClassFileParserVset_precomputed_flags6MnTinstanceKlassHandle__v_; +text: .text%__1cFKlassNlookup_method6kMpnNsymbolOopDesc_2_pnNmethodOopDesc__; +text: .text%__1cNinstanceKlassWuncached_lookup_method6kMpnNsymbolOopDesc_2_pnNmethodOopDesc__; +text: .text%__1cNinstanceKlassLfind_method6kMpnNsymbolOopDesc_2_pnNmethodOopDesc__; +text: .text%__1cNinstanceKlassLfind_method6FpnPobjArrayOopDesc_pnNsymbolOopDesc_4_pnNmethodOopDesc__; +text: .text%__1cNmethodOopDescPis_empty_method6kM_i_; +text: .text%__1cPClassFileParserYcheck_super_class_access6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cPClassFileParserbCcheck_super_interface_access6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cPClassFileParserbBcheck_final_method_override6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cTClassLoadingServiceTnotify_class_loaded6FpnNinstanceKlass_i_v_; +text: .text%__1cTClassLoadingServiceScompute_class_size6FpnNinstanceKlass__I_; +text: .text%__1cSinstanceKlassKlassIoop_size6kMpnHoopDesc__i_; +text: .text%__1cNinstanceKlassPoop_is_instance6kM_i_: instanceKlass.o; +text: .text%__1cRconstantPoolKlassIoop_size6kMpnHoopDesc__i_; +text: .text%__1cLClassLoaderLadd_package6Fpkci_i_; +text: .text%__1cLClassLoaderOlookup_package6Fpkc_pnLPackageInfo__; +text: .text%__1cQPackageHashtableMcompute_hash6Mpkci_I_: classLoader.o; +text: .text%__1cQPackageHashtableJget_entry6MiIpkcI_pnLPackageInfo__: classLoader.o; +text: .text%__1cMstringStream2T6M_v_; +text: .text%__1cSThreadProfilerMark2T6M_v_; +text: .text%__1cFVTuneOend_class_load6F_v_; +text: .text%__1cQSystemDictionaryVdefine_instance_class6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cQSystemDictionaryRcheck_constraints6FiInTinstanceKlassHandle_nGHandle_pnGThread__v_; +text: .text%__1cVLoaderConstraintTablePcheck_or_update6MnTinstanceKlassHandle_nGHandle_nMsymbolHandle__pkc_; +text: .text%__1cVLoaderConstraintTableWfind_loader_constraint6MnMsymbolHandle_nGHandle__ppnVLoaderConstraintEntry__; +text: .text%__1cQSystemDictionaryQadd_to_hierarchy6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cFKlassWappend_to_sibling_list6M_v_; +text: .text%__1cNinstanceKlassSprocess_interfaces6MpnGThread__v_; +text: .text%__1cIUniverseTflush_dependents_on6FnTinstanceKlassHandle__v_; +text: .text%__1cJCodeCachebKnumber_of_nmethods_with_dependencies6F_i_; +text: .text%__1cQSystemDictionaryRupdate_dictionary6FiIiInTinstanceKlassHandle_nGHandle_pnGThread__v_; +text: .text%__1cQSystemDictionaryQfind_placeholder6FiInMsymbolHandle_nGHandle__pnNsymbolOopDesc__; +text: .text%__1cQPlaceholderTableMremove_entry6MiInMsymbolHandle_nGHandle__v_; +text: .text%__1cKDictionaryJadd_klass6MnMsymbolHandle_nGHandle_nLKlassHandle__v_; +text: .text%__1cPTwoOopHashtableMcompute_hash6MnMsymbolHandle_nGHandle__I_: dictionary.o; +text: .text%__1cKDictionaryJnew_entry6MIpnMklassOopDesc_pnHoopDesc__pnPDictionaryEntry__; +text: .text%__1cNinstanceKlassQeager_initialize6MpnGThread__v_; +text: .text%__1cMObjectLocker2T6M_v_; +text: .text%__1cSObjectSynchronizerJfast_exit6FpnHoopDesc_pnJBasicLock_pnGThread__v_; +text: .text%__1cPClassFileParserbIparse_constant_pool_fieldref_entry6MnSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cPClassFileParserbSparse_constant_pool_interfacemethodref_entry6MnSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cPClassFileParserbEparse_constant_pool_long_entry6MnSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cPClassFileStreamGget_u86MpnGThread__X_; +text: .text%__1cSObjectSynchronizerKslow_enter6FnGHandle_pnJBasicLock_pnGThread__v_; +text: .text%__1cKJavaThreadNis_lock_owned6kMpC_i_; +text: .text%__1cGThreadLis_in_stack6kMpC_i_; +text: .text%__1cQSystemDictionaryVresolve_super_or_fail6FnMsymbolHandle_1nGHandle_2pnGThread__pnMklassOopDesc__; +text: .text%__1cNinstanceKlassZcan_be_primary_super_slow6kM_i_; +text: .text%__1cKReflectionTverify_class_access6FpnMklassOopDesc_2i_i_; +text: .text%__1cPClassFileParserbBcheck_illegal_static_method6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cPClassFileParserbJparse_classfile_signature_attribute6MnSconstantPoolHandle_nTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cPClassFileParserbCverify_legal_field_modifiers6MiipnGThread__v_; +text: .text%__1cPClassFileParserXverify_legal_field_name6MnMsymbolHandle_pnGThread__v_; +text: .text%__1cPClassFileParserbCverify_legal_field_signature6MnMsymbolHandle_1pnGThread__v_; +text: .text%__1cPClassFileParserWparse_field_attributes6MnSconstantPoolHandle_iHpHpi2pnPtypeArrayHandle_pnGThread__v_; +text: .text%__1cTconstantPoolOopDescbBbasic_type_for_signature_at6Mi_nJBasicType__; +text: .text%__1cJFieldTypeKbasic_type6FpnNsymbolOopDesc__nJBasicType__; +text: .text%__1cJchar2type6Fc_nJBasicType__: fieldType.o; +text: .text%__1cRSignatureIteratorSskip_optional_size6M_v_; +text: .text%__1cNSignatureInfoIdo_array6Mii_v_: frame.o; +text: .text%__1cPClassFileParserVparse_exception_table6MIInSconstantPoolHandle_pnGThread__nPtypeArrayHandle__; +text: .text%__1cNSignatureInfoHdo_bool6M_v_: frame.o; +text: .text%__1cNSignatureInfoHdo_char6M_v_: frame.o; +text: .text%__1cNSignatureInfoIdo_float6M_v_: frame.o; +text: .text%__1cNSignatureInfoJdo_double6M_v_: frame.o; +text: .text%__1cbDreorder_based_on_method_index6FpnPobjArrayOopDesc_1ppnHoopDesc__v_: methodOop.o; +text: .text%__1cLklassVtableYadd_new_mirandas_to_list6FpnNGrowableArray4CpnNmethodOopDesc___pnPobjArrayOopDesc_6pnMklassOopDesc__v_; +text: .text%__1cLklassVtableKis_miranda6FpnNmethodOopDesc_pnPobjArrayOopDesc_pnMklassOopDesc__i_; +text: .text%__1cWCountInterfacesClosureEdoit6MpnMklassOopDesc_i_v_: klassVtable.o; +text: .text%__1cPClassFileParserbNparse_classfile_inner_classes_attribute6MnSconstantPoolHandle_nTinstanceKlassHandle_pnGThread__H_; +text: .text%__1cPfieldDescriptorKinitialize6MpnMklassOopDesc_i_v_; +text: .text%__1cXinitialize_static_field6FpnPfieldDescriptor_pnGThread__v_: classFileParser.o; +text: .text%__1cPfieldDescriptorSlong_initial_value6kM_x_; +text: .text%__1cFKlassZcan_be_primary_super_slow6kM_i_; +text: .text%__1cSSetupItableClosureEdoit6MpnMklassOopDesc_i_v_: klassVtable.o; +text: .text%__1cNmethodOopDescWis_vanilla_constructor6kM_i_; +text: .text%__1cNinstanceKlassPadd_implementor6MpnMklassOopDesc__v_; +text: .text%__1cPClassFileParserXjava_lang_Class_fix_pre6MpnOobjArrayHandle_pnUFieldAllocationCount_pnGThread__v_; +text: .text%__1cPClassFileParserYjava_lang_Class_fix_post6Mpi_v_; +text: .text%__1cPfieldDescriptorRint_initial_value6kM_i_; +text: .text%__1cIUniverseNfixup_mirrors6FpnGThread__v_; +text: .text%__1cKSharedHeapYpermanent_object_iterate6MpnNObjectClosure__v_: genCollectedHeap.o; +text: .text%__1cHPermGenOobject_iterate6MpnNObjectClosure__v_: permGen.o; +text: .text%__1cRCompactingPermGenGas_gen6kM_pnKGeneration__: permGen.o; +text: .text%__1cbCOneContigSpaceCardGenerationOobject_iterate6MpnNObjectClosure__v_; +text: .text%__1cPContiguousSpaceOobject_iterate6MpnNObjectClosure__v_; +text: .text%__1cPContiguousSpaceTobject_iterate_from6MnJWaterMark_pnNObjectClosure__v_; +text: .text%__1cSFixupMirrorClosureJdo_object6MpnHoopDesc__v_: universe.o; +text: .text%__1cKklassKlassMoop_is_klass6kM_i_: klassKlass.o; +text: .text%__1cNinstanceKlassbBallocate_permanent_instance6MpnGThread__pnPinstanceOopDesc__; +text: .text%__1cNCollectedHeapWpermanent_obj_allocate6FnLKlassHandle_ipnGThread__pnHoopDesc__: instanceKlass.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: instanceKlass.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: instanceKlass.o; +text: .text%__1cKklassKlassIoop_size6kMpnHoopDesc__i_; +text: .text%__1cKklassKlassOklass_oop_size6kM_i_: klassKlass.o; +text: .text%__1cKklassKlassOklass_oop_size6kM_i_: arrayKlassKlass.o; +text: .text%__1cSobjArrayKlassKlassOklass_oop_size6kM_i_: objArrayKlassKlass.o; +text: .text%__1cSinstanceKlassKlassOklass_oop_size6kM_i_: instanceKlassKlass.o; +text: .text%__1cTtypeArrayKlassKlassOklass_oop_size6kM_i_: typeArrayKlassKlass.o; +text: .text%__1cLsymbolKlassOklass_oop_size6kM_i_: symbolKlass.o; +text: .text%__1cLsymbolKlassIoop_size6kMpnHoopDesc__i_; +text: .text%__1cKklassKlassMoop_is_klass6kM_i_: typeArrayKlassKlass.o; +text: .text%__1cTtypeArrayKlassKlassIoop_size6kMpnHoopDesc__i_: typeArrayKlassKlass.o; +text: .text%__1cKarrayKlassLobject_size6kMi_i_; +text: .text%__1cLmethodKlassOklass_oop_size6kM_i_: methodKlass.o; +text: .text%__1cQconstMethodKlassOklass_oop_size6kM_i_: constMethodKlass.o; +text: .text%__1cPmethodDataKlassOklass_oop_size6kM_i_: methodDataKlass.o; +text: .text%__1cKklassKlassMoop_is_klass6kM_i_: arrayKlassKlass.o; +text: .text%__1cRconstantPoolKlassOklass_oop_size6kM_i_: constantPoolKlass.o; +text: .text%__1cWconstantPoolCacheKlassOklass_oop_size6kM_i_: cpCacheKlass.o; +text: .text%__1cVcompiledICHolderKlassOklass_oop_size6kM_i_: compiledICHolderKlass.o; +text: .text%__1cKklassKlassMoop_is_klass6kM_i_: objArrayKlassKlass.o; +text: .text%__1cSobjArrayKlassKlassIoop_size6kMpnHoopDesc__i_: objArrayKlassKlass.o; +text: .text%__1cFKlassMoop_is_klass6kM_i_: typeArrayKlass.o; +text: .text%__1cFKlassMoop_is_klass6kM_i_: objArrayKlass.o; +text: .text%__1cFKlassMoop_is_klass6kM_i_: constantPoolKlass.o; +text: .text%__1cFKlassMoop_is_klass6kM_i_: constMethodKlass.o; +text: .text%__1cQconstMethodKlassIoop_size6kMpnHoopDesc__i_; +text: .text%__1cFKlassMoop_is_klass6kM_i_: methodKlass.o; +text: .text%__1cSinstanceKlassKlassMoop_is_klass6kM_i_: instanceKlassKlass.o; +text: .text%__1cFKlassMoop_is_klass6kM_i_: instanceKlass.o; +text: .text%__1cFKlassXsearch_secondary_supers6kMpnMklassOopDesc__i_; +text: .text%__1cPClassFileParserbFjava_lang_ref_Reference_fix_pre6MpnPtypeArrayHandle_nSconstantPoolHandle_pnUFieldAllocationCount_pnGThread__v_; +text: .text%__1cQinstanceRefKlassZupdate_nonstatic_oop_maps6FpnMklassOopDesc__v_; +text: .text%__1cQinstanceRefKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: instanceRefKlass.o; +text: .text%__1cNinstanceKlassOset_alloc_size6MI_v_: instanceRefKlass.o; +text: .text%__1cNinstanceKlassPoop_is_instance6kM_i_: instanceRefKlass.o; +text: .text%__1cKReflectionVis_same_class_package6FpnMklassOopDesc_2_i_; +text: .text%__1cNinstanceKlassVis_same_class_package6MpnMklassOopDesc__i_; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: instanceRefKlass.o; +text: .text%__1cNinstanceKlassVis_same_class_package6FpnHoopDesc_pnNsymbolOopDesc_24_i_; +text: .text%__1cEUTF8Hstrrchr6FpWiW_1_; +text: .text%__1cEUTF8Fequal6FpWi1i_i_; +text: .text%__1cPClassFileParserbFparse_constant_pool_float_entry6MnSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cNSignatureInfoHdo_byte6M_v_: frame.o; +text: .text%__1cNSignatureInfoIdo_short6M_v_: frame.o; +text: .text%__1cRappend_interfaces6FnOobjArrayHandle_ripnPobjArrayOopDesc__v_; +text: .text%__1cQSystemDictionaryPresolve_or_null6FnMsymbolHandle_pnGThread__pnMklassOopDesc__; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: instanceKlass.o; +text: .text%__1cPfieldDescriptorTfloat_initial_value6kM_f_; +text: .text%__1cPClassFileParserbGparse_constant_pool_double_entry6MnSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cPfieldDescriptorUdouble_initial_value6kM_d_; +text: .text%__1cQSystemDictionarybDinitialize_basic_type_mirrors6FpnGThread__v_; +text: .text%__1cPjava_lang_ClassYcreate_basic_type_mirror6FpkcpnGThread__pnHoopDesc__; +text: .text%__1cNobjArrayKlassZcan_be_primary_super_slow6kM_i_; +text: .text%__1cXreferenceProcessor_init6F_v_; +text: .text%__1cSReferenceProcessorMinit_statics6F_v_; +text: .text%__1cbBjava_lang_ref_SoftReferenceJset_clock6Fx_v_; +text: .text%__1cQjni_handles_init6F_v_; +text: .text%__1cKJNIHandlesKinitialize6F_v_; +text: .text%__1cOvmStructs_init6F_v_; +text: .text%__1cVverificationType_init6F_v_; +text: .text%__1cQVerificationTypeKinitialize6F_v_; +text: .text%__1cOcompiler1_init6F_v_; +text: .text%__1cKSharedInfoKset_stack06Fi_v_; +text: .text%__1cKSharedInfoLset_regName6F_v_; +text: .text%__1cIRegAllocYinit_register_allocation6F_v_; +text: .text%__1cIFrameMapEinit6F_v_; +text: .text%__1cKc1_RegMaskKinit_masks6Fi_v_; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_FrameMap_x86.o; +text: .text%__1cNc1_AllocTableLinit_tables6F_v_; +text: .text%__1cIFrameMapOfirst_register6F_pnMRegisterImpl__; +text: .text%__1cIFrameMapLcpu_reg2rnr6FpnMRegisterImpl__i_; +text: .text%__1cIFrameMapLcpu_rnr2reg6Fi_pnMRegisterImpl__; +text: .text%__1cIRuntime1Kinitialize6F_v_; +text: .text%__1cKCodeBufferRinsts_memory_size6Fi_i_; +text: .text%__1cKCodeBufferQlocs_memory_size6Fi_i_; +text: .text%__1cIRuntime1Ninitialize_pd6F_v_; +text: .text%__1cNSharedRuntimeTgenerate_deopt_blob6F_v_; +text: .text%__1cKCodeBuffer2t6MiiiiiipnKBufferBlob_pnJrelocInfo_pnORelocateBuffer_ipnLOopRecorder_pkcii_v_; +text: .text%__1cKCodeBufferQalloc_relocation6MI_v_; +text: .text%__1cJOopMapSet2t6M_v_; +text: .text%__1cJAssemblerEsubl6MnHAddress_i_v_; +text: .text%__1cTsave_live_registers6FpnOMacroAssembler_i_pnGOopMap__: c1_Runtime1_x86.o; +text: .text%__1cJAssemblerGfldenv6MnHAddress__v_; +text: .text%__1cGOopMap2t6Mii_v_; +text: .text%__1cGOopMapQset_callee_saved6MnHOptoRegEName_ii2_v_; +text: .text%__1cGOopMapHset_xxx6MnHOptoRegEName_nLOopMapValueJoop_types_ii2_v_; +text: .text%__1cGOopMapbEmap_compiler_reg_to_oopmap_reg6MnHOptoRegEName_ii_nFVMRegEName__; +text: .text%__1cVCompressedWriteStreamJwrite_int6Mi_v_: oopMap.o; +text: .text%__1cIFrameMapRfpu_stack_regname6Fi_nHOptoRegEName__; +text: .text%__1cKRelocationJpack_data6M_i_: codeBlob.o; +text: .text%__1cJrelocInfoNfinish_prefix6Mph_p0_; +text: .text%__1cJrelocInfo2t6Mn0AJrelocType_ii_v_; +text: .text%__1cOMacroAssemblerTset_last_Java_frame6MpnMRegisterImpl_22pC_v_; +text: .text%__1cJOopMapSetKadd_gc_map6MiipnGOopMap__v_; +text: .text%__1cOMacroAssemblerVreset_last_Java_frame6MpnMRegisterImpl_i_v_; +text: .text%__1cJAssemblerEdecl6MnHAddress__v_; +text: .text%__1cSDeoptimizationBlobGcreate6FpnKCodeBuffer_pnJOopMapSet_iiii_p0_; +text: .text%__1cICodeBlobPallocation_size6FpnKCodeBuffer_ii_I_; +text: .text%__1cNRelocIteratorTlocs_and_index_size6Fii_i_; +text: .text%__1cSDeoptimizationBlob2n6FII_pv_; +text: .text%__1cSDeoptimizationBlob2t6MpnKCodeBuffer_ipnJOopMapSet_iiii_v_; +text: .text%__1cICodeBlob2t6MpkcpnKCodeBuffer_iiipnJOopMapSet_i_v_; +text: .text%__1cKCodeBufferPcopy_relocation6MpnICodeBlob__v_; +text: .text%__1cNRelocIteratorMcreate_index6FpnKCodeBuffer_pnJrelocInfo_4_4_; +text: .text%__1cKCodeBufferJcopy_code6MpnICodeBlob__v_; +text: .text%__1cRAbstractAssemblerOcode_fill_byte6F_i_; +text: .text%__1cICodeBlobWfix_relocation_at_move6Mi_v_; +text: .text%__1cNRelocIteratorKinitialize6MipnICodeBlob_pC3_v_; +text: .text%__1cNRelocIteratorKset_limits6MpC1_v_; +text: .text%__1cVPatchingRelocIteratorHprepass6M_v_; +text: .text%__1cNRelocIteratorEnext6M_i_: relocInfo.o; +text: .text%__1cNRelocIteratorEnext6M_i_: codeBlob.o; +text: .text%__1cNRelocIteratorFreloc6M_pnKRelocation__; +text: .text%__1cOCallRelocationWfix_relocation_at_move6Mi_v_; +text: .text%__1cOCallRelocationFvalue6M_pC_: codeBlob.o; +text: .text%__1cKRelocationTpd_call_destination6M_pC_; +text: .text%__1cKNativeCallLdestination6kM_pC_; +text: .text%__1cOCallRelocationPset_destination6MpCi_v_; +text: .text%__1cKRelocationXpd_set_call_destination6MpCi_v_; +text: .text%__1cRNativeInstructionFwrote6Mi_v_; +text: .text%__1cKRelocationLunpack_data6M_v_: relocInfo.o; +text: .text%__1cKRelocationWfix_relocation_at_move6Mi_v_: relocInfo.o; +text: .text%__1cVPatchingRelocIteratorIpostpass6M_v_; +text: .text%__1cJOopMapSetJheap_size6kM_i_; +text: .text%__1cGOopMapJheap_size6kM_i_; +text: .text%__1cJOopMapSetHcopy_to6MpC_v_; +text: .text%__1cGOopMapHcopy_to6MpC_v_; +text: .text%__1cIRuntime1Rgenerate_blob_for6Fn0AGStubID__v_; +text: .text%__1cIRuntime1Pnew_code_buffer6F_pnKCodeBuffer__; +text: .text%__1cLOopRecorder2t6MpnFArena__v_; +text: .text%__1cNStubAssembler2t6MpnKCodeBuffer__v_; +text: .text%__1cIRuntime1Rgenerate_code_for6Fn0AGStubID_pnNStubAssembler_pi_pnJOopMapSet__; +text: .text%__1cIRuntime1Iname_for6Fn0AGStubID__pkc_; +text: .text%__1cLRuntimeStubQnew_runtime_stub6FpkcpnKCodeBuffer_ipnJOopMapSet_i_p0_; +text: .text%__1cLRuntimeStub2n6FII_pv_; +text: .text%__1cLRuntimeStub2t6MpkcpnKCodeBuffer_iipnJOopMapSet_i_v_; +text: .text%__1cJStubFrame2t6MpnNStubAssembler_pkci_v_; +text: .text%__1cNStubAssemblerIset_info6Mpkci_v_; +text: .text%__1cNStubAssemblerHcall_RT6MpnMRegisterImpl_2pC2_i_; +text: .text%__1cNStubAssemblerHcall_RT6MpnMRegisterImpl_2pCi_i_; +text: .text%__1cJStubFrame2T6M_v_; +text: .text%__1cIRuntime1Ygenerate_exception_throw6FpnNStubAssembler_pCpnMRegisterImpl__pnJOopMapSet__; +text: .text%__1cOMacroAssemblerLtlab_refill6MrnFLabel_22_v_; +text: .text%__1cLlog2_intptr6Fi_i_: assembler_x86.o; +text: .text%__1cOMacroAssemblerNeden_allocate6MpnMRegisterImpl_2i2rnFLabel__v_; +text: .text%__1cOMacroAssemblerLverify_tlab6M_v_; +text: .text%__1cLlog2_intptr6Fi_i_: c1_Runtime1_x86.o; +text: .text%__1cOMacroAssemblerNtlab_allocate6MpnMRegisterImpl_2i22rnFLabel__v_; +text: .text%__1cRC1_MacroAssemblerRinitialize_object6MpnMRegisterImpl_22i22_v_; +text: .text%__1cRC1_MacroAssemblerRinitialize_header6MpnMRegisterImpl_22_v_; +text: .text%__1cRC1_MacroAssemblerPinitialize_body6MpnMRegisterImpl_2i2_v_; +text: .text%__1cNStubAssemblerHcall_RT6MpnMRegisterImpl_2pC22_i_; +text: .text%__1cNStubAssemblerHcall_RT6MpnMRegisterImpl_2pC222_i_; +text: .text%__1cIRuntime1Iblob_for6Fn0AGStubID__pnICodeBlob__; +text: .text%__1cJStubFrame2t6MpnNStubAssembler_pkcipnMRegisterImpl_6_v_; +text: .text%__1cJStubFrame2t6MpnNStubAssembler_pkcipnMRegisterImpl__v_; +text: .text%__1cIiEntries2t6Miiii_v_; +text: .text%__1cRNativeGeneralJumpQjump_destination6kM_pC_; +text: .text%__1cJAssemblerOlocate_operand6FpCn0AMWhichOperand__1_; +text: .text%__1cIRuntime1Rgenerate_patching6FpnNStubAssembler_pC_pnJOopMapSet__; +text: .text%__1cWrestore_live_registers6FpnOMacroAssembler__v_: c1_Runtime1_x86.o; +text: .text%__1cNSafepointBlobGcreate6FpnKCodeBuffer_pnJOopMapSet_i_p0_; +text: .text%__1cNSafepointBlob2n6FII_pv_; +text: .text%__1cNSafepointBlob2t6MpnKCodeBuffer_ipnJOopMapSet_i_v_; +text: .text%__1cJAssemblerFfldcw6MnHAddress__v_; +text: .text%__1cJAssemblerGfnstcw6MnHAddress__v_; +text: .text%__1cJAssemblerHfcomp_d6MnHAddress__v_; +text: .text%__1cIiEntriesIset_base6MpC_v_; +text: .text%__1cQvtableStubs_init6F_v_; +text: .text%__1cLVtableStubsKinitialize6F_v_; +text: .text%__1cWInlineCacheBuffer_init6F_v_; +text: .text%__1cRInlineCacheBufferKinitialize6F_v_; +text: .text%__1cRInlineCacheBufferOinit_next_stub6F_v_; +text: .text%__1cRInlineCacheBufferRic_stub_code_size6F_i_; +text: .text%__1cJStubQdDueueRrequest_committed6Mi_pnEStub__; +text: .text%__1cPICStubInterfaceRcode_size_to_size6kMi_i_: icBuffer.o; +text: .text%__1cPICStubInterfaceKinitialize6MpnEStub_i_v_: icBuffer.o; +text: .text%__1cTcompilerOracle_init6F_v_; +text: .text%__1cOCompilerOracleRparse_from_string6Fpkc_v_; +text: .text%__1cOCompilerOracleOread_from_line6Fpc_v_; +text: .text%__1cOCompilerOraclePparse_from_file6F_v_; +text: .text%__1cHcc_file6F_pkc_: compilerOracle.o; +text: .text%__1cXonStackReplacement_init6F_v_; +text: .text%__1cSOnStackReplacementKinitialize6F_v_; +text: .text%__1cUGenericGrowableArrayPraw_at_put_grow6MipknEGrET_3_v_; +text: .text%__1cWcompilationPolicy_init6F_v_; +text: .text%__1cSuniverse_post_init6F_v_; +text: .text%__1cIUniverseWreinitialize_vtable_of6FpnFKlass_pnGThread__v_; +text: .text%__1cNinstanceKlassGvtable6kM_pnLklassVtable__; +text: .text%__1cNinstanceKlassKjava_super6kM_pnMklassOopDesc__: instanceKlass.o; +text: .text%__1cLklassVtableVinitialize_from_super6MnLKlassHandle__i_; +text: .text%__1cFKlassMoop_is_array6kM_i_: instanceKlass.o; +text: .text%__1cLklassVtableTupdate_super_vtable6MpnNinstanceKlass_pnNmethodOopDesc_i_i_; +text: .text%__1cLklassVtableNput_method_at6MpnNmethodOopDesc_i_v_; +text: .text%__1cLklassVtableQfill_in_mirandas6Mri_v_; +text: .text%__1cFKlassIsubklass6kM_p0_; +text: .text%__1cLklassVtableOcopy_vtable_to6MpnLvtableEntry__v_; +text: .text%__1cLklassVtableXvtable_accessibility_at6Mi_n0AKAccessType__; +text: .text%__1cFKlassMnext_sibling6kM_p0_; +text: .text%__1cKarrayKlassMoop_is_array6kM_i_: objArrayKlass.o; +text: .text%__1cFKlassPoop_is_instance6kM_i_: objArrayKlass.o; +text: .text%__1cKarrayKlassMoop_is_array6kM_i_: constantPoolKlass.o; +text: .text%__1cFKlassPoop_is_instance6kM_i_: constantPoolKlass.o; +text: .text%__1cKarrayKlassMoop_is_array6kM_i_: typeArrayKlass.o; +text: .text%__1cNinstanceKlassKjava_super6kM_pnMklassOopDesc__: instanceRefKlass.o; +text: .text%__1cFKlassMoop_is_array6kM_i_: instanceRefKlass.o; +text: .text%__1cIUniverseUreinitialize_itables6F_v_; +text: .text%__1cQSystemDictionaryKclasses_do6FpFpnMklassOopDesc__v_v_; +text: .text%__1cKDictionaryKclasses_do6MpFpnMklassOopDesc__v_v_; +text: .text%__1cbBinitialize_itable_for_klass6FpnMklassOopDesc__v_; +text: .text%__1cNinstanceKlassGitable6kM_pnLklassItable__; +text: .text%__1cLklassItable2t6MnTinstanceKlassHandle__v_; +text: .text%__1cLklassItableRinitialize_itable6M_v_; +text: .text%__1cLklassItablebFinitialize_itable_for_interface6MpnMklassOopDesc_pnRitableMethodEntry__v_; +text: .text%__1cRitableMethodEntryKinitialize6MpnNmethodOopDesc__v_; +text: .text%__1cKoopFactoryMnew_objArray6FpnMklassOopDesc_ipnGThread__pnPobjArrayOopDesc__; +text: .text%__1cNinstanceKlassRallocate_objArray6MiipnGThread__pnPobjArrayOopDesc__; +text: .text%__1cNinstanceKlassQarray_klass_impl6MiipnGThread__pnMklassOopDesc__; +text: .text%__1cNinstanceKlassQarray_klass_impl6FnTinstanceKlassHandle_iipnGThread__pnMklassOopDesc__; +text: .text%__1cFKlassTarray_klass_or_null6M_pnMklassOopDesc__; +text: .text%__1cNinstanceKlassQarray_klass_impl6MipnGThread__pnMklassOopDesc__; +text: .text%__1cFKlassNoop_is_symbol6kM_i_: instanceKlass.o; +text: .text%__1cNobjArrayKlassQarray_klass_impl6MiipnGThread__pnMklassOopDesc__; +text: .text%__1cNobjArrayKlassQarray_klass_impl6FnTobjArrayKlassHandle_iipnGThread__pnMklassOopDesc__; +text: .text%__1cFKlassTarray_klass_or_null6Mi_pnMklassOopDesc__; +text: .text%__1cNCollectedHeapOarray_allocate6FnLKlassHandle_iipnGThread__pnHoopDesc__: instanceKlass.o; +text: .text%__1cNCollectedHeapYcommon_mem_allocate_init6FIipnGThread__pnIHeapWord__: instanceKlass.o; +text: .text%__1cNCollectedHeapXallocate_from_tlab_slow6FpnGThread_I_pnIHeapWord__; +text: .text%__1cQGenCollectedHeapVunsafe_max_tlab_alloc6kM_I_; +text: .text%__1cQDefNewGenerationVunsafe_max_tlab_alloc6kM_I_: defNewGeneration.o; +text: .text%__1cQDefNewGenerationVunsafe_max_alloc_nogc6kM_I_; +text: .text%__1cPContiguousSpaceEfree6kM_I_: space.o; +text: .text%__1cWThreadLocalAllocBufferXclear_before_allocation6M_v_; +text: .text%__1cWThreadLocalAllocBufferFreset6M_v_; +text: .text%__1cQGenCollectedHeapRallocate_new_tlab6MI_pnIHeapWord__; +text: .text%__1cQGenCollectedHeapMmem_allocate6MIii_pnIHeapWord__; +text: .text%__1cbCTwoGenerationCollectorPolicyRmem_allocate_work6MIii_pnIHeapWord__; +text: .text%__1cQGenCollectedHeapEheap6F_p0_; +text: .text%__1cQDefNewGenerationPshould_allocate6MIii_i_: defNewGeneration.o; +text: .text%__1cQDefNewGenerationMpar_allocate6MIii_pnIHeapWord__: defNewGeneration.o; +text: .text%__1cJEdenSpaceMpar_allocate6MI_pnIHeapWord__; +text: .text%__1cPContiguousSpaceRpar_allocate_impl6MIkpnIHeapWord__2_: space.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: collectedHeap.o; +text: .text%__1cWThreadLocalAllocBufferEfill6MpnIHeapWord_2I_v_; +text: .text%__1cQjava_lang_StringPcreate_from_str6FpkcpnGThread__nGHandle__; +text: .text%__1cQjava_lang_StringTcreate_oop_from_str6FpkcpnGThread__pnHoopDesc__; +text: .text%__1cKoopFactoryNnew_charArray6FpkcpnGThread__pnQtypeArrayOopDesc__; +text: .text%__1cEUTF8Ounicode_length6Fpkc_i_; +text: .text%__1cEUTF8Enext6FpkcpH_pc_; +text: .text%__1cOtypeArrayKlassIallocate6MipnGThread__pnQtypeArrayOopDesc__; +text: .text%__1cQGenCollectedHeapVlarge_typearray_limit6M_I_; +text: .text%__1cbCTwoGenerationCollectorPolicyYis_two_generation_policy6M_i_: collectorPolicy.o; +text: .text%__1cbCTwoGenerationCollectorPolicyVlarge_typearray_limit6M_I_; +text: .text%__1cNCollectedHeapOarray_allocate6FnLKlassHandle_iipnGThread__pnHoopDesc__: typeArrayKlass.o; +text: .text%__1cNCollectedHeapYcommon_mem_allocate_init6FIipnGThread__pnIHeapWord__: typeArrayKlass.o; +text: .text%__1cEUTF8Sconvert_to_unicode6FpkcpHi_v_; +text: .text%__1cQjava_lang_StringQbasic_create_oop6FpnQtypeArrayOopDesc_ipnGThread__pnHoopDesc__; +text: .text%__1cNinstanceKlassRallocate_instance6MpnGThread__pnPinstanceOopDesc__; +text: .text%__1cNCollectedHeapMobj_allocate6FnLKlassHandle_ipnGThread__pnHoopDesc__: instanceKlass.o; +text: .text%__1cTjava_lang_ThrowableLset_message6FpnHoopDesc_2_v_; +text: .text%__1cNinstanceKlassKlink_class6MpnGThread__v_; +text: .text%__1cNinstanceKlassPlink_class_impl6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cNinstanceKlassLverify_code6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cIVerifierRverify_byte_codes6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cNinstanceKlassWadd_loader_constraints6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cNinstanceKlassNrewrite_class6MpnGThread__v_; +text: .text%__1cIRewriterHrewrite6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cIRewriterScompute_index_maps6FnSconstantPoolHandle_rpnIintArray_rpnIintStack__v_; +text: .text%__1cIintArray2t6Mki1_v_: rewriter.o; +text: .text%__1cIRewriterXnew_constant_pool_cache6FrnIintArray_pnGThread__nXconstantPoolCacheHandle__; +text: .text%__1cKoopFactoryVnew_constantPoolCache6FipnGThread__pnYconstantPoolCacheOopDesc__; +text: .text%__1cWconstantPoolCacheKlassIallocate6MipnGThread__pnYconstantPoolCacheOopDesc__; +text: .text%__1cNCollectedHeapYpermanent_array_allocate6FnLKlassHandle_iipnGThread__pnHoopDesc__: cpCacheKlass.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: cpCacheKlass.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: cpCacheKlass.o; +text: .text%__1cYconstantPoolCacheOopDescKinitialize6MrnIintArray__v_; +text: .text%__1cWConstantPoolCacheEntryRset_initial_state6Mi_v_; +text: .text%__1cIRewriterOrewrite_method6FnMmethodHandle_rnIintArray_pnGThread__1_; +text: .text%__1cNmethodOopDescLlink_method6FnMmethodHandle__v_; +text: .text%__1cTAbstractInterpreterLmethod_kind6FnMmethodHandle__n0AKMethodKind__; +text: .text%__1cNmethodOopDescbGupdate_compiled_code_entry_point6Mi_v_; +text: .text%__1cIRuntime1Mientries_for6FnMmethodHandle__pnIiEntries__; +text: .text%__1cNmethodOopDescLis_accessor6kM_i_; +text: .text%__1cNmethodOopDescMintrinsic_id6kM_n0ALIntrinsicId__; +text: .text%__1cQSystemDictionaryXcheck_signature_loaders6FnMsymbolHandle_nGHandle_2ipnGThread__v_; +text: .text%__1cNSharedRuntimebIinitialize_StrictMath_entry_points6F_v_; +text: .text%__1cNSharedRuntimeUlookup_function_DD_D6FrpFpnHJNIEnv__pnH_jclass_dd_dpkc_v_; +text: .text%__1cMNativeLookupTbase_library_lookup6Fpkc22_pC_; +text: .text%__1cMNativeLookupGlookup6FnMmethodHandle_ripnGThread__pC_; +text: .text%__1cNmethodOopDescThas_native_function6kM_i_; +text: .text%__1cMNativeLookupLlookup_base6FnMmethodHandle_ripnGThread__pC_; +text: .text%__1cMNativeLookupNpure_jni_name6FnMmethodHandle__pc_; +text: .text%__1cMoutputStreamFprint6MpkcE_v_; +text: .text%__1cMoutputStreamMdo_vsnprintf6FpcIpkcpvirI_3_; +text: .text%__1cNmethodOopDescKklass_name6kM_pnNsymbolOopDesc__; +text: .text%__1cOmangle_name_on6FpnMoutputStream_pnNsymbolOopDesc__v_: nativeLookup.o; +text: .text%__1cOmangle_name_on6FpnMoutputStream_pnNsymbolOopDesc_ii_v_: nativeLookup.o; +text: .text%__1cMoutputStreamDput6Mc_v_; +text: .text%__1cMNativeLookupMlookup_style6FnMmethodHandle_pcpkciiripnGThread__pC_; +text: .text%__1cCosYprint_jni_name_prefix_on6FpnMoutputStream_i_v_; +text: .text%__1cCosYprint_jni_name_suffix_on6FpnMoutputStream_i_v_; +text: .text%__1cVlookup_special_native6Fpc_pC_: nativeLookup.o; +text: .text%__1cbEinitialize_converter_functions6F_v_; +text: .text%__1cIUniverseWupdate_heap_info_at_gc6F_v_; +text: .text%__1cQGenCollectedHeapIcapacity6kM_I_; +text: .text%__1cQDefNewGenerationIcapacity6kM_I_; +text: .text%__1cQGenCollectedHeapEused6kM_I_; +text: .text%__1cQDefNewGenerationEused6kM_I_; +text: .text%__1cbCOneContigSpaceCardGenerationEused6kM_I_; +text: .text%__1cQGenCollectedHeapPpost_initialize6M_v_; +text: .text%__1cQGenCollectedHeapTref_processing_init6M_v_; +text: .text%__1cKSharedHeapTref_processing_init6M_v_; +text: .text%__1cKGenerationSref_processor_init6M_v_; +text: .text%__1cKGenerationYrefs_discovery_is_atomic6kM_i_: compactingPermGenGen.o; +text: .text%__1cKGenerationUrefs_discovery_is_mt6kM_i_: compactingPermGenGen.o; +text: .text%__1cSReferenceProcessor2t6MnJMemRegion_iii_v_; +text: .text%__1cKGenerationYrefs_discovery_is_atomic6kM_i_: defNewGeneration.o; +text: .text%__1cKGenerationUrefs_discovery_is_mt6kM_i_: defNewGeneration.o; +text: .text%__1cKGenerationYrefs_discovery_is_atomic6kM_i_: tenuredGeneration.o; +text: .text%__1cKGenerationUrefs_discovery_is_mt6kM_i_: tenuredGeneration.o; +text: .text%__1cNMemoryServiceRset_universe_heap6FpnNCollectedHeap__v_; +text: .text%__1cQGenCollectedHeapEkind6M_nNCollectedHeapEName__: genCollectedHeap.o; +text: .text%__1cNMemoryServicebBadd_gen_collected_heap_info6FpnQGenCollectedHeap__v_; +text: .text%__1cPMarkSweepPolicyUis_mark_sweep_policy6M_i_: collectorPolicy.o; +text: .text%__1cNMemoryManagerXget_copy_memory_manager6F_pnPGCMemoryManager__; +text: .text%__1cPGCMemoryManager2t6M_v_; +text: .text%__1cNMemoryManagerWget_msc_memory_manager6F_pnPGCMemoryManager__; +text: .text%__1cNMemoryServicebAadd_generation_memory_pool6FpnKGeneration_pnNMemoryManager_4_v_; +text: .text%__1cQDefNewGenerationEkind6M_nKGenerationEName__: defNewGeneration.o; +text: .text%__1cNMemoryServiceJadd_space6FpnPContiguousSpace_pkciIi_pnKMemoryPool__; +text: .text%__1cTContiguousSpacePool2t6MpnPContiguousSpace_pkcnKMemoryPoolIPoolType_Ii_v_; +text: .text%__1cNMemoryServiceTadd_survivor_spaces6FpnQDefNewGeneration_pkciIi_pnKMemoryPool__; +text: .text%__1cbBSurvivorContiguousSpacePool2t6MpnQDefNewGeneration_pkcnKMemoryPoolIPoolType_Ii_v_; +text: .text%__1cRTenuredGenerationEkind6M_nKGenerationEName__: tenuredGeneration.o; +text: .text%__1cNMemoryServiceHadd_gen6FpnKGeneration_pkcii_pnKMemoryPool__; +text: .text%__1cOGenerationPool2t6MpnKGeneration_pkcnKMemoryPoolIPoolType_i_v_; +text: .text%__1cKGenerationMmax_capacity6kM_I_; +text: .text%__1cNMemoryServicebGadd_compact_perm_gen_memory_pool6FpnUCompactingPermGenGen_pnNMemoryManager__v_; +text: .text%__1cQGenCollectedHeapNgc_threads_do6kMpnNThreadClosure__v_; +text: .text%__1cPGCMemoryManagerXinitialize_gc_stat_info6M_v_; +text: .text%__1cKGCStatInfo2t6Mi_v_; +text: .text%__1cQjavaClasses_init6F_v_; +text: .text%__1cLJavaClassesPcompute_offsets6F_v_; +text: .text%__1cQjava_lang_SystemPcompute_offsets6F_v_; +text: .text%__1cQjava_lang_ThreadPcompute_offsets6F_v_; +text: .text%__1cNinstanceKlassQfind_local_field6kMpnNsymbolOopDesc_2pnPfieldDescriptor__i_; +text: .text%__1cVjava_lang_ThreadGroupPcompute_offsets6F_v_; +text: .text%__1cbIjava_security_AccessControlContextPcompute_offsets6F_v_; +text: .text%__1cbIjava_lang_reflect_AccessibleObjectPcompute_offsets6F_v_; +text: .text%__1cYjava_lang_reflect_MethodPcompute_offsets6F_v_; +text: .text%__1cbDjava_lang_reflect_ConstructorPcompute_offsets6F_v_; +text: .text%__1cXjava_lang_reflect_FieldPcompute_offsets6F_v_; +text: .text%__1cPjava_nio_BufferPcompute_offsets6F_v_; +text: .text%__1cYsun_reflect_ConstantPoolPcompute_offsets6F_v_; +text: .text%__1cZsun_misc_AtomicLongCSImplPcompute_offsets6F_v_; +text: .text%__1cSstubRoutines_init26F_v_; +text: .text%__1cMStubRoutinesLinitialize26F_v_; +text: .text%__1cNStubGeneratorYgenerate_throw_exception6MpkcpCi_3_: stubGenerator_x86.o; +text: .text%__1cNStubGeneratorTgenerate_verify_oop6M_pC_: stubGenerator_x86.o; +text: .text%__1cJAssemblerEincl6MnHAddress__v_; +text: .text%__1cHThreadsDadd6FpnKJavaThread_i_v_; +text: .text%__1cNThreadServiceKadd_thread6FpnKJavaThread_i_v_; +text: .text%__1cGThreadbCis_hidden_from_external_view6kM_i_: thread.o; +text: .text%__1cGThreadVis_jvmti_agent_thread6kM_i_: thread.o; +text: .text%__1cGEventsDlog6FpkcE_v_: thread.o; +text: .text%__1cLJvmtiExportbMtransition_pending_onload_raw_monitors6F_v_; +text: .text%__1cUJvmtiPendingMonitorsXtransition_raw_monitors6F_v_; +text: .text%__1cUGenericGrowableArrayUclear_and_deallocate6M_v_; +text: .text%__1cIVMThreadGcreate6F_v_; +text: .text%__1cIVMThread2t6M_v_; +text: .text%__1cQVMOperationQdDueue2t6M_v_; +text: .text%__1cCosNcreate_thread6FpnGThread_n0AKThreadType_I_i_; +text: .text%__1cCosMstart_thread6FpnGThread__v_; +text: .text%__1cCosPpd_start_thread6FpnGThread__v_; +text: .text%__1cHMonitorEwait6Mil_i_; +text: .text%_start: os_solaris.o; +text: .text%__1cCosTset_native_priority6FpnGThread_i_nIOSReturn__; +text: .text%__1cQset_lwp_priority6Fiii_i_; +text: .text%__1cVscale_to_lwp_priority6Fiii_i_: os_solaris.o; +text: .text%__1cIVMThreadMis_VM_thread6kM_i_: vmThread.o; +text: .text%__1cIVMThreadDrun6M_v_; +text: .text%__1cHMonitorGnotify6M_i_; +text: .text%__1cIVMThreadEloop6M_v_; +text: .text%__1cQVMOperationQdDueueLremove_next6M_pnMVM_Operation__; +text: .text%__1cQVMOperationQdDueueLqueue_empty6Mi_i_; +text: .text%__1cQVMOperationQdDueueSqueue_remove_front6Mi_pnMVM_Operation__; +text: .text%__1cLJvmtiExportRenter_start_phase6F_v_; +text: .text%__1cLJvmtiExportNpost_vm_start6F_v_; +text: .text%__1cUJvmtiEventControllerIvm_start6F_v_; +text: .text%__1cQinitialize_class6FnMsymbolHandle_pnGThread__v_: thread.o; +text: .text%__1cNinstanceKlassKinitialize6MpnGThread__v_; +text: .text%__1cNinstanceKlassVshould_be_initialized6kM_i_; +text: .text%__1cNinstanceKlassPinitialize_impl6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cNinstanceKlassWcall_class_initializer6MpnGThread__v_; +text: .text%__1cNinstanceKlassbBcall_class_initializer_impl6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cNinstanceKlassRclass_initializer6M_pnNmethodOopDesc__; +text: .text%__1cJJavaCallsEcall6FpnJJavaValue_nMmethodHandle_pnRJavaCallArguments_pnGThread__v_; +text: .text%__1cCosUos_exception_wrapper6FpFpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v2468_v_; +text: .text%__1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v_; +text: .text%__1cRCompilationPolicyOmustBeCompiled6FnMmethodHandle__i_; +text: .text%__1cRCompilationPolicyNcanBeCompiled6FnMmethodHandle__i_; +text: .text%__1cNmethodOopDescRis_not_compilable6kMi_i_; +text: .text%__1cRruntime_type_from6FpnJJavaValue__nJBasicType__: javaCalls.o; +text: .text%__1cCosbCstack_shadow_pages_available6FpnGThread_nMmethodHandle__i_; +text: .text%__1cTAbstractInterpreterbFsize_top_interpreter_activation6FpnNmethodOopDesc__i_; +text: .text%__1cPJavaCallWrapper2t6MnMmethodHandle_nGHandle_pnJJavaValue_pnGThread__v_; +text: .text%__1cGThreadSis_Compiler_thread6kM_i_: thread.o; +text: .text%__1cGThreadXclear_pending_exception6M_v_; +text: .text%__1cRJavaCallArgumentsKparameters6M_pi_; +text: .text%__1cSInterpreterRuntimeOresolve_invoke6FpnKJavaThread_nJBytecodesECode__v_; +text: .text%__1cKJavaThreadPcook_last_frame6MnFframe__1_; +text: .text%__1cFframeYinterpreter_frame_method6kM_pnNmethodOopDesc__; +text: .text%__1cFframeVinterpreter_frame_bcp6kM_pC_; +text: .text%__1cMLinkResolverOresolve_invoke6FrnICallInfo_nGHandle_nSconstantPoolHandle_inJBytecodesECode_pnGThread__v_; +text: .text%__1cMLinkResolverUresolve_invokestatic6FrnICallInfo_nSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cMLinkResolverMresolve_pool6FrnLKlassHandle_rnMsymbolHandle_42nSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cMLinkResolverNresolve_klass6FrnLKlassHandle_nSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cTconstantPoolOopDescMklass_ref_at6MipnGThread__pnMklassOopDesc__; +text: .text%__1cTconstantPoolOopDescNklass_at_impl6FnSconstantPoolHandle_ipnGThread__pnMklassOopDesc__; +text: .text%__1cNinstanceKlassRprotection_domain6M_pnHoopDesc__: instanceKlass.o; +text: .text%__1cTconstantPoolOopDescbCverify_constant_pool_resolve6FnSconstantPoolHandle_nLKlassHandle_pnGThread__v_; +text: .text%__1cMLinkResolverZcheck_klass_accessability6FnLKlassHandle_1pnGThread__v_; +text: .text%__1cTconstantPoolOopDescMklass_at_put6MipnMklassOopDesc__v_: constantPoolOop.o; +text: .text%__1cTconstantPoolOopDescLname_ref_at6Mi_pnNsymbolOopDesc__; +text: .text%__1cTconstantPoolOopDescQsignature_ref_at6Mi_pnNsymbolOopDesc__; +text: .text%__1cMLinkResolverTresolve_static_call6FrnICallInfo_rnLKlassHandle_nMsymbolHandle_53iipnGThread__v_; +text: .text%__1cMLinkResolverbElinktime_resolve_static_method6FrnMmethodHandle_nLKlassHandle_nMsymbolHandle_43ipnGThread__v_; +text: .text%__1cMLinkResolverOresolve_method6FrnMmethodHandle_nLKlassHandle_nMsymbolHandle_43ipnGThread__v_; +text: .text%__1cMLinkResolverYlookup_method_in_klasses6FrnMmethodHandle_nLKlassHandle_nMsymbolHandle_4pnGThread__v_; +text: .text%__1cMLinkResolverbAcheck_method_accessability6FnLKlassHandle_11nMmethodHandle_pnGThread__v_; +text: .text%__1cKReflectionTverify_field_access6FpnMklassOopDesc_22nLAccessFlags_ii_i_; +text: .text%__1cICallInfoDset6MnLKlassHandle_nMmethodHandle_pnGThread__v_; +text: .text%__1cICallInfoDset6MnLKlassHandle_1nMmethodHandle_2ipnGThread__v_; +text: .text%__1cSInterpreterRuntimeLcache_entry6FpnKJavaThread__pnWConstantPoolCacheEntry__: interpreterRuntime.o; +text: .text%__1cWConstantPoolCacheEntryLis_resolved6kMnJBytecodesECode__i_: interpreterRuntime.o; +text: .text%__1cWConstantPoolCacheEntryPbytecode_number6FnJBytecodesECode__i_: interpreterRuntime.o; +text: .text%__1cWConstantPoolCacheEntryKset_method6MnJBytecodesECode_nMmethodHandle_i_v_; +text: .text%__1cNmethodOopDescLresult_type6kM_nJBasicType__; +text: .text%__1cRSignatureIteratorSiterate_returntype6M_v_; +text: .text%__1cNSignatureInfoHdo_void6M_v_: bytecode.o; +text: .text%__1cQResultTypeFinderDset6MinJBasicType__v_: bytecode.o; +text: .text%__1cRSignatureIteratorTcheck_signature_end6M_v_; +text: .text%__1cLas_TosState6FnJBasicType__nITosState__: cpCacheOop.o; +text: .text%__1cNmethodOopDescPis_final_method6kM_i_; +text: .text%__1cWConstantPoolCacheEntryIas_flags6MnITosState_iiiii_i_; +text: .text%__1cWConstantPoolCacheEntryOset_bytecode_16MnJBytecodesECode__v_; +text: .text%__1cWConstantPoolCacheEntryGverify6kMpnMoutputStream__v_; +text: .text%__1cSInterpreterRuntimeTprepare_native_call6FpnKJavaThread_pnNmethodOopDesc__v_; +text: .text%__1cXSignatureHandlerLibraryDadd6FnMmethodHandle__v_; +text: .text%__1cXSignatureHandlerLibraryKinitialize6F_v_; +text: .text%__1cXSignatureHandlerLibraryQset_handler_blob6F_pC_; +text: .text%__1cRSignatureIterator2t6MpnNsymbolOopDesc__v_; +text: .text%__1cNFingerprinterLfingerprint6M_X_: interpreterRuntime.o; +text: .text%__1cNGrowableArray4CX_Efind6kMkX_i_: interpreterRuntime.o; +text: .text%__1cSInterpreterRuntimeZSignatureHandlerGeneratorIgenerate6MX_v_; +text: .text%__1cRSignatureIteratorSiterate_parameters6MX_v_; +text: .text%__1cXSignatureHandlerLibraryLset_handler6FpnKCodeBuffer__pC_; +text: .text%__1cXSignatureHandlerLibraryOpd_set_handler6FpC_v_; +text: .text%jni_RegisterNatives: jni.o; +text: .text%__1cPjava_lang_ClassLas_klassOop6FpnHoopDesc__pnMklassOopDesc__; +text: .text%__1cLSymbolTableFprobe6Fpkci_pnNsymbolOopDesc__; +text: .text%__1cPregister_native6FnLKlassHandle_nMsymbolHandle_1pCpnGThread__i_: jni.o; +text: .text%__1cPJavaCallWrapper2T6M_v_; +text: .text%__1cOJNIHandleBlockNrelease_block6Fp0pnGThread__v_; +text: .text%__1cNinstanceKlassbJset_initialization_state_and_notify6Mn0AKClassState_pnGThread__v_; +text: .text%__1cNinstanceKlassbOset_initialization_state_and_notify_impl6FnTinstanceKlassHandle_n0AKClassState_pnGThread__v_; +text: .text%__1cSObjectSynchronizerJnotifyall6FnGHandle_pnGThread__v_; +text: .text%__1cSInterpreterRuntimeJanewarray6FpnKJavaThread_pnTconstantPoolOopDesc_ii_v_; +text: .text%__1cSInterpreterRuntimePresolve_get_put6FpnKJavaThread_nJBytecodesECode__v_; +text: .text%__1cMLinkResolverNresolve_field6FrnPFieldAccessInfo_nSconstantPoolHandle_inJBytecodesECode_ipnGThread__v_; +text: .text%__1cMLinkResolverNresolve_field6FrnPFieldAccessInfo_nSconstantPoolHandle_inJBytecodesECode_iipnGThread__v_; +text: .text%__1cNinstanceKlassKfind_field6kMpnNsymbolOopDesc_2pnPfieldDescriptor__pnMklassOopDesc__; +text: .text%__1cMLinkResolverZcheck_field_accessability6FnLKlassHandle_11rnPfieldDescriptor_pnGThread__v_; +text: .text%__1cPFieldAccessInfoDset6MnLKlassHandle_nMsymbolHandle_iinJBasicType_nLAccessFlags__v_; +text: .text%__1cLas_TosState6FnJBasicType__nITosState__: interpreterRuntime.o; +text: .text%__1cWConstantPoolCacheEntryJset_field6MnJBytecodesECode_2nLKlassHandle_iinITosState_ii_v_; +text: .text%__1cWConstantPoolCacheEntryOset_bytecode_26MnJBytecodesECode__v_; +text: .text%__1cSInterpreterRuntimeE_new6FpnKJavaThread_pnTconstantPoolOopDesc_i_v_; +text: .text%__1cNinstanceKlassbDcheck_valid_for_instantiation6MipnGThread__v_; +text: .text%__1cMLinkResolverVresolve_invokespecial6FrnICallInfo_nSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cMLinkResolverUresolve_special_call6FrnICallInfo_nLKlassHandle_nMsymbolHandle_43ipnGThread__v_; +text: .text%__1cMLinkResolverbFlinktime_resolve_special_method6FrnMmethodHandle_nLKlassHandle_nMsymbolHandle_43ipnGThread__v_; +text: .text%__1cMLinkResolverbEruntime_resolve_special_method6FrnICallInfo_nMmethodHandle_nLKlassHandle_4ipnGThread__v_; +text: .text%__1cWConstantPoolCacheEntryLis_resolved6kMnJBytecodesECode__i_: cpCacheOop.o; +text: .text%__1cWConstantPoolCacheEntryPbytecode_number6FnJBytecodesECode__i_: cpCacheOop.o; +text: .text%__1cNSignatureInfoJdo_object6Mii_v_: bytecode.o; +text: .text%__1cNSignatureInfoHdo_long6M_v_: bytecode.o; +text: .text%JVM_CurrentTimeMillis; +text: .text%__1cbBcreate_initial_thread_group6FpnGThread__nGHandle__: thread.o; +text: .text%__1cJJavaCallsMcall_special6FpnJJavaValue_nGHandle_nLKlassHandle_nMsymbolHandle_5pnGThread__v_; +text: .text%__1cJJavaCallsMcall_special6FpnJJavaValue_nLKlassHandle_nMsymbolHandle_4pnRJavaCallArguments_pnGThread__v_; +text: .text%__1cSInterpreterRuntimeDldc6FpnKJavaThread_i_v_; +text: .text%__1cTconstantPoolOopDescOstring_at_impl6FnSconstantPoolHandle_ipnGThread__pnHoopDesc__; +text: .text%__1cLsymbolKlassNoop_is_symbol6kM_i_: symbolKlass.o; +text: .text%__1cLStringTableGintern6FpnNsymbolOopDesc_pnGThread__pnHoopDesc__; +text: .text%__1cNsymbolOopDescKas_unicode6kMri_pH_; +text: .text%__1cEUTF8Ounicode_length6Fpkci_i_; +text: .text%__1cLStringTableGintern6FnGHandle_pHipnGThread__pnHoopDesc__; +text: .text%__1cLStringTableLhash_string6FpHi_i_; +text: .text%__1cLStringTableGlookup6MipHiI_pnHoopDesc__; +text: .text%__1cLStringTableJbasic_add6MinGHandle_pHiIpnGThread__pnHoopDesc__; +text: .text%__1cQjava_lang_StringbBcreate_tenured_from_unicode6FpHipnGThread__nGHandle__; +text: .text%__1cKoopFactoryXnew_permanent_charArray6FipnGThread__pnQtypeArrayOopDesc__; +text: .text%__1cQjava_lang_StringMbasic_create6FpnQtypeArrayOopDesc_ipnGThread__nGHandle__; +text: .text%__1cJJavaCallsMcall_special6FpnJJavaValue_nGHandle_nLKlassHandle_nMsymbolHandle_533pnGThread__v_; +text: .text%__1cNmethodOopDescIbci_from6kMpC_i_; +text: .text%__1cPBytecode_invokeJsignature6kM_pnNsymbolOopDesc__; +text: .text%__1cPBytecode_invokeFindex6kM_i_; +text: .text%__1cNmethodOopDescIbcp_from6kMi_pC_; +text: .text%__1cFframebGinterpreter_callee_receiver_addr6MnMsymbolHandle__ppnHoopDesc__; +text: .text%__1cMLinkResolverVresolve_invokevirtual6FrnICallInfo_nGHandle_nSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cMLinkResolverUresolve_virtual_call6FrnICallInfo_nGHandle_nLKlassHandle_4nMsymbolHandle_54iipnGThread__v_; +text: .text%__1cMLinkResolverbFlinktime_resolve_virtual_method6FrnMmethodHandle_nLKlassHandle_nMsymbolHandle_43ipnGThread__v_; +text: .text%__1cMLinkResolverbEruntime_resolve_virtual_method6FrnICallInfo_nMmethodHandle_nLKlassHandle_nGHandle_4ipnGThread__v_; +text: .text%__1cFKlassXcan_be_statically_bound6FpnNmethodOopDesc__i_; +text: .text%__1cNSignatureInfoGdo_int6M_v_: bytecode.o; +text: .text%__1cNSignatureInfoHdo_char6M_v_: bytecode.o; +text: .text%__1cFKlassOis_subclass_of6kMpnMklassOopDesc__i_; +text: .text%__1cNinstanceKlassVis_same_class_package6MpnHoopDesc_pnNsymbolOopDesc__i_; +text: .text%__1cJBytecodesRspecial_length_at6FpC_i_; +text: .text%__1cJJavaCallsLcall_static6FpnJJavaValue_nLKlassHandle_nMsymbolHandle_4nGHandle_5pnGThread__v_; +text: .text%__1cJJavaCallsLcall_static6FpnJJavaValue_nLKlassHandle_nMsymbolHandle_4pnRJavaCallArguments_pnGThread__v_; +text: .text%__1cLklassVtableIindex_of6kMpnNmethodOopDesc_i_i_; +text: .text%__1cMNativeLookupNlong_jni_name6FnMmethodHandle__pc_; +text: .text%__1cNFingerprinterJdo_object6Mii_v_: dump.o; +text: .text%__1cXNativeSignatureIteratorJdo_object6Mii_v_: interpreterRuntime.o; +text: .text%__1cSInterpreterRuntimeZSignatureHandlerGeneratorLpass_object6M_v_: interpreterRuntime.o; +text: .text%__1cSInterpreterRuntimeZSignatureHandlerGeneratorDbox6Mii_v_; +text: .text%__1cSInterpreterRuntimeZSignatureHandlerGeneratorEfrom6F_pnMRegisterImpl__; +text: .text%__1cSInterpreterRuntimeZSignatureHandlerGeneratorCto6F_pnMRegisterImpl__; +text: .text%JVM_DoPrivileged; +text: .text%__1cLmethodKlassNoop_is_method6kM_i_: methodKlass.o; +text: .text%__1cMvframeStream2t6MpnKJavaThread_i_v_; +text: .text%__1cLRegisterMap2t6MpnKJavaThread_i_v_; +text: .text%__1cLRegisterMapFclear6Mpi_v_; +text: .text%__1cSvframeStreamCommonPfill_from_frame6M_i_; +text: .text%__1cFframeUis_interpreted_frame6kM_i_; +text: .text%__1cSvframeStreamCommonbBfill_from_interpreter_frame6M_v_; +text: .text%__1cSvframeStreamCommonZsecurity_get_caller_frame6Mi_v_; +text: .text%__1cSvframeStreamCommonbHskip_method_invoke_and_aux_frames6M_v_; +text: .text%__1cSvframeStreamCommonEnext6M_v_; +text: .text%__1cFframeGsender6kMpnLRegisterMap_pnICodeBlob__0_; +text: .text%__1cFframeOis_entry_frame6kM_i_; +text: .text%__1cRPrivilegedElementKinitialize6MpnMvframeStream_pnHoopDesc_p0pnGThread__v_; +text: .text%__1cKJNIHandlesKmake_local6FpnHJNIEnv__pnHoopDesc__pnI_jobject__; +text: .text%__1cOJNIHandleBlockPallocate_handle6MpnHoopDesc__pnI_jobject__; +text: .text%__1cSInterpreterRuntimeNquicken_io_cc6FpnKJavaThread__v_; +text: .text%__1cNSignatureInfoHdo_bool6M_v_: bytecode.o; +text: .text%__1cNSharedRuntimeDf2i6Ff_i_; +text: .text%jni_FindClass: jni.o; +text: .text%__1cKJavaThreadZsecurity_get_caller_class6Mi_pnMklassOopDesc__; +text: .text%__1cbCfind_class_from_class_loader6FpnHJNIEnv__nMsymbolHandle_CnGHandle_3CpnGThread__pnH_jclass__; +text: .text%__1cRCompilationPolicyUcompleted_vm_startup6F_v_; +text: .text%jni_NewGlobalRef: jni.o; +text: .text%__1cKJNIHandlesLmake_global6FnGHandle_i_pnI_jobject__; +text: .text%jni_GetStringUTFChars: jni.o; +text: .text%__1cQjava_lang_StringOas_utf8_string6FpnHoopDesc__pc_; +text: .text%__1cHUNICODEHas_utf86FpHi_pc_; +text: .text%__1cHUNICODELutf8_length6FpHi_i_; +text: .text%__1cKutf8_write6FpCH_0_: utf8.o; +text: .text%JVM_FindPrimitiveClass; +text: .text%__1cJname2type6Fpkc_nJBasicType__; +text: .text%jni_ReleaseStringUTFChars; +text: .text%__1cVcreate_initial_thread6FnGHandle_pnKJavaThread_pnGThread__pnHoopDesc__: thread.o; +text: .text%__1cQjava_lang_ThreadKset_thread6FpnHoopDesc_pnKJavaThread__v_; +text: .text%__1cQjava_lang_ThreadMset_priority6FpnHoopDesc_nOThreadPriority__v_; +text: .text%JVM_CurrentThread; +text: .text%__1cNSignatureInfoIdo_array6Mii_v_: bytecode.o; +text: .text%__1cSInterpreterRuntimeInewarray6FpnKJavaThread_nJBasicType_i_v_; +text: .text%__1cKoopFactoryNnew_typeArray6FnJBasicType_ipnGThread__pnQtypeArrayOopDesc__; +text: .text%__1cNFingerprinterGdo_int6M_v_: dump.o; +text: .text%__1cXNativeSignatureIteratorGdo_int6M_v_: interpreterRuntime.o; +text: .text%__1cSInterpreterRuntimeZSignatureHandlerGeneratorIpass_int6M_v_: interpreterRuntime.o; +text: .text%__1cSInterpreterRuntimeZSignatureHandlerGeneratorEmove6Mii_v_; +text: .text%JVM_ArrayCopy; +text: .text%__1cOtypeArrayKlassKcopy_array6MpnMarrayOopDesc_i2iipnGThread__v_; +text: .text%__1cOtypeArrayKlassQoop_is_typeArray6kM_i_: typeArrayKlass.o; +text: .text%JVM_GetStackAccessControlContext; +text: .text%__1cbGJvmtiVMObjectAllocEventCollector2t6M_v_; +text: .text%__1cJCodeCacheJfind_blob6Fpv_pnICodeBlob__; +text: .text%__1cJCodeCacheQfind_blob_unsafe6Fpv_pnICodeBlob__; +text: .text%__1cICodeHeapKfind_start6kMpv_1_; +text: .text%__1cICodeBlobJis_zombie6kM_i_: codeBlob.o; +text: .text%__1cICodeBlobKis_nmethod6kM_i_: codeBlob.o; +text: .text%__1cFframeOis_first_frame6kM_i_; +text: .text%__1cFframeUentry_frame_is_first6kM_i_; +text: .text%__1cbIjava_security_AccessControlContextGcreate6FnOobjArrayHandle_inGHandle_pnGThread__pnHoopDesc__; +text: .text%__1cbGJvmtiVMObjectAllocEventCollector2T6M_v_; +text: .text%__1cTJvmtiEventCollectorYunset_jvmti_thread_state6M_v_; +text: .text%JVM_GetInheritedAccessControlContext; +text: .text%__1cQjava_lang_ThreadbGinherited_access_control_context6FpnHoopDesc__2_; +text: .text%JVM_SetThreadPriority; +text: .text%__1cQjava_lang_ThreadGthread6FpnHoopDesc__pnKJavaThread__; +text: .text%__1cGThreadMset_priority6Fp0nOThreadPriority__v_; +text: .text%__1cCosMset_priority6FpnGThread_nOThreadPriority__nIOSReturn__; +text: .text%__1cQjava_lang_ThreadRset_thread_status6FpnHoopDesc_n0AMThreadStatus__v_; +text: .text%JVM_IsThreadAlive; +text: .text%__1cQjava_lang_ThreadIis_alive6FpnHoopDesc__i_; +text: .text%JVM_StartThread; +text: .text%__1cQjava_lang_ThreadMis_stillborn6FpnHoopDesc__i_; +text: .text%__1cQjava_lang_ThreadJstackSize6FpnHoopDesc__x_; +text: .text%__1cKJavaThread2t6MpFp0pnGThread__vI_v_; +text: .text%__1cKJavaThreadHprepare6MpnI_jobject_nOThreadPriority__v_; +text: .text%__1cQjava_lang_ThreadIpriority6FpnHoopDesc__nOThreadPriority__; +text: .text%__1cQjava_lang_ThreadJis_daemon6FpnHoopDesc__i_; +text: .text%__1cGThreadFstart6Fp0_v_; +text: .text%__1cNinstanceKlassRprotection_domain6M_pnHoopDesc__: instanceRefKlass.o; +text: .text%__1cbAcall_initializeSystemClass6FpnGThread__v_: thread.o; +text: .text%__1cJJavaCallsLcall_static6FpnJJavaValue_nLKlassHandle_nMsymbolHandle_4pnGThread__v_; +text: .text%__1cKJavaThreadDrun6M_v_; +text: .text%__1cKJavaThreadRthread_main_inner6M_v_; +text: .text%__1cMthread_entry6FpnKJavaThread_pnGThread__v_: jvm.o; +text: .text%__1cJJavaCallsMcall_virtual6FpnJJavaValue_nGHandle_nLKlassHandle_nMsymbolHandle_5pnGThread__v_; +text: .text%__1cJJavaCallsMcall_virtual6FpnJJavaValue_nLKlassHandle_nMsymbolHandle_4pnRJavaCallArguments_pnGThread__v_; +text: .text%__1cIBytecodeIset_code6MnJBytecodesECode__v_; +text: .text%__1cNFingerprinterHdo_long6M_v_: dump.o; +text: .text%__1cXNativeSignatureIteratorHdo_long6M_v_: interpreterRuntime.o; +text: .text%__1cSInterpreterRuntimeZSignatureHandlerGeneratorJpass_long6M_v_: interpreterRuntime.o; +text: .text%JVM_MonitorWait; +text: .text%__1cQjava_lang_ThreadRget_thread_status6FpnHoopDesc__n0AMThreadStatus__; +text: .text%__1cSObjectSynchronizerEwait6FnGHandle_xpnGThread__v_; +text: .text%__1cSObjectSynchronizerHinflate6FpnHoopDesc__pnNObjectMonitor__; +text: .text%__1cNObjectMonitor2t6M_v_; +text: .text%__1cNObjectMonitorHRecycle6M_v_; +text: .text%__1cNObjectMonitorEwait6MxipnGThread__v_; +text: .text%__1cGThreadOis_interrupted6Fp0i_i_; +text: .text%__1cCosOis_interrupted6FpnGThread_i_i_; +text: .text%__1cNObjectMonitorEexit6MpnGThread__v_; +text: .text%__1cCosHSolarisFEventEpark6M_v_: objectMonitor_solaris.o; +text: .text%jni_GetObjectClass: jni.o; +text: .text%jni_GetMethodID: jni.o; +text: .text%__1cNget_method_id6FpnHJNIEnv__pnH_jclass_pkc5ipnGThread__pnK_jmethodID__: jni.o; +text: .text%__1cPjava_lang_ClassMis_primitive6FpnHoopDesc__i_; +text: .text%__1cNmethodOopDescKjmethod_id6M_pnK_jmethodID__; +text: .text%__1cMjniIdSupportNto_jmethod_id6FpnNmethodOopDesc__pnK_jmethodID__; +text: .text%__1cMjniIdPrivateGid_for6FnTinstanceKlassHandle_i_i_: jniId.o; +text: .text%__1cIjniIdMapGcreate6FnTinstanceKlassHandle__p0_; +text: .text%__1cIjniIdMapRcompute_index_cnt6FnTinstanceKlassHandle__i_; +text: .text%__1cIjniIdMap2t6MpnMklassOopDesc_i_v_; +text: .text%__1cLjniIdBucket2t6MpnIjniIdMap_p0_v_; +text: .text%jni_NewStringUTF: jni.o; +text: .text%jni_CallObjectMethod: jni.o; +text: .text%__1cMjniIdSupportNto_method_oop6FpnK_jmethodID__pnNmethodOopDesc__; +text: .text%__1cRSignatureIterator2t6MpnGThread_pnNsymbolOopDesc__v_; +text: .text%__1cUjni_invoke_nonstatic6FpnHJNIEnv__pnJJavaValue_pnI_jobject_nLJNICallType_pnK_jmethodID_pnSJNI_ArgumentPusher_pnGThread__v_: jni.o; +text: .text%__1cNFingerprinterLfingerprint6M_X_: jni.o; +text: .text%__1cXJNI_ArgumentPusherVaArgHiterate6MX_v_: jni.o; +text: .text%__1cXJNI_ArgumentPusherVaArgKget_object6M_v_: jni.o; +text: .text%jni_ExceptionOccurred: jni.o; +text: .text%__1cbAjni_check_async_exceptions6FpnKJavaThread__v_: jni.o; +text: .text%__1cKJavaThreadbHcheck_and_handle_async_exceptions6Mi_v_; +text: .text%jni_DeleteLocalRef: jni.o; +text: .text%__1cOJNIHandleBlockRrebuild_free_list6M_v_; +text: .text%jni_EnsureLocalCapacity; +text: .text%jni_GetStaticMethodID: jni.o; +text: .text%jni_CallStaticObjectMethodV: jni.o; +text: .text%__1cRjni_invoke_static6FpnHJNIEnv__pnJJavaValue_pnI_jobject_nLJNICallType_pnK_jmethodID_pnSJNI_ArgumentPusher_pnGThread__v_: jni.o; +text: .text%__1cMLinkResolverbHlookup_instance_method_in_klasses6FrnMmethodHandle_nLKlassHandle_nMsymbolHandle_4pnGThread__v_; +text: .text%jni_ExceptionCheck: jni.o; +text: .text%jni_NewString: jni.o; +text: .text%__1cQjava_lang_StringXcreate_oop_from_unicode6FpHipnGThread__pnHoopDesc__; +text: .text%JVM_InitProperties; +text: .text%__1cMset_property6FnGHandle_pkc2pnGThread__v_: jvm.o; +text: .text%__1cQjava_lang_StringbHcreate_from_platform_depended_str6FpkcpnGThread__nGHandle__; +text: .text%__1cJJavaCallsMcall_virtual6FpnJJavaValue_nGHandle_nLKlassHandle_nMsymbolHandle_533pnGThread__v_; +text: .text%__1cKSharedHeapXfill_region_with_object6FnJMemRegion__v_; +text: .text%__1cYNoJvmtiVMObjectAllocMark2t6M_v_; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: sharedHeap.o; +text: .text%__1cYNoJvmtiVMObjectAllocMark2T6M_v_; +text: .text%__1cPfieldDescriptorUstring_initial_value6kMpnGThread__pnHoopDesc__; +text: .text%jni_GetFieldID: jni.o; +text: .text%__1cNinstanceKlassKfind_field6kMpnNsymbolOopDesc_2ipnPfieldDescriptor__pnMklassOopDesc__; +text: .text%__1cNinstanceKlassSregister_finalizer6FpnPinstanceOopDesc_pnGThread__2_; +text: .text%__1cJFieldTypeYis_valid_array_signature6FpnNsymbolOopDesc__i_; +text: .text%__1cQSystemDictionarybBresolve_array_class_or_null6FnMsymbolHandle_nGHandle_2pnGThread__pnMklassOopDesc__; +text: .text%__1cJFieldTypeOget_array_info6FpnNsymbolOopDesc_pip2pnGThread__nJBasicType__; +text: .text%__1cJFieldTypeSskip_optional_size6FpnNsymbolOopDesc_pi_v_; +text: .text%__1cOtypeArrayKlassQarray_klass_impl6MiipnGThread__pnMklassOopDesc__; +text: .text%__1cOtypeArrayKlassQarray_klass_impl6FnUtypeArrayKlassHandle_iipnGThread__pnMklassOopDesc__; +text: .text%JVM_RegisterUnsafeMethods; +text: .text%JVM_IsArrayClass; +text: .text%JVM_GetComponentType; +text: .text%__1cKReflectionUarray_component_type6FpnHoopDesc_pnGThread__2_; +text: .text%__1cKReflectionbFbasic_type_arrayklass_to_mirror6FpnMklassOopDesc_pnGThread__pnHoopDesc__; +text: .text%JVM_IsPrimitiveClass; +text: .text%JVM_GetClassLoader; +text: .text%JVM_DesiredAssertionStatus; +text: .text%__1cOJavaAssertionsHenabled6Fpkci_i_; +text: .text%__1cOJavaAssertionsLmatch_class6Fpkc_pn0AKOptionList__: javaAssertions.o; +text: .text%__1cOJavaAssertionsNmatch_package6Fpkc_pn0AKOptionList__; +text: .text%__1cNinstanceKlassUfind_interface_field6kMpnNsymbolOopDesc_2pnPfieldDescriptor__pnMklassOopDesc__; +text: .text%JVM_InternString; +text: .text%__1cLStringTableGintern6FpnHoopDesc_pnGThread__2_; +text: .text%__1cQjava_lang_StringRas_unicode_string6FpnHoopDesc_ri_pH_; +text: .text%__1cKSharedHeapPis_in_permanent6kMpkv_i_: genCollectedHeap.o; +text: .text%__1cQjava_lang_StringGequals6FpnHoopDesc_pHi_i_; +text: .text%JVM_NanoTime; +text: .text%__1cCosNjavaTimeNanos6F_x_; +text: .text%JVM_GetCallerClass; +text: .text%JVM_SupportsCX8; +text: .text%__1cNFingerprinterHdo_bool6M_v_: dump.o; +text: .text%__1cXNativeSignatureIteratorHdo_bool6M_v_: interpreterRuntime.o; +text: .text%JVM_GetClassDeclaredFields; +text: .text%__1cKReflectionJnew_field6FpnPfieldDescriptor_ipnGThread__pnHoopDesc__; +text: .text%__1cKReflectionInew_type6FnMsymbolHandle_nLKlassHandle_pnGThread__nGHandle__; +text: .text%__1cJvmSymbolsOsignature_type6FpnNsymbolOopDesc__nJBasicType__; +text: .text%__1cXjava_lang_reflect_FieldGcreate6FpnGThread__nGHandle__; +text: .text%__1cXjava_lang_reflect_FieldJset_clazz6FpnHoopDesc_2_v_; +text: .text%__1cXjava_lang_reflect_FieldIset_slot6FpnHoopDesc_i_v_; +text: .text%__1cXjava_lang_reflect_FieldIset_name6FpnHoopDesc_2_v_; +text: .text%__1cXjava_lang_reflect_FieldIset_type6FpnHoopDesc_2_v_; +text: .text%__1cXjava_lang_reflect_FieldNset_modifiers6FpnHoopDesc_i_v_; +text: .text%__1cbIjava_lang_reflect_AccessibleObjectMset_override6FpnHoopDesc_C_v_; +text: .text%__1cXjava_lang_reflect_FieldThas_signature_field6F_i_; +text: .text%__1cXjava_lang_reflect_FieldVhas_annotations_field6F_i_; +text: .text%__1cPfieldDescriptorLannotations6kM_pnQtypeArrayOopDesc__; +text: .text%__1cXjava_lang_reflect_FieldPset_annotations6FpnHoopDesc_2_v_; +text: .text%__1cMLinkResolverXresolve_invokeinterface6FrnICallInfo_nGHandle_nSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cMLinkResolverWresolve_interface_call6FrnICallInfo_nGHandle_nLKlassHandle_4nMsymbolHandle_54iipnGThread__v_; +text: .text%__1cMLinkResolverbHlinktime_resolve_interface_method6FrnMmethodHandle_nLKlassHandle_nMsymbolHandle_43ipnGThread__v_; +text: .text%__1cMLinkResolverYresolve_interface_method6FrnMmethodHandle_nLKlassHandle_nMsymbolHandle_43ipnGThread__v_; +text: .text%__1cMLinkResolverbGruntime_resolve_interface_method6FrnICallInfo_nMmethodHandle_nLKlassHandle_nGHandle_4ipnGThread__v_; +text: .text%__1cICallInfoDset6MnLKlassHandle_1nMmethodHandle_2pnGThread__v_; +text: .text%__1cLklassItableUcompute_itable_index6FpnNmethodOopDesc__i_; +text: .text%__1cWConstantPoolCacheEntrySset_interface_call6MnMmethodHandle_i_v_; +text: .text%Unsafe_ObjectFieldOffset; +text: .text%__1cRfind_field_offset6FpnI_jobject_ipnGThread__i_; +text: .text%__1cXjava_lang_reflect_FieldFclazz6FpnHoopDesc__2_; +text: .text%__1cXjava_lang_reflect_FieldEslot6FpnHoopDesc__i_; +text: .text%__1cXjava_lang_reflect_FieldJmodifiers6FpnHoopDesc__i_; +text: .text%__1cQjava_lang_StringScreate_from_symbol6FnMsymbolHandle_pnGThread__nGHandle__; +text: .text%__1cXjava_lang_reflect_FieldNset_signature6FpnHoopDesc_2_v_; +text: .text%JVM_IHashCode; +text: .text%jni_GetStaticFieldID: jni.o; +text: .text%__1cNinstanceKlassKjni_id_for6Mi_pnFJNIid__; +text: .text%__1cNinstanceKlassPjni_id_for_impl6FnTinstanceKlassHandle_i_pnFJNIid__; +text: .text%__1cFJNIid2t6MpnMklassOopDesc_ip0_v_; +text: .text%jni_SetStaticObjectField: jni.o; +text: .text%__1cFKlassNoop_is_symbol6kM_i_: instanceRefKlass.o; +text: .text%__1cNobjArrayKlassPoop_is_objArray6kM_i_: objArrayKlass.o; +text: .text%__1cKarrayKlassTallocate_arrayArray6MiipnGThread__pnPobjArrayOopDesc__; +text: .text%__1cNobjArrayKlassQarray_klass_impl6MipnGThread__pnMklassOopDesc__; +text: .text%__1cFKlassNoop_is_symbol6kM_i_: objArrayKlass.o; +text: .text%__1cNCollectedHeapOarray_allocate6FnLKlassHandle_iipnGThread__pnHoopDesc__: arrayKlass.o; +text: .text%__1cNCollectedHeapYcommon_mem_allocate_init6FIipnGThread__pnIHeapWord__: arrayKlass.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: arrayKlass.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: arrayKlass.o; +text: .text%jni_GetStringUTFLength: jni.o; +text: .text%__1cQjava_lang_StringLutf8_length6FpnHoopDesc__i_; +text: .text%jni_GetStringLength: jni.o; +text: .text%__1cQjava_lang_StringGlength6FpnHoopDesc__i_; +text: .text%jni_GetStringUTFRegion: jni.o; +text: .text%__1cQjava_lang_StringOas_utf8_string6FpnHoopDesc_ii_pc_; +text: .text%JVM_FindClassFromClassLoader; +text: .text%JVM_IsInterface; +text: .text%JVM_GetClassDeclaredConstructors; +text: .text%__1cNmethodOopDescOis_initializer6kM_i_; +text: .text%__1cKReflectionPnew_constructor6FnMmethodHandle_pnGThread__pnHoopDesc__; +text: .text%__1cNinstanceKlassQmethod_index_for6kMpnNmethodOopDesc_pnGThread__i_; +text: .text%__1cKReflectionTget_parameter_types6FnMmethodHandle_ippnHoopDesc_pnGThread__nOobjArrayHandle__; +text: .text%__1cPSignatureStream2t6MnMsymbolHandle_i_v_; +text: .text%__1cPSignatureStreamEnext6M_v_; +text: .text%__1cKReflectionTget_exception_types6FnMmethodHandle_pnGThread__nOobjArrayHandle__; +text: .text%__1cNmethodOopDescbGresolved_checked_exceptions_impl6Fp0pnGThread__nOobjArrayHandle__; +text: .text%__1cSconstMethodOopDescZchecked_exceptions_length6kM_i_; +text: .text%__1cbDjava_lang_reflect_ConstructorGcreate6FpnGThread__nGHandle__; +text: .text%__1cbDjava_lang_reflect_ConstructorJset_clazz6FpnHoopDesc_2_v_; +text: .text%__1cbDjava_lang_reflect_ConstructorIset_slot6FpnHoopDesc_i_v_; +text: .text%__1cbDjava_lang_reflect_ConstructorTset_parameter_types6FpnHoopDesc_2_v_; +text: .text%__1cbDjava_lang_reflect_ConstructorTset_exception_types6FpnHoopDesc_2_v_; +text: .text%__1cbDjava_lang_reflect_ConstructorNset_modifiers6FpnHoopDesc_i_v_; +text: .text%__1cbDjava_lang_reflect_ConstructorThas_signature_field6F_i_; +text: .text%__1cbDjava_lang_reflect_ConstructorVhas_annotations_field6F_i_; +text: .text%__1cNmethodOopDescLannotations6kM_pnQtypeArrayOopDesc__; +text: .text%__1cbDjava_lang_reflect_ConstructorPset_annotations6FpnHoopDesc_2_v_; +text: .text%__1cbDjava_lang_reflect_ConstructorbFhas_parameter_annotations_field6F_i_; +text: .text%__1cNmethodOopDescVparameter_annotations6kM_pnQtypeArrayOopDesc__; +text: .text%__1cbDjava_lang_reflect_ConstructorZset_parameter_annotations6FpnHoopDesc_2_v_; +text: .text%__1cKarrayKlassWuncached_lookup_method6kMpnNsymbolOopDesc_2_pnNmethodOopDesc__; +text: .text%JVM_Clone; +text: .text%__1cNCollectedHeapOarray_allocate6FnLKlassHandle_iipnGThread__pnHoopDesc__: jvm.o; +text: .text%__1cNCollectedHeapYcommon_mem_allocate_init6FIipnGThread__pnIHeapWord__: jvm.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: jvm.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: jvm.o; +text: .text%__1cRCardTableModRefBSPdirty_MemRegion6MnJMemRegion__v_; +text: .text%JVM_GetClassAccessFlags; +text: .text%JVM_GetClassName; +text: .text%__1cFKlassNexternal_name6kM_pkc_; +text: .text%__1cNsymbolOopDescWas_klass_external_name6kM_pkc_; +text: .text%__1cLStringTableGintern6FpkcpnGThread__pnHoopDesc__; +text: .text%JVM_GetClassModifiers; +text: .text%jni_GetSuperclass: jni.o; +text: .text%__1cKJNIHandlesKmake_local6FpnHoopDesc__pnI_jobject__; +text: .text%__1cNFingerprinterIdo_array6Mii_v_: dump.o; +text: .text%JVM_NewInstanceFromConstructor; +text: .text%__1cKReflectionSinvoke_constructor6FpnHoopDesc_nOobjArrayHandle_pnGThread__2_; +text: .text%__1cbDjava_lang_reflect_ConstructorFclazz6FpnHoopDesc__2_; +text: .text%__1cbDjava_lang_reflect_ConstructorEslot6FpnHoopDesc__i_; +text: .text%__1cbIjava_lang_reflect_AccessibleObjectIoverride6FpnHoopDesc__C_; +text: .text%__1cbDjava_lang_reflect_ConstructorPparameter_types6FpnHoopDesc__2_; +text: .text%__1cKReflectionGinvoke6FnTinstanceKlassHandle_nMmethodHandle_nGHandle_inOobjArrayHandle_nJBasicType_4ipnGThread__pnHoopDesc__; +text: .text%__1cKReflectionDbox6FpnGjvalue_nJBasicType_pnGThread__pnHoopDesc__; +text: .text%JVM_MaxMemory; +text: .text%__1cQGenCollectedHeapMmax_capacity6kM_I_; +text: .text%__1cQDefNewGenerationMmax_capacity6kM_I_; +text: .text%Unsafe_AllocateMemory; +text: .text%Unsafe_SetNativeLong; +text: .text%__1cNSignatureInfoHdo_byte6M_v_: bytecode.o; +text: .text%Unsafe_GetNativeByte; +text: .text%Unsafe_FreeMemory; +text: .text%__1cNSignatureInfoIdo_float6M_v_: bytecode.o; +text: .text%__1cFJNIidEfind6Mi_p0_; +text: .text%jni_NewObjectV: jni.o; +text: .text%__1cMalloc_object6FpnH_jclass_pnGThread__pnPinstanceOopDesc__: jni.o; +text: .text%jni_GetStringRegion: jni.o; +text: .text%__1cQjava_lang_StringGoffset6FpnHoopDesc__i_; +text: .text%__1cQjava_lang_StringFvalue6FpnHoopDesc__pnQtypeArrayOopDesc__; +text: .text%jni_GetObjectField: jni.o; +text: .text%jni_GetStringCritical: jni.o; +text: .text%__1cJGC_lockerNlock_critical6FpnKJavaThread__v_: jni.o; +text: .text%jni_ReleaseStringCritical: jni.o; +text: .text%JVM_LoadLibrary; +text: .text%JVM_FindLibraryEntry; +text: .text%jni_GetJavaVM; +text: .text%JVM_IsSupportedJNIVersion; +text: .text%jni_SetIntField: jni.o; +text: .text%jni_SetLongField: jni.o; +text: .text%JVM_FindSignal; +text: .text%JVM_RegisterSignal; +text: .text%__1cCosMuser_handler6F_pv_; +text: .text%__1cCosGsignal6Fipv_1_; +text: .text%__1cWreset_vm_info_property6FpnGThread__v_: thread.o; +text: .text%__1cVquicken_jni_functions6F_v_; +text: .text%__1cQJNI_FastGetFieldbFgenerate_fast_get_boolean_field6F_pC_; +text: .text%__1cQJNI_FastGetFieldbCgenerate_fast_get_int_field06FnJBasicType__pC_; +text: .text%__1cJAssemblerFtestb6MpnMRegisterImpl_i_v_; +text: .text%__1cJAssemblerMemit_arith_b6MiipnMRegisterImpl_i_v_; +text: .text%__1cYjni_GetBooleanField_addr6F_pC_; +text: .text%__1cQJNI_FastGetFieldbCgenerate_fast_get_byte_field6F_pC_; +text: .text%__1cVjni_GetByteField_addr6F_pC_; +text: .text%__1cQJNI_FastGetFieldbCgenerate_fast_get_char_field6F_pC_; +text: .text%__1cVjni_GetCharField_addr6F_pC_; +text: .text%__1cQJNI_FastGetFieldbDgenerate_fast_get_short_field6F_pC_; +text: .text%__1cWjni_GetShortField_addr6F_pC_; +text: .text%__1cQJNI_FastGetFieldbBgenerate_fast_get_int_field6F_pC_; +text: .text%__1cUjni_GetIntField_addr6F_pC_; +text: .text%__1cQJNI_FastGetFieldbCgenerate_fast_get_long_field6F_pC_; +text: .text%__1cVjni_GetLongField_addr6F_pC_; +text: .text%__1cQJNI_FastGetFieldbDgenerate_fast_get_float_field6F_pC_; +text: .text%__1cQJNI_FastGetFieldbEgenerate_fast_get_float_field06FnJBasicType__pC_; +text: .text%__1cJAssemblerFfst_s6MnHAddress__v_; +text: .text%__1cJAssemblerGfstp_d6Mi_v_; +text: .text%__1cWjni_GetFloatField_addr6F_pC_; +text: .text%__1cQJNI_FastGetFieldbEgenerate_fast_get_double_field6F_pC_; +text: .text%__1cXjni_GetDoubleField_addr6F_pC_; +text: .text%__1cSset_init_completed6F_v_; +text: .text%__1cJTimeStampGupdate6M_v_; +text: .text%__1cQSystemDictionarybAcompute_java_system_loader6FpnGThread__v_; +text: .text%jni_NewObjectArray: jni.o; +text: .text%__1cNobjArrayKlassKinitialize6MpnGThread__v_; +text: .text%__1cNobjArrayKlassIallocate6MipnGThread__pnPobjArrayOopDesc__; +text: .text%__1cNCollectedHeapOarray_allocate6FnLKlassHandle_iipnGThread__pnHoopDesc__: objArrayKlass.o; +text: .text%__1cNCollectedHeapYcommon_mem_allocate_init6FIipnGThread__pnIHeapWord__: objArrayKlass.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: objArrayKlass.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: objArrayKlass.o; +text: .text%jni_SetObjectArrayElement: jni.o; +text: .text%jni_GetObjectArrayElement: jni.o; +text: .text%__1cSInterpreterRuntimebAfrequency_counter_overflow6FpnKJavaThread_pC_x_; +text: .text%__1cQSimpleCompPolicyXmethod_invocation_event6MnMmethodHandle_pnGThread__v_; +text: .text%__1cRCompilationPolicybIreset_counter_for_invocation_event6MnMmethodHandle__v_; +text: .text%__1cRInvocationCounterJset_carry6M_v_; +text: .text%__1cNCompileBrokerOcompile_method6FnMmethodHandle_i1ipkcpnGThread__pnHnmethod__; +text: .text%__1cQSimpleCompPolicyRcompilation_level6MnMmethodHandle_i_i_; +text: .text%__1cNCompileBrokerTcompile_method_base6FnMmethodHandle_ii1ipkcpnGThread__pnHnmethod__; +text: .text%__1cNobjArrayKlassKcopy_array6MpnMarrayOopDesc_i2iipnGThread__v_; +text: .text%__1cLJvmtiExportQenter_live_phase6F_v_; +text: .text%__1cLJvmtiExportTpost_vm_initialized6F_v_; +text: .text%__1cUJvmtiEventControllerHvm_init6F_v_; +text: .text%__1cHMonitorKnotify_all6M_i_; +text: .text%__1cFChunkbDstart_chunk_pool_cleaner_task6F_v_; +text: .text%__1cMPeriodicTask2t6MI_v_; +text: .text%__1cMPeriodicTaskGenroll6M_v_; +text: .text%__1cURecompilationMonitorbGstart_recompilation_monitor_task6F_v_; +text: .text%__1cCosLsignal_init6F_v_; +text: .text%__1cJJavaCallsMcall_special6FpnJJavaValue_nGHandle_nLKlassHandle_nMsymbolHandle_53pnGThread__v_; +text: .text%__1cCosOsignal_init_pd6F_v_; +text: .text%__1cQjava_lang_ThreadKset_daemon6FpnHoopDesc__v_; +text: .text%__1cICompiler2t6M_v_; +text: .text%__1cNCompileBrokerQcompilation_init6FpnQAbstractCompiler__v_; +text: .text%__1cNCompileBrokerVinit_compiler_threads6Fi_v_; +text: .text%__1cICompilerOneeds_adapters6M_i_: c1_Compiler.o; +text: .text%__1cQCompilerCounters2t6MpkcipnGThread__v_; +text: .text%__1cNCompileBrokerUmake_compiler_thread6FpkcpnMCompileQdDueue_pnQCompilerCounters_pnGThread__pnOCompilerThread__; +text: .text%__1cOCompilerThread2t6MpnMCompileQdDueue_pnQCompilerCounters__v_; +text: .text%__1cOCompilerThreadbCis_hidden_from_external_view6kM_i_: thread.o; +text: .text%__1cCosFyield6F_v_; +text: .text%__1cCosFsleep6FpnGThread_xi_i_; +text: .text%__1cGThreadRis_Watcher_thread6kM_i_: thread.o; +text: .text%__1cTsignal_thread_entry6FpnKJavaThread_pnGThread__v_: os.o; +text: .text%__1cCosLsignal_wait6F_i_; +text: .text%__1cVcheck_pending_signals6Fi_i_: os_solaris.o; +text: .text%__1cVcompiler_thread_entry6FpnKJavaThread_pnGThread__v_: thread.o; +text: .text%__1cNCompileBrokerUcompiler_thread_loop6F_v_; +text: .text%__1cICompilerKinitialize6M_v_; +text: .text%__1cMCompileQdDueueDget6M_pnLCompileTask__; +text: .text%__1cKManagementKinitialize6FpnGThread__v_; +text: .text%__1cRLowMemoryDetectorKinitialize6F_v_; +text: .text%__1cXLowMemoryDetectorThreadbCis_hidden_from_external_view6kM_i_: lowMemoryDetector.o; +text: .text%__1cKJavaThreadOis_Java_thread6kM_i_: lowMemoryDetector.o; +text: .text%__1cLStatSamplerGengage6F_v_; +text: .text%__1cLStatSamplerKinitialize6F_v_; +text: .text%__1cLStatSamplerUcreate_misc_perfdata6F_v_; +text: .text%__1cCosRelapsed_frequency6F_x_; +text: .text%__1cLStatSamplerbMcreate_system_property_instrumentation6FpnGThread__v_; +text: .text%__1cLStatSamplerTget_system_property6FpkcpnGThread__2_; +text: .text%__1cJJavaCallsLcall_static6FpnJJavaValue_nLKlassHandle_nMsymbolHandle_4nGHandle_pnGThread__v_; +text: .text%__1cLStatSamplerXcreate_sampled_perfdata6F_v_; +text: .text%__1cPPerfDataManagerTcreate_long_counter6FnJCounterNS_pkcnIPerfDataFUnits_pnUPerfLongSampleHelper_pnGThread__pnPPerfLongCounter__; +text: .text%__1cSHighResTimeSamplerLtake_sample6M_x_: statSampler.o; +text: .text%__1cPPerfDataManagerHsampled6F_pnMPerfDataList__; +text: .text%__1cMPerfDataListFclone6M_p0_; +text: .text%__1cMPerfDataList2t6Mp0_v_; +text: .text%__1cUGenericGrowableArrayNraw_appendAll6Mpk0_v_; +text: .text%__1cNWatcherThreadFstart6F_v_; +text: .text%__1cNWatcherThread2t6M_v_; +text: .text%__1cJTimeStampMmilliseconds6kM_x_; +text: .text%__1cKManagementWrecord_vm_startup_time6Fxx_v_; +text: .text%__1cORuntimeServiceYrecord_application_start6F_v_; +text: .text%__1cNWatcherThreadDrun6M_v_; +text: .text%__1cMPeriodicTaskMtime_to_wait6F_I_: thread.o; +text: .text%__1cNWatcherThreadRis_Watcher_thread6kM_i_: thread.o; +text: .text%__1cIos_sleep6Fxi_i_: os_solaris.o; +text: .text%__1cNgetTimeMillis6F_x_; +text: .text%__1cQjava_lang_StringOchar_converter6FnGHandle_HHpnGThread__1_; +text: .text%JVM_FindLoadedClass; +text: .text%__1cQSystemDictionarybCfind_instance_or_array_klass6FnMsymbolHandle_nGHandle_2pnGThread__pnMklassOopDesc__; +text: .text%__1cQSystemDictionaryEfind6FnMsymbolHandle_nGHandle_2pnGThread__pnMklassOopDesc__; +text: .text%__1cSInterpreterRuntimeLmonitorexit6FpnKJavaThread_pnPBasicObjectLock__v_; +text: .text%__1cSObjectSynchronizerJslow_exit6FpnHoopDesc_pnJBasicLock_pnGThread__v_; +text: .text%jni_CallStaticObjectMethod: jni.o; +text: .text%jni_NewByteArray: jni.o; +text: .text%jni_SetByteArrayRegion: jni.o; +text: .text%__1cSInterpreterRuntimeMmonitorenter6FpnKJavaThread_pnPBasicObjectLock__v_; +text: .text%__1cNObjectMonitorFenter6MpnGThread__v_; +text: .text%jni_NewObject: jni.o; +text: .text%__1cGThreadMis_VM_thread6kM_i_: lowMemoryDetector.o; +text: .text%__1cRLowMemoryDetectorbGlow_memory_detector_thread_entry6FpnKJavaThread_pnGThread__v_; +text: .text%__1cRLowMemoryDetectorUhas_pending_requests6F_i_; +text: .text%__1cVjava_lang_ClassLoaderGparent6FpnHoopDesc__2_; +text: .text%__1cKExceptionsK_throw_msg6FpnGThread_pkcipnNsymbolOopDesc_4_v_; +text: .text%__1cKExceptionsK_throw_msg6FpnGThread_pkcinMsymbolHandle_4nGHandle_6_v_; +text: .text%__1cKExceptionsRspecial_exception6FpnGThread_pkcinMsymbolHandle_4_i_; +text: .text%__1cKExceptionsNnew_exception6FpnGThread_nMsymbolHandle_pkcnGHandle_6_6_; +text: .text%__1cKExceptionsNnew_exception6FpnGThread_nMsymbolHandle_3pnRJavaCallArguments_nGHandle_6_6_; +text: .text%JVM_FillInStackTrace; +text: .text%__1cTjava_lang_ThrowableTfill_in_stack_trace6FnGHandle__v_; +text: .text%__1cIUniverseWis_out_of_memory_error6FnGHandle__i_; +text: .text%__1cVPreserveExceptionMark2t6MrpnGThread__v_; +text: .text%__1cKJavaThreadGactive6F_p0_; +text: .text%__1cTjava_lang_ThrowableTfill_in_stack_trace6FnGHandle_pnGThread__v_; +text: .text%__1cTjava_lang_ThrowableNset_backtrace6FpnHoopDesc_2_v_; +text: .text%__1cTjava_lang_ThrowableQclear_stacktrace6FpnHoopDesc__v_; +text: .text%__1cVPreserveExceptionMark2T6M_v_; +text: .text%__1cKExceptionsG_throw6FpnGThread_pkcinGHandle__v_; +text: .text%__1cKExceptionsRspecial_exception6FpnGThread_pkcinGHandle__i_; +text: .text%__1cGThreadVset_pending_exception6MpnHoopDesc_pkci_v_; +text: .text%__1cGEventsDlog6FpkcE_v_: exceptions.o; +text: .text%__1cSInterpreterRuntimeXthrow_pending_exception6FpnKJavaThread__v_; +text: .text%__1cNSharedRuntimebKexception_handler_for_return_address6FpC_1_; +text: .text%__1cNSharedRuntimebOraw_exception_handler_for_return_address6FpC_1_; +text: .text%__1cSInterpreterRuntimebFexception_handler_for_exception6FpnKJavaThread_pnHoopDesc__pC_; +text: .text%__1cNmethodOopDescbEfast_exception_handler_bci_for6MnLKlassHandle_ipnGThread__i_; +text: .text%__1cKJavaThreadNreguard_stack6MpC_i_; +text: .text%__1cSInterpreterRuntimePset_bcp_and_mdp6FpCpnKJavaThread__v_; +text: .text%__1cFframeZinterpreter_frame_set_bcp6MpC_v_; +text: .text%__1cFframeZinterpreter_frame_set_bcx6Mi_v_; +text: .text%__1cNCompileBrokerYcheck_compilation_result6FnMmethodHandle_iippnHnmethod__i_; +text: .text%__1cNCompileBrokerXcompilation_is_in_queue6FnMmethodHandle_i_i_; +text: .text%__1cNCompileBrokerZcompilation_is_prohibited6FnMmethodHandle_i_i_; +text: .text%__1cNCompileBrokerTis_not_compile_only6FnMmethodHandle__i_; +text: .text%__1cOCompilerOracleOshould_exclude6FnMmethodHandle__i_; +text: .text%__1cNCompileBrokerRassign_compile_id6FnMmethodHandle_i_I_; +text: .text%__1cNCompileBrokerTis_compile_blocking6FnMmethodHandle_i_i_; +text: .text%__1cNCompileBrokerTcreate_compile_task6FpnMCompileQdDueue_inMmethodHandle_i3ipkcii_pnLCompileTask__; +text: .text%__1cNCompileBrokerNallocate_task6F_pnLCompileTask__; +text: .text%__1cLCompileTaskKinitialize6MinMmethodHandle_i1ipkcii_v_; +text: .text%__1cMCompileQdDueueDadd6MpnLCompileTask__v_; +text: .text%__1cNCompileBrokerTwait_for_completion6FpnLCompileTask__pnHnmethod__; +text: .text%__1cCosPhint_no_preempt6F_v_; +text: .text%__1cSCompileTaskWrapper2t6MpnLCompileTask__v_; +text: .text%__1cNCompileBrokerZinvoke_compiler_on_method6FpnLCompileTask__v_; +text: .text%__1cNCompileBrokerQset_last_compile6FpnOCompilerThread_nMmethodHandle_ii_v_; +text: .text%__1cNCompileBrokerVpush_jni_handle_block6F_v_; +text: .text%__1cNCompileBrokerOcheck_break_at6FnMmethodHandle_iii_i_; +text: .text%__1cOCompilerOraclePshould_break_at6FnMmethodHandle__i_; +text: .text%__1cFciEnv2t6MpnHJNIEnv__iii_v_; +text: .text%__1cPciObjectFactory2t6MpnFArena_i_v_; +text: .text%__1cPciObjectFactoryTinit_shared_objects6M_v_; +text: .text%__1cUGenericGrowableArray2t6MpnFArena_iipnEGrET__v_; +text: .text%__1cIciSymbol2t6MnMsymbolHandle__v_; +text: .text%__1cIciObject2t6MnGHandle__v_; +text: .text%__1cPciObjectFactoryEfind6MpnHoopDesc_pnNGrowableArray4CpnIciObject____i_; +text: .text%__1cPciObjectFactoryLis_found_at6MipnHoopDesc_pnNGrowableArray4CpnIciObject____i_; +text: .text%__1cPciObjectFactoryNinit_ident_of6MpnIciObject__v_; +text: .text%__1cIciObjectJset_ident6MI_v_; +text: .text%__1cPciObjectFactoryGinsert6MipnIciObject_pnNGrowableArray4C2___v_; +text: .text%__1cGciType2t6MnJBasicType__v_; +text: .text%__1cIciObject2t6M_v_; +text: .text%__1cPciObjectFactoryDget6MpnHoopDesc__pnIciObject__; +text: .text%__1cPciObjectFactoryNfind_non_perm6MpnHoopDesc__rpn0ANNonPermObject__; +text: .text%__1cFKlassNoop_is_symbol6kM_i_: klassKlass.o; +text: .text%__1cPciObjectFactoryRcreate_new_object6MpnHoopDesc__pnIciObject__; +text: .text%__1cFKlassPoop_is_instance6kM_i_: methodKlass.o; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: methodKlass.o; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: methodKlass.o; +text: .text%__1cIciSymbolEmake6Fpkc_p0_; +text: .text%__1cFciEnvIis_in_vm6F_i_; +text: .text%__1cIciSymbolJmake_impl6Fpkc_p0_; +text: .text%__1cHciKlass2t6MnLKlassHandle_pnIciSymbol__v_; +text: .text%__1cGciType2t6MnLKlassHandle__v_; +text: .text%__1cFKlassMoop_is_array6kM_i_: methodKlass.o; +text: .text%__1cFKlassPoop_is_instance6kM_i_: symbolKlass.o; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: symbolKlass.o; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: symbolKlass.o; +text: .text%__1cFKlassNoop_is_method6kM_i_: symbolKlass.o; +text: .text%__1cFKlassMoop_is_array6kM_i_: symbolKlass.o; +text: .text%__1cFKlassPoop_is_instance6kM_i_: klassKlass.o; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: klassKlass.o; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: klassKlass.o; +text: .text%__1cFKlassNoop_is_method6kM_i_: klassKlass.o; +text: .text%__1cFKlassUoop_is_objArrayKlass6kM_i_: klassKlass.o; +text: .text%__1cFKlassVoop_is_typeArrayKlass6kM_i_: klassKlass.o; +text: .text%__1cFKlassUoop_is_instanceKlass6kM_i_: klassKlass.o; +text: .text%__1cFKlassMoop_is_array6kM_i_: klassKlass.o; +text: .text%__1cFKlassPoop_is_instance6kM_i_: instanceKlassKlass.o; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: instanceKlassKlass.o; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: instanceKlassKlass.o; +text: .text%__1cFKlassNoop_is_method6kM_i_: instanceKlassKlass.o; +text: .text%__1cFKlassNoop_is_symbol6kM_i_: instanceKlassKlass.o; +text: .text%__1cFKlassUoop_is_objArrayKlass6kM_i_: instanceKlassKlass.o; +text: .text%__1cFKlassVoop_is_typeArrayKlass6kM_i_: instanceKlassKlass.o; +text: .text%__1cSinstanceKlassKlassUoop_is_instanceKlass6kM_i_: instanceKlassKlass.o; +text: .text%__1cFKlassMoop_is_array6kM_i_: instanceKlassKlass.o; +text: .text%__1cFKlassPoop_is_instance6kM_i_: typeArrayKlassKlass.o; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: typeArrayKlassKlass.o; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: typeArrayKlassKlass.o; +text: .text%__1cFKlassNoop_is_method6kM_i_: typeArrayKlassKlass.o; +text: .text%__1cFKlassNoop_is_symbol6kM_i_: typeArrayKlassKlass.o; +text: .text%__1cFKlassUoop_is_objArrayKlass6kM_i_: typeArrayKlassKlass.o; +text: .text%__1cTtypeArrayKlassKlassVoop_is_typeArrayKlass6kM_i_: typeArrayKlassKlass.o; +text: .text%__1cFKlassMoop_is_array6kM_i_: typeArrayKlassKlass.o; +text: .text%__1cFKlassPoop_is_instance6kM_i_: objArrayKlassKlass.o; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: objArrayKlassKlass.o; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: objArrayKlassKlass.o; +text: .text%__1cFKlassNoop_is_method6kM_i_: objArrayKlassKlass.o; +text: .text%__1cFKlassNoop_is_symbol6kM_i_: objArrayKlassKlass.o; +text: .text%__1cSobjArrayKlassKlassUoop_is_objArrayKlass6kM_i_: objArrayKlassKlass.o; +text: .text%__1cFKlassMoop_is_array6kM_i_: objArrayKlassKlass.o; +text: .text%__1cPciInstanceKlass2t6MnLKlassHandle__v_; +text: .text%__1cHciKlass2t6MnLKlassHandle__v_; +text: .text%__1cPciInstanceKlassFsuper6M_p0_; +text: .text%__1cPciInstanceKlassTis_java_lang_Object6M_i_; +text: .text%__1cIciObjectGequals6Mp0_i_; +text: .text%__1cPciInstanceKlassLjava_mirror6M_pnKciInstance__; +text: .text%__1cHciKlassLjava_mirror6M_pnKciInstance__; +text: .text%__1cFKlassNoop_is_method6kM_i_: instanceKlass.o; +text: .text%__1cFKlassRoop_is_methodData6kM_i_: instanceKlass.o; +text: .text%__1cUciInstanceKlassKlassEmake6F_p0_; +text: .text%__1cHciKlass2t6MpnIciSymbol_p0_v_; +text: .text%__1cGciType2t6MpnHciKlass__v_; +text: .text%__1cIciObject2t6MpnHciKlass__v_; +text: .text%__1cIciObjectUis_array_klass_klass6M_i_: ciObjectFactory.o; +text: .text%__1cPciObjArrayKlass2t6MpnIciSymbol_pnHciKlass_i_v_; +text: .text%__1cUciObjArrayKlassKlassEmake6F_p0_; +text: .text%__1cMciArrayKlass2t6MpnIciSymbol_ipnHciKlass__v_; +text: .text%__1cRciArrayKlassKlassUis_array_klass_klass6M_i_: ciObjectFactory.o; +text: .text%__1cQciTypeArrayKlass2t6MnLKlassHandle__v_; +text: .text%__1cMciArrayKlass2t6MnLKlassHandle__v_; +text: .text%__1cFciEnvWget_method_from_handle6MpnI_jobject__pnIciMethod__; +text: .text%__1cFKlassNoop_is_symbol6kM_i_: methodKlass.o; +text: .text%__1cIciMethod2t6MnMmethodHandle__v_; +text: .text%__1cLciSignature2t6MpnHciKlass_pnIciSymbol__v_; +text: .text%__1cPSignatureStreamJis_object6kM_i_; +text: .text%__1cGciTypeEmake6FnJBasicType__p0_; +text: .text%__1cJTraceTime2t6MpkcpnMelapsedTimer_iipnMoutputStream__v_; +text: .text%__1cICompilerOcompile_method6MpnFciEnv_pnIciMethod_i_v_; +text: .text%__1cLCompilation2t6MpnQAbstractCompiler_pnFciEnv_pnIciMethod_ipnRC1_MacroAssembler__v_; +text: .text%__1cTExceptionRangeTable2t6Mi_v_; +text: .text%__1cWImplicitExceptionTableIset_size6MI_v_; +text: .text%__1cLCompilationOcompile_method6M_v_; +text: .text%__1cLCompilationKinitialize6M_v_; +text: .text%__1cLCompilationEcode6kM_pnKCodeBuffer__; +text: .text%__1cYDebugInformationRecorder2t6MpnLOopRecorder__v_; +text: .text%__1cUDebugInfoWriteStream2t6MpnYDebugInformationRecorder_i_v_; +text: .text%__1cLCompilationTdebug_info_recorder6kM_pnYDebugInformationRecorder__; +text: .text%__1cLCompilationbBis_optimized_library_method6kM_i_; +text: .text%__1cLCompilationTcompile_java_method6MpnLCodeOffsets__i_; +text: .text%__1cLCompilationTinitialize_oop_maps6M_v_; +text: .text%__1cIciMethodMall_oop_maps6M_pnKciLocalMap__; +text: .text%__1cSciGenerateLocalMap2t6MpnFArena_nMmethodHandle__v_; +text: .text%__1cOGenerateOopMap2t6MnMmethodHandle__v_; +text: .text%__1cSciGenerateLocalMapWfind_jsr_return_points6MnMmethodHandle__v_; +text: .text%__1cRRawBytecodeStream2t6MnMmethodHandle__v_; +text: .text%__1cRRawBytecodeStreamMset_interval6Mii_v_; +text: .text%__1cOBytecodeStreamEnext6M_nJBytecodesECode__: ciOopMap.o; +text: .text%__1cOGenerateOopMapLcompute_map6MpnGThread__v_; +text: .text%__1cIRetTableRcompute_ret_table6MnMmethodHandle__v_; +text: .text%__1cOBytecodeStreamEnext6M_nJBytecodesECode__: generateOopMap.o; +text: .text%__1cOGenerateOopMapbImark_bbheaders_and_count_gc_points6M_v_; +text: .text%__1cOGenerateOopMapNinitialize_bb6M_v_; +text: .text%__1cOGenerateOopMapLbb_mark_fct6Fp0ipi_v_; +text: .text%__1cOGenerateOopMapOset_bbmark_bit6Mi_v_; +text: .text%__1cOGenerateOopMapPjump_targets_do6MpnOBytecodeStream_pFp0ipi_v4_i_; +text: .text%__1cSciGenerateLocalMapRpossible_gc_point6MpnOBytecodeStream__i_; +text: .text%__1cSciGenerateLocalMapUbytecode_is_gc_point6FnJBytecodesECode_ii_i_; +text: .text%__1cOGenerateOopMapRdo_interpretation6M_v_; +text: .text%__1cOGenerateOopMapRinit_basic_blocks6M_v_; +text: .text%__1cOGenerateOopMapKinit_state6M_v_; +text: .text%__1cOGenerateOopMapTmark_reachable_code6M_v_; +text: .text%__1cOGenerateOopMapUreachable_basicblock6Fp0ipi_v_; +text: .text%__1cOGenerateOopMapSget_basic_block_at6kMi_pnKBasicBlock__; +text: .text%__1cOGenerateOopMapbAget_basic_block_containing6kMi_pnKBasicBlock__; +text: .text%__1cOGenerateOopMapYsetup_method_entry_state6M_v_; +text: .text%__1cOGenerateOopMapbAmake_context_uninitialized6M_v_; +text: .text%__1cOGenerateOopMapTmethodsig_to_effect6MpnNsymbolOopDesc_ipnNCellTypeState__i_; +text: .text%__1cOGenerateOopMapPinitialize_vars6M_v_; +text: .text%__1cOGenerateOopMapTmerge_state_into_bb6MpnKBasicBlock__v_; +text: .text%__1cOGenerateOopMapKcopy_state6MpnNCellTypeState_2_v_; +text: .text%__1cOGenerateOopMapKinterp_all6M_v_; +text: .text%__1cOGenerateOopMapJinterp_bb6MpnKBasicBlock__v_; +text: .text%__1cOGenerateOopMapNrestore_state6MpnKBasicBlock__v_; +text: .text%__1cOGenerateOopMapQnext_bb_start_pc6MpnKBasicBlock__i_; +text: .text%__1cOGenerateOopMapHinterp16MpnOBytecodeStream__v_; +text: .text%__1cOGenerateOopMapGppload6MpnNCellTypeState_i_v_; +text: .text%__1cOGenerateOopMapHget_var6Mi_nNCellTypeState__; +text: .text%__1cOGenerateOopMapEpush6MnNCellTypeState__v_; +text: .text%__1cOGenerateOopMapIdo_field6Miiii_v_; +text: .text%__1cOGenerateOopMapRsigchar_to_effect6McipnNCellTypeState__2_; +text: .text%__1cOGenerateOopMapCpp6MpnNCellTypeState_2_v_; +text: .text%__1cOGenerateOopMapEppop6MpnNCellTypeState__v_; +text: .text%__1cOGenerateOopMapFppop16MnNCellTypeState__v_; +text: .text%__1cOGenerateOopMapDpop6M_nNCellTypeState__; +text: .text%__1cOGenerateOopMapKcheck_type6MnNCellTypeState_1_v_; +text: .text%__1cOGenerateOopMapFppush6MpnNCellTypeState__v_; +text: .text%__1cOGenerateOopMapGppush16MnNCellTypeState__v_; +text: .text%__1cOGenerateOopMapHppstore6MpnNCellTypeState_i_v_; +text: .text%__1cOGenerateOopMapHset_var6MinNCellTypeState__v_; +text: .text%__1cOGenerateOopMapLmerge_state6Fp0ipi_v_; +text: .text%__1cOGenerateOopMapJdo_astore6Mi_v_; +text: .text%__1cOGenerateOopMapTmerge_state_vectors6MpnNCellTypeState_2_i_; +text: .text%__1cNCellTypeStateFmerge6kM0i_0_; +text: .text%__1cOGenerateOopMapIcopy_cts6MpnNCellTypeState_2_i_; +text: .text%__1cOGenerateOopMapXdo_return_monitor_check6M_v_; +text: .text%__1cOGenerateOopMapYrewrite_refval_conflicts6M_v_; +text: .text%__1cSciGenerateLocalMapOreport_results6kM_i_: ciOopMap.o; +text: .text%__1cOGenerateOopMapNreport_result6M_v_; +text: .text%__1cSciGenerateLocalMapUfill_stackmap_prolog6Mi_v_; +text: .text%__1cSciGenerateLocalMapZfill_stackmap_for_opcodes6MpnOBytecodeStream_pnNCellTypeState_4i_v_; +text: .text%__1cKciLocalMap2t6MpnFArena_iii_v_; +text: .text%__1cKciLocalMapRset_bci_for_index6Mii_v_; +text: .text%__1cSciGenerateLocalMapUfill_stackmap_epilog6M_v_: ciOopMap.o; +text: .text%__1cSciGenerateLocalMapOfill_init_vars6MpnNGrowableArray4Ci___v_; +text: .text%__1cKciLocalMapSset_nof_initialize6Mi_v_; +text: .text%__1cLCompilationJbuild_hir6M_v_; +text: .text%__1cCIR2t6MpnLCompilation_pnIciMethod_i_v_; +text: .text%__1cJValueTypeKinitialize6F_v_; +text: .text%__1cMciNullObjectEmake6F_p0_; +text: .text%__1cMGraphBuilderKinitialize6F_v_; +text: .text%__1cHIRScope2t6MpnLCompilation_p0ipnIciMethod_ii_v_; +text: .text%__1cOLocalSlotArray2t6MkikpnJLocalSlot__v_: c1_IR.o; +text: .text%__1cGBitMap2t6MI_v_; +text: .text%__1cGBitMapGresize6MI_v_; +text: .text%__1cNWordSizeArray2t6Mki1_v_: c1_IR.o; +text: .text%__1cJXHandlers2t6MpnIciMethod__v_; +text: .text%__1cIciMethodJload_code6M_v_; +text: .text%__1cIciMethodVhas_balanced_monitors6M_i_; +text: .text%__1cHIRScopeLbuild_graph6MpnLCompilation_i_pnKBlockBegin__; +text: .text%__1cQBlockListBuilder2t6MpnHIRScope_ii_v_; +text: .text%__1cPBlockBeginArray2t6MkikpnKBlockBegin__v_: c1_GraphBuilder.o; +text: .text%__1cQBlockListBuilderLset_leaders6M_v_; +text: .text%__1cQciBytecodeStream2t6MpnIciMethod__v_; +text: .text%__1cQciBytecodeStreamMset_interval6Mii_v_; +text: .text%__1cQBlockListBuilderMnew_block_at6MinKBlockBeginEFlag__p1_; +text: .text%__1cQBlockListBuilderUset_xhandler_entries6M_v_; +text: .text%__1cKValueStack2t6MpnHIRScope_ii_v_; +text: .text%__1cKValueArray2t6MkikpnLInstruction__v_: c1_ValueStack.o; +text: .text%__1cJLocalSlot2t6M_v_; +text: .text%__1cJLocalSlotIfor_type6MpnJValueType_ii_pnFLocal__: c1_IR.o; +text: .text%__1cKObjectTypeDtag6kM_nIValueTag__: c1_ValueType.o; +text: .text%__1cMGraphBuilder2t6MpnLCompilation_pnHIRScope_pnJBlockList_pnKBlockBegin__v_; +text: .text%__1cMGraphBuilderPpush_root_scope6MpnHIRScope_pnJBlockList_pnKBlockBegin__v_; +text: .text%__1cMGraphBuilderJScopeData2t6Mp1i_v_; +text: .text%__1cMGraphBuilderJScopeDataJset_scope6MpnHIRScope__v_; +text: .text%__1cMGraphBuilderUpush_exception_scope6M_v_; +text: .text%__1cOExceptionScope2t6M_v_; +text: .text%__1cOExceptionScopeEinit6M_v_; +text: .text%__1cIValueMap2t6M_v_; +text: .text%__1cMGraphBuilderJScopeDataQadd_to_work_list6MpnKBlockBegin__v_; +text: .text%__1cNResourceArrayGexpand6MIiri_v_; +text: .text%__1cMGraphBuilderSiterate_all_blocks6Mi_v_; +text: .text%__1cMGraphBuilderJScopeDataVremove_from_work_list6M_pnKBlockBegin__; +text: .text%__1cMGraphBuilderJScopeDataSis_work_list_empty6kM_i_; +text: .text%__1cMGraphBuilderOconnect_to_end6MpnKBlockBegin__pnIBlockEnd__; +text: .text%__1cIValueMapIkill_all6M_v_; +text: .text%__1cIValueMapRnumber_of_buckets6kM_i_; +text: .text%__1cIValueMapJbucket_at6Mi_pnGBucket__; +text: .text%__1cGBucketIkill_all6M_v_; +text: .text%__1cKValueStackEcopy6M_p0_; +text: .text%__1cGValuesIpush_all6Mpk0_v_: c1_ValueStack.o; +text: .text%__1cMGraphBuilderbBiterate_bytecodes_for_block6Mi_pnIBlockEnd__; +text: .text%__1cLInstructionLas_BlockEnd6M_pnIBlockEnd__: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderJScopeDataIblock_at6Mi_pnKBlockBegin__; +text: .text%__1cMGraphBuilderKload_local6MpnJValueType_i_v_; +text: .text%__1cJLocalSlotIfor_type6MpnJValueType_ii_pnFLocal__: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderGappend6MpnLInstruction__2_; +text: .text%__1cMGraphBuilderLappend_base6MpnLInstruction__2_; +text: .text%__1cJLoadLocalFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerMdo_LoadLocal6MpnJLoadLocal__v_; +text: .text%__1cIValueMapEfind6MpnLInstruction__2_; +text: .text%__1cLInstructionOas_AccessField6M_pnLAccessField__: c1_GraphBuilder.o; +text: .text%__1cLInstructionLas_UnsafeOp6M_pnIUnsafeOp__: c1_GraphBuilder.o; +text: .text%__1cLInstructionMas_Intrinsic6M_pnJIntrinsic__: c1_GraphBuilder.o; +text: .text%__1cLInstructionEhash6kM_i_: c1_GraphBuilder.o; +text: .text%__1cLInstructionNas_StateSplit6M_pnKStateSplit__: c1_GraphBuilder.o; +text: .text%__1cLInstructionIcan_trap6kM_i_: c1_GraphBuilder.o; +text: .text%__1cKValueStackLclear_store6Mi_v_; +text: .text%__1cKValueStackEpush6MpnJValueType_pnLInstruction__v_: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderMaccess_field6MnJBytecodesECode__v_; +text: .text%__1cQciBytecodeStreamJget_field6kM_pnHciField__; +text: .text%__1cQciBytecodeStreamPget_field_index6kM_i_; +text: .text%__1cFciEnvSget_field_by_index6MpnPciInstanceKlass_i_pnHciField__; +text: .text%__1cFciEnvXget_field_by_index_impl6MpnPciInstanceKlass_i_pnHciField__; +text: .text%__1cPciInstanceKlassLfield_cache6M_pnTciConstantPoolCache__; +text: .text%__1cHciField2t6MpnPciInstanceKlass_i_v_; +text: .text%__1cFciEnvSget_klass_by_index6MpnPciInstanceKlass_iri_pnHciKlass__; +text: .text%__1cFciEnvXget_klass_by_index_impl6MpnPciInstanceKlass_iri_pnHciKlass__; +text: .text%__1cTconstantPoolOopDescSklass_at_if_loaded6FnSconstantPoolHandle_i_pnMklassOopDesc__; +text: .text%__1cPciObjectFactorySget_unloaded_klass6MpnHciKlass_pnIciSymbol_i_2_; +text: .text%__1cPciInstanceKlassGloader6M_pnHoopDesc__; +text: .text%__1cPciInstanceKlassRprotection_domain6M_pnHoopDesc__; +text: .text%__1cHciFieldPinitialize_from6MpnPfieldDescriptor__v_; +text: .text%__1cMas_ValueType6FnJBasicType__pnJValueType__; +text: .text%__1cHciFieldJwill_link6MpnPciInstanceKlass_nJBytecodesECode__i_; +text: .text%__1cMLinkResolverXresolve_klass_no_update6FrnLKlassHandle_nSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cTconstantPoolOopDescbCklass_ref_at_if_loaded_check6FnSconstantPoolHandle_ipnGThread__pnMklassOopDesc__; +text: .text%__1cMGraphBuilderKlock_stack6M_pnKValueStack__; +text: .text%__1cKValueStackKcopy_locks6M_p0_; +text: .text%__1cJLoadFieldFvisit6MpnSInstructionVisitor__v_: c1_Instruction.o; +text: .text%__1cNCanonicalizerMdo_LoadField6MpnJLoadField__v_; +text: .text%__1cLAccessFieldOas_AccessField6M_p0_: c1_Instruction.o; +text: .text%__1cJLoadFieldEhash6kM_i_: c1_Instruction.o; +text: .text%__1cJLoadFieldEname6kM_pkc_: c1_Instruction.o; +text: .text%__1cIValueMapNlookup_bucket6Mi_pnGBucket__; +text: .text%__1cGBucketEfind6MpnLInstruction_i_2_; +text: .text%__1cGBucketGappend6MpnLInstruction_i_v_; +text: .text%__1cLInstructionNas_StateSplit6M_pnKStateSplit__: c1_Instruction.o; +text: .text%__1cLInstructionLas_BlockEnd6M_pnIBlockEnd__: c1_Instruction.o; +text: .text%__1cLAccessFieldIcan_trap6kM_i_: c1_Instruction.o; +text: .text%__1cOExceptionScopeEcopy6M_p0_; +text: .text%__1cOExceptionScopeGlength6kM_i_; +text: .text%__1cHIntTypeDtag6kM_nIValueTag__: c1_ValueType.o; +text: .text%__1cMGraphBuilderLstore_local6MpnJValueType_i_v_; +text: .text%__1cKValueStackDpop6MpnJValueType__pnLInstruction__: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderLstore_local6MpnKValueStack_pnLInstruction_pnJValueType_ii_v_; +text: .text%__1cJValueTypeNas_ObjectType6M_pnKObjectType__: c1_ValueType.o; +text: .text%__1cKStoreLocalFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerNdo_StoreLocal6MpnKStoreLocal__v_; +text: .text%__1cKValueStackLstore_local6MpnKStoreLocal_i_v_; +text: .text%__1cKValueStackQpin_stack_locals6Mi_v_; +text: .text%__1cKValueStackNpin_stack_all6MnLInstructionJPinReason__v_; +text: .text%__1cHIntTypeEsize6kM_i_: c1_ValueType.o; +text: .text%__1cMGraphBuilderHif_zero6MpnJValueType_nLInstructionJCondition__v_; +text: .text%__1cIConstantFvisit6MpnSInstructionVisitor__v_: c1_Instruction.o; +text: .text%__1cNCanonicalizerLdo_Constant6MpnIConstant__v_; +text: .text%__1cLInstructionOas_AccessField6M_pnLAccessField__: c1_Instruction.o; +text: .text%__1cLInstructionLas_UnsafeOp6M_pnIUnsafeOp__: c1_Instruction.o; +text: .text%__1cLInstructionMas_Intrinsic6M_pnJIntrinsic__: c1_Instruction.o; +text: .text%__1cIConstantEhash6kM_i_; +text: .text%__1cHIntTypeDtag6kM_nIValueTag__: c1_Canonicalizer.o; +text: .text%__1cLIntConstantOas_IntConstant6M_p0_: c1_Canonicalizer.o; +text: .text%__1cIConstantEname6kM_pkc_: c1_Instruction.o; +text: .text%__1cIConstantIcan_trap6kM_i_: c1_Instruction.o; +text: .text%__1cMGraphBuilderHif_node6MpnLInstruction_n0BJCondition_2pnKValueStack__v_; +text: .text%__1cCIf2t6MpnLInstruction_n0BJCondition_i2pnKBlockBegin_5pnKValueStack_i_v_: c1_GraphBuilder.o; +text: .text%__1cCIfFvisit6MpnSInstructionVisitor__v_: c1_Canonicalizer.o; +text: .text%__1cNCanonicalizerFdo_If6MpnCIf__v_; +text: .text%__1cJValueTypeLis_constant6kM_i_: c1_ValueType.o; +text: .text%__1cLInstructionMas_CompareOp6M_pnJCompareOp__: c1_Instruction.o; +text: .text%__1cLInstructionNas_InstanceOf6M_pnKInstanceOf__: c1_Instruction.o; +text: .text%__1cLInstructionOas_AccessField6M_pnLAccessField__: c1_Canonicalizer.o; +text: .text%__1cLInstructionLas_UnsafeOp6M_pnIUnsafeOp__: c1_Canonicalizer.o; +text: .text%__1cLInstructionMas_Intrinsic6M_pnJIntrinsic__: c1_Canonicalizer.o; +text: .text%__1cLInstructionEhash6kM_i_: c1_Canonicalizer.o; +text: .text%__1cKStateSplitNas_StateSplit6M_p0_: c1_Canonicalizer.o; +text: .text%__1cIBlockEndLas_BlockEnd6M_p0_: c1_Canonicalizer.o; +text: .text%__1cLInstructionIcan_trap6kM_i_: c1_Canonicalizer.o; +text: .text%__1cLInstructionJas_Return6M_pnGReturn__: c1_Canonicalizer.o; +text: .text%__1cLInstructionIas_Throw6M_pnFThrow__: c1_Canonicalizer.o; +text: .text%__1cKBlockBeginItry_join6MpnKValueStack__i_; +text: .text%__1cKValueStack2t6Mp0_v_; +text: .text%__1cKValueStackEinit6Mp0_v_; +text: .text%__1cMGraphBuilderNmethod_return6MpnLInstruction__v_; +text: .text%__1cGReturnFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerJdo_Return6MpnGReturn__v_; +text: .text%__1cKStateSplitNas_StateSplit6M_p0_: c1_GraphBuilder.o; +text: .text%__1cIBlockEndLas_BlockEnd6M_p0_: c1_GraphBuilder.o; +text: .text%__1cGReturnJas_Return6M_p0_: c1_GraphBuilder.o; +text: .text%__1cKValueStackbAeliminate_all_scope_stores6Mi_v_; +text: .text%__1cKValueStackQeliminate_stores6Mi_v_; +text: .text%__1cKValueStackMcaller_state6kM_p0_; +text: .text%__1cFciEnvWget_klass_by_name_impl6MpnHciKlass_pnIciSymbol_i_2_; +text: .text%__1cQSystemDictionarybOfind_constrained_instance_or_array_klass6FnMsymbolHandle_nGHandle_pnGThread__pnMklassOopDesc__; +text: .text%__1cHciKlassGloader6M_pnHoopDesc__: ciTypeArrayKlass.o; +text: .text%__1cFciEnvZcheck_klass_accessibility6MpnHciKlass_pnMklassOopDesc__i_; +text: .text%__1cIciObjectMis_obj_array6M_i_: ciInstanceKlass.o; +text: .text%__1cPciInstanceKlassRis_instance_klass6M_i_: ciInstanceKlass.o; +text: .text%__1cKObjectTypeNas_ObjectType6M_p0_: c1_ValueType.o; +text: .text%__1cJValueTypeOas_AddressType6M_pnLAddressType__: c1_ValueType.o; +text: .text%__1cKObjectTypeEsize6kM_i_: c1_ValueType.o; +text: .text%__1cMGraphBuilderHif_same6MpnJValueType_nLInstructionJCondition__v_; +text: .text%__1cJValueTypeOas_IntConstant6M_pnLIntConstant__: c1_ValueType.o; +text: .text%__1cKStoreFieldFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerNdo_StoreField6MpnKStoreField__v_; +text: .text%__1cLAccessFieldOas_AccessField6M_p0_: c1_GraphBuilder.o; +text: .text%__1cLAccessFieldIcan_trap6kM_i_: c1_GraphBuilder.o; +text: .text%__1cIValueMapKkill_field6MpnHciField__v_; +text: .text%__1cGBucketKkill_field6MpnHciField__v_; +text: .text%__1cKValueStackQpin_stack_fields6MpnHciField__v_; +text: .text%__1cKValueStackVis_same_across_scopes6Mp0_i_; +text: .text%__1cMGraphBuilderNarithmetic_op6MpnJValueType_nJBytecodesECode_pnKValueStack__v_; +text: .text%__1cJValueTypeEmeet6kMp0_1_; +text: .text%__1cHIntTypeEbase6kM_pnJValueType__: c1_Canonicalizer.o; +text: .text%__1cMArithmeticOpIcan_trap6kM_i_; +text: .text%__1cMArithmeticOpFvisit6MpnSInstructionVisitor__v_: c1_Instruction.o; +text: .text%__1cNCanonicalizerPdo_ArithmeticOp6MpnMArithmeticOp__v_; +text: .text%__1cNCanonicalizerGdo_Op26MpnDOp2__v_; +text: .text%__1cLIntConstantLis_constant6kM_i_: c1_Canonicalizer.o; +text: .text%__1cNCanonicalizerTmove_const_to_right6MpnDOp2__v_; +text: .text%__1cMArithmeticOpOis_commutative6kM_i_; +text: .text%__1cMArithmeticOpEhash6kM_i_: c1_Instruction.o; +text: .text%__1cMArithmeticOpEname6kM_pkc_: c1_Instruction.o; +text: .text%__1cMGraphBuilderJincrement6M_v_; +text: .text%__1cHIntTypeEbase6kM_pnJValueType__: c1_ValueType.o; +text: .text%__1cMGraphBuilderMload_indexed6MnJBasicType__v_; +text: .text%__1cLLoadIndexedFvisit6MpnSInstructionVisitor__v_: c1_Instruction.o; +text: .text%__1cNCanonicalizerOdo_LoadIndexed6MpnLLoadIndexed__v_; +text: .text%__1cLLoadIndexedEhash6kM_i_: c1_Instruction.o; +text: .text%__1cLLoadIndexedEname6kM_pkc_: c1_Instruction.o; +text: .text%__1cLAccessArrayIcan_trap6kM_i_: c1_Instruction.o; +text: .text%__1cIConstantIis_equal6kMpnLInstruction__i_; +text: .text%__1cIConstantLas_Constant6M_p0_: c1_Instruction.o; +text: .text%__1cEGotoFvisit6MpnSInstructionVisitor__v_: c1_Canonicalizer.o; +text: .text%__1cNCanonicalizerHdo_Goto6MpnEGoto__v_; +text: .text%__1cHIRScopeMheader_block6MpnKBlockBegin_n0BEFlag__2_; +text: .text%__1cCIRIoptimize6M_v_; +text: .text%__1cJOptimizer2t6MpnCIR__v_; +text: .text%__1cJOptimizerbHeliminate_conditional_expressions6M_v_; +text: .text%__1cCIRQiterate_preorder6MpnMBlockClosure__v_; +text: .text%__1cKBlockBeginQiterate_preorder6MpnMBlockClosure__v_; +text: .text%__1cJboolArray2t6Mki1_v_: c1_Instruction.o; +text: .text%__1cKBlockBeginQiterate_preorder6MrnJboolArray_pnMBlockClosure__v_; +text: .text%__1cNCE_EliminatorIblock_do6MpnKBlockBegin__v_: c1_Optimizer.o; +text: .text%__1cLInstructionFas_If6M_pnCIf__: c1_IR.o; +text: .text%__1cLInstructionFas_If6M_pnCIf__: c1_Canonicalizer.o; +text: .text%__1cCIfFas_If6M_p0_: c1_Canonicalizer.o; +text: .text%__1cHIntTypeKas_IntType6M_p0_: c1_ValueType.o; +text: .text%__1cNCE_EliminatorRsimple_value_copy6MpnLInstruction__2_: c1_Optimizer.o; +text: .text%__1cLInstructionLas_Constant6M_pnIConstant__: c1_GraphBuilder.o; +text: .text%__1cJLoadLocalMas_LoadLocal6M_p0_: c1_GraphBuilder.o; +text: .text%__1cLInstructionHas_Goto6M_pnEGoto__: c1_GraphBuilder.o; +text: .text%__1cLInstructionFas_If6M_pnCIf__: c1_GraphBuilder.o; +text: .text%__1cJOptimizerQeliminate_blocks6M_v_; +text: .text%__1cUGenericGrowableArray2t6MiipnEGrET_i_v_; +text: .text%__1cSPredecessorCounterIblock_do6MpnKBlockBegin__v_: c1_Optimizer.o; +text: .text%__1cLBlockMergerIblock_do6MpnKBlockBegin__v_: c1_Optimizer.o; +text: .text%__1cLBlockMergerJtry_merge6MpnKBlockBegin__i_: c1_Optimizer.o; +text: .text%__1cLInstructionHas_Goto6M_pnEGoto__: c1_IR.o; +text: .text%__1cEGotoHas_Goto6M_p0_: c1_Canonicalizer.o; +text: .text%__1cLInstructionHas_Goto6M_pnEGoto__: c1_Canonicalizer.o; +text: .text%__1cJOptimizerVeliminate_null_checks6M_v_; +text: .text%__1cGBitMapFclear6M_v_; +text: .text%__1cGBitMapUclear_range_of_words6MII_v_: bitMap.o; +text: .text%__1cNValueSetArray2t6MkikpnIValueSet__v_: c1_Optimizer.o; +text: .text%__1cTNullCheckEliminatorHiterate6MpnKBlockBegin__v_; +text: .text%__1cTNullCheckEliminatorLiterate_all6M_v_; +text: .text%__1cTNullCheckEliminatorLiterate_one6MpnKBlockBegin__v_; +text: .text%__1cJLocalSlotIfor_type6MpnJValueType_ii_pnFLocal__: c1_Optimizer.o; +text: .text%__1cGBitMapIset_from6M0_v_; +text: .text%__1cKStateSplitPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cKBlockBeginFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorNdo_BlockBegin6MpnKBlockBegin__v_; +text: .text%__1cKStateSplitPinput_values_do6MpFppnLInstruction__v_v_: c1_IR.o; +text: .text%__1cEBaseFvisit6MpnSInstructionVisitor__v_: c1_IR.o; +text: .text%__1cQNullCheckVisitorHdo_Base6MpnEBase__v_; +text: .text%__1cTNullCheckEliminatorPmerge_state_for6MpnKBlockBegin_pnKValueStack_pnIValueSet__i_; +text: .text%__1cPBlockBeginArrayIindex_of6kMkpnKBlockBegin__i_: c1_Optimizer.o; +text: .text%__1cKStateSplitPinput_values_do6MpFppnLInstruction__v_v_: c1_Canonicalizer.o; +text: .text%__1cQNullCheckVisitorHdo_Goto6MpnEGoto__v_; +text: .text%__1cLInstructionMas_NullCheck6M_pnJNullCheck__: c1_GraphBuilder.o; +text: .text%__1cLInstructionMas_NullCheck6M_pnJNullCheck__: c1_Instruction.o; +text: .text%__1cKStoreLocalPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cTNullCheckEliminatorIdo_value6FppnLInstruction__v_; +text: .text%__1cFLocalPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cFLocalFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorIdo_Local6MpnFLocal__v_; +text: .text%__1cLAccessFieldPinput_values_do6MpFppnLInstruction__v_v_: c1_Instruction.o; +text: .text%__1cLAccessLocalPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorMdo_LoadLocal6MpnJLoadLocal__v_; +text: .text%__1cTNullCheckEliminatorQhandle_LoadLocal6MpnJLoadLocal__v_; +text: .text%__1cQNullCheckVisitorMdo_LoadField6MpnJLoadField__v_; +text: .text%__1cTNullCheckEliminatorShandle_AccessField6MpnLAccessField__v_; +text: .text%__1cQNullCheckVisitorNdo_StoreLocal6MpnKStoreLocal__v_; +text: .text%__1cTNullCheckEliminatorRhandle_StoreLocal6MpnKStoreLocal__v_; +text: .text%__1cCIfPinput_values_do6MpFppnLInstruction__v_v_: c1_Canonicalizer.o; +text: .text%__1cIConstantPinput_values_do6MpFppnLInstruction__v_v_: c1_Instruction.o; +text: .text%__1cQNullCheckVisitorLdo_Constant6MpnIConstant__v_; +text: .text%__1cQNullCheckVisitorFdo_If6MpnCIf__v_; +text: .text%__1cDOp2Pinput_values_do6MpFppnLInstruction__v_v_: c1_Instruction.o; +text: .text%__1cQNullCheckVisitorPdo_ArithmeticOp6MpnMArithmeticOp__v_; +text: .text%__1cNAccessIndexedPinput_values_do6MpFppnLInstruction__v_v_: c1_Instruction.o; +text: .text%__1cQNullCheckVisitorOdo_LoadIndexed6MpnLLoadIndexed__v_; +text: .text%__1cTNullCheckEliminatorShandle_LoadIndexed6MpnLLoadIndexed__v_; +text: .text%__1cGBitMapbCset_intersection_with_result6M0_i_; +text: .text%__1cKStoreFieldPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorNdo_StoreField6MpnKStoreField__v_; +text: .text%__1cGReturnPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorJdo_Return6MpnGReturn__v_; +text: .text%__1cJboolArray2t6Mki1_v_: c1_Optimizer.o; +text: .text%__1cCIRTcompute_locals_size6M_v_; +text: .text%__1cHIRScopePallocate_locals6MipnMWordSizeList__i_; +text: .text%__1cHIRScopeGlocals6M_pnJLocalList__; +text: .text%__1cJLocalSlotOcollect_locals6MpnJLocalList__v_; +text: .text%__1cHIRScopePargument_locals6M_pnJLocalList__; +text: .text%__1cJLocalSlotXcollect_argument_locals6MpnJLocalList__v_; +text: .text%__1cCIRTallocate_local_name6M_i_; +text: .text%__1cMWordSizeListEgrow6Mki1_v_: c1_IR.o; +text: .text%__1cCIRSnotice_used_offset6Mi_v_; +text: .text%__1cCIRNcompute_loops6M_v_; +text: .text%__1cIciMethodJhas_loops6kM_i_; +text: .text%__1cNmethodOopDescWcompute_has_loops_flag6M_i_; +text: .text%__1cOBytecodeStreamEnext6M_nJBytecodesECode__: methodOop.o; +text: .text%__1cKLoopFinder2t6MpnCIR_i_v_; +text: .text%__1cSBlockLoopInfoArray2t6MkikpnNBlockLoopInfo__v_: c1_Loops.o; +text: .text%__1cKLoopFinderNcompute_loops6Mi_pnILoopList__; +text: .text%__1cJboolArray2t6Mki1_v_: c1_Loops.o; +text: .text%__1cKLoopFinderScompute_dominators6MpnJboolArray__v_; +text: .text%__1cGBitMapGat_put6MIi_v_; +text: .text%__1cRCreateInfoClosureIblock_do6MpnKBlockBegin__v_: c1_Loops.o; +text: .text%__1cNBlockLoopInfo2t6MpnKBlockBegin_i_v_; +text: .text%__1cPSetPredsClosureIblock_do6MpnKBlockBegin__v_: c1_Loops.o; +text: .text%__1cKLoopFinderSdominator_walk_sux6MpnKBlockBegin_pnJboolArray__v_; +text: .text%__1cGBitMapQset_intersection6M0_v_; +text: .text%__1cGBitMapHis_same6M0_i_; +text: .text%__1cKLoopFinderOfind_backedges6MpnJboolArray__pnILoopList__; +text: .text%__1cELoop2t6MpnKBlockBegin_2_v_: c1_Loops.o; +text: .text%__1cKLoopFinderSgather_loop_blocks6MpnILoopList__v_; +text: .text%__1cPBlockBeginArrayIindex_of6kMkpnKBlockBegin__i_: c1_Loops.o; +text: .text%__1cKLoopFinderKfind_loops6MpnILoopList_i_2_; +text: .text%__1cKScanBlocks2t6MpnJBlockList__v_; +text: .text%__1cIintStack2t6M_v_: c1_ScanBlocks.o; +text: .text%__1cKScanBlocksEscan6MpnKScanResult_i_v_; +text: .text%__1cKScanBlocksKscan_block6MpnKBlockBegin_pnKScanResult_i_v_; +text: .text%__1cLIllegalTypeDtag6kM_nIValueTag__: c1_ValueType.o; +text: .text%__1cLInstructionJas_Invoke6M_pnGInvoke__: c1_GraphBuilder.o; +text: .text%__1cLInstructionLas_NewArray6M_pnINewArray__: c1_GraphBuilder.o; +text: .text%__1cLInstructionOas_NewInstance6M_pnLNewInstance__: c1_GraphBuilder.o; +text: .text%__1cLInstructionQas_AccessMonitor6M_pnNAccessMonitor__: c1_GraphBuilder.o; +text: .text%__1cLInstructionOas_AccessLocal6M_pnLAccessLocal__: c1_Instruction.o; +text: .text%__1cLAccessLocalOas_AccessLocal6M_p0_: c1_GraphBuilder.o; +text: .text%__1cLInstructionNas_StoreLocal6M_pnKStoreLocal__: c1_GraphBuilder.o; +text: .text%__1cKStoreLocalNas_StoreLocal6M_p0_: c1_GraphBuilder.o; +text: .text%__1cKScanBlocksRaccumulate_access6MinIValueTag_i_v_; +text: .text%__1cKScanBlocksPincrement_count6MnIValueTag_ii_v_; +text: .text%__1cKScanBlocksJget_array6MnIValueTag__pnIintStack__; +text: .text%__1cIintStackEgrow6Mki1_v_: c1_ScanBlocks.o; +text: .text%__1cKScanBlocksLupdate_type6MinIValueTag__v_; +text: .text%__1cLInstructionJas_Invoke6M_pnGInvoke__: c1_Canonicalizer.o; +text: .text%__1cLInstructionLas_NewArray6M_pnINewArray__: c1_Canonicalizer.o; +text: .text%__1cLInstructionOas_NewInstance6M_pnLNewInstance__: c1_Canonicalizer.o; +text: .text%__1cLInstructionQas_AccessMonitor6M_pnNAccessMonitor__: c1_Canonicalizer.o; +text: .text%__1cJ_LoopListIpush_all6Mpk0_v_: c1_Loops.o; +text: .text%__1cKLoopFinderbEcompute_loop_exits_and_entries6MpnILoopList__v_; +text: .text%__1cKLoopFinderRfind_loop_entries6MpnKBlockBegin_pnELoop__v_; +text: .text%__1cKLoopFinderPfind_loop_exits6MpnKBlockBegin_pnELoop__v_; +text: .text%__1cKLoopFinderbDcompute_single_precision_flag6MpnILoopList__v_; +text: .text%__1cKLoopFinderNinsert_blocks6MpnILoopList__v_; +text: .text%__1cIintArray2t6Mki1_v_: c1_Loops.o; +text: .text%__1cJBlockListPiterate_forward6MpnMBlockClosure__v_; +text: .text%__1cGTaggerIblock_do6MpnKBlockBegin__v_: c1_Loops.o; +text: .text%__1cNPairCollectorIblock_do6MpnKBlockBegin__v_: c1_Loops.o; +text: .text%__1cNResourceArrayEsort6MIpGpkv2_i_v_; +text: .text%__1cRsort_by_block_ids6FppnJBlockPair_2_i_: c1_Loops.o; +text: .text%__1cKLoopFinderUinsert_caching_block6MpnILoopList_pnKBlockBegin_4_4_; +text: .text%__1cLInstructionQas_CachingChange6M_pnNCachingChange__: c1_GraphBuilder.o; +text: .text%__1cKStateSplitFscope6kM_pnHIRScope__; +text: .text%__1cKLoopFinderJnew_block6MpnHIRScope_i_pnKBlockBegin__; +text: .text%__1cIBlockEndOsubstitute_sux6MpnKBlockBegin_2_v_; +text: .text%__1cILoopListMupdate_loops6MpnKBlockBegin_22_v_; +text: .text%__1cELoopSupdate_loop_blocks6MpnKBlockBegin_22_v_; +text: .text%__1cCIRMcompute_code6M_v_; +text: .text%__1cJboolArray2t6Mki1_v_: c1_IR.o; +text: .text%__1cCIRWiterate_and_set_weight6kMrnJboolArray_pnKBlockBegin_pnJBlockList_i_v_; +text: .text%__1cKBlockBeginKset_weight6Mi_v_; +text: .text%__1cLInstructionIas_Throw6M_pnFThrow__: c1_IR.o; +text: .text%__1cLInstructionJas_Return6M_pnGReturn__: c1_IR.o; +text: .text%__1cLInstructionIas_Throw6M_pnFThrow__: c1_GraphBuilder.o; +text: .text%__1cDcmp6FppnKBlockBegin_2_i_: c1_IR.o; +text: .text%__1cUSuxAndWeightAdjusterIblock_do6MpnKBlockBegin__v_: c1_IR.o; +text: .text%__1cJBlockListJblocks_do6MpFpnKBlockBegin__v_v_; +text: .text%__1cQUseCountComputerRcompute_use_count6FpnKBlockBegin__v_: c1_IR.o; +text: .text%__1cQUseCountComputerXbasic_compute_use_count6FpnKBlockBegin__v_: c1_IR.o; +text: .text%__1cQUseCountComputerQupdate_use_count6FppnLInstruction__v_: c1_IR.o; +text: .text%__1cFLocalIas_Local6M_p0_: c1_GraphBuilder.o; +text: .text%__1cKStateSplitPstate_values_do6MpFppnLInstruction__v_v_; +text: .text%__1cKValueStackJvalues_do6MpFppnLInstruction__v_v_; +text: .text%__1cQUseCountComputerPupdated_pinning6FpnKBlockBegin__i_: c1_IR.o; +text: .text%__1cNCachingChangePinput_values_do6MpFppnLInstruction__v_v_: c1_Loops.o; +text: .text%__1cLInstructionLas_BlockEnd6M_pnIBlockEnd__: c1_Loops.o; +text: .text%__1cIBlockEndLas_BlockEnd6M_p0_: c1_IR.o; +text: .text%__1cLCompilationIemit_lir6M_v_; +text: .text%__1cIFrameMap2t6Mi_v_; +text: .text%__1cIFrameMapLFpuStackSim2t6M_v_; +text: .text%__1cLCompilationNinit_framemap6MpnIFrameMap__v_; +text: .text%__1cIFrameMapbCset_local_name_to_offset_map6MpnMWordSizeList__v_; +text: .text%__1cLLIR_Emitter2t6MpnLCompilation__v_; +text: .text%__1cIValueGenOinit_value_gen6F_v_; +text: .text%__1cIRegAlloc2t6M_v_; +text: .text%__1cNc1_AllocTable2t6Mi_v_; +text: .text%__1cIRegAllocFclear6M_v_; +text: .text%__1cNCodeGenerator2t6MpnIValueGen_pnRValueGenInvariant__v_; +text: .text%__1cNCodeGeneratorIblock_do6MpnKBlockBegin__v_; +text: .text%__1cLLIR_EmitterMmust_bailout6kM_i_; +text: .text%__1cNCodeGeneratorPblock_do_prolog6MpnKBlockBegin__v_; +text: .text%__1cIValueGenLstart_block6MpnKBlockBegin__v_; +text: .text%__1cLLIR_EmitterLstart_block6MpnKBlockBegin__v_; +text: .text%__1cILIR_List2t6MpnLCompilation__v_; +text: .text%__1cIValueGenQbind_block_entry6MpnKBlockBegin__v_; +text: .text%__1cLLIR_EmitterQbind_block_entry6MpnKBlockBegin__v_; +text: .text%__1cIValueGenMblock_prolog6MpnKBlockBegin__v_; +text: .text%__1cIValueGenHdo_root6MpnLInstruction__v_; +text: .text%__1cLInstructionGas_Phi6M_pnDPhi__: c1_GraphBuilder.o; +text: .text%__1cIValueGenNdo_BlockBegin6MpnKBlockBegin__v_; +text: .text%__1cQDelayedSpillMark2T6M_v_: c1_CodeGenerator.o; +text: .text%__1cLInstructionGas_Phi6M_pnDPhi__: c1_IR.o; +text: .text%__1cIValueGenHdo_Base6MpnEBase__v_; +text: .text%__1cIValueGenNreceiverRInfo6F_nFRInfo__; +text: .text%__1cIValueGenMicKlassRInfo6F_nFRInfo__; +text: .text%__1cLCompilationNget_init_vars6M_pnIintStack__; +text: .text%__1cLLIR_EmitterJstd_entry6MpnHIRScope_pnIintStack_nFRInfo_5_v_; +text: .text%__1cILIR_ListWunverified_entry_point6MnFRInfo_1_v_: c1_LIREmitter.o; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_LIREmitter.o; +text: .text%__1cLLIR_EmitterGmethod6kM_pnIciMethod__; +text: .text%__1cMCodeEmitInfo2t6MpnLLIR_Emitter_ipnIintStack_pnKValueStack_pnOExceptionScope_pnPRInfoCollection__v_; +text: .text%__1cLCompilationVvalue_stack2lir_stack6MpnKValueStack__pnNGrowableArray4CpnLLIR_OprDesc____; +text: .text%__1cIValueGenMblock_epilog6MpnKBlockBegin__v_; +text: .text%__1cNCodeGeneratorPblock_do_epilog6MpnKBlockBegin__v_; +text: .text%__1cLInstructionGas_Phi6M_pnDPhi__: c1_Canonicalizer.o; +text: .text%__1cIValueGenHdo_Goto6MpnEGoto__v_; +text: .text%__1cIValueGenNset_no_result6MpnLInstruction__v_; +text: .text%__1cIValueGenLmove_to_phi6MpnKValueStack_i_i_; +text: .text%__1cIValueGenWgoto_default_successor6MpnIBlockEnd_pnMCodeEmitInfo__v_; +text: .text%__1cLInstructionGas_Phi6M_pnDPhi__: c1_Instruction.o; +text: .text%__1cIValueGenMdo_LoadField6MpnJLoadField__v_; +text: .text%__1cLAccessFieldKlock_stack6kM_pnKValueStack__: c1_Instruction.o; +text: .text%__1cIValueGenEwalk6MpnLInstruction__v_; +text: .text%__1cIValueGenMdo_LoadLocal6MpnJLoadLocal__v_; +text: .text%__1cIValueGenJload_item6MpnEItem__v_; +text: .text%__1cEItemGupdate6M_v_; +text: .text%__1cIValueGenQset_maynot_spill6MpnEItem__v_; +text: .text%__1cIValueGenSfpu_fanout_handled6MpnEItem__i_; +text: .text%__1cEItemEtype6kM_pnJValueType__: c1_Items.o; +text: .text%__1cIValueGenPlock_free_rinfo6MpnLInstruction_pnJValueType__nFRInfo__; +text: .text%__1cIRegAllocMhas_free_reg6kMpnJValueType__i_; +text: .text%__1cIRegAllocMhas_free_reg6kMnIValueTag__i_; +text: .text%__1cNc1_AllocTableMhas_one_free6kM_i_; +text: .text%__1cIRegAllocNget_lock_temp6MpnLInstruction_pnJValueType__nFRInfo__; +text: .text%__1cIRegAllocMget_free_reg6MpnJValueType__nFRInfo__; +text: .text%__1cIRegAllocMget_free_reg6MnIValueTag__nFRInfo__; +text: .text%__1cNc1_AllocTableIget_free6M_i_; +text: .text%__1cNc1_AllocTablePget_free_helper6Mi_i_; +text: .text%__1cIRegAllocIlock_reg6MpnLInstruction_nFRInfo_i_v_; +text: .text%__1cJRInfo2RegFdo_it6M_v_: c1_RegAlloc.o; +text: .text%__1cHLockRegGdo_cpu6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIRegAllocOset_locked_cpu6MipnLInstruction_i_v_; +text: .text%__1cNc1_AllocTableKset_locked6Mi_v_; +text: .text%__1cLCompilationIitem2lir6MpknEItem__pnLLIR_OprDesc__; +text: .text%__1cLCompilationKitem2stack6MpknEItem__i_; +text: .text%__1cJValueTypeNas_DoubleType6M_pnKDoubleType__: c1_ValueType.o; +text: .text%__1cMas_BasicType6FpnJValueType__nJBasicType__; +text: .text%__1cJValueTypeMas_ArrayType6M_pnJArrayType__: c1_ValueType.o; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_Compilation.o; +text: .text%__1cLLIR_EmitterEmove6MpnLLIR_OprDesc_nFRInfo__v_; +text: .text%__1cILIR_ListEmove6MpnLLIR_OprDesc_2pnMCodeEmitInfo__v_: c1_LIREmitter.o; +text: .text%__1cIValueGenJitem_free6MpnEItem__v_; +text: .text%__1cIRegAllocPincr_spill_lock6MnFRInfo__v_; +text: .text%__1cQChangeSpillCountGdo_cpu6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIValueGenFrfree6MpnEItem__v_; +text: .text%__1cIRegAllocPdecr_spill_lock6MnFRInfo__v_; +text: .text%__1cIRegAllocIfree_reg6MnFRInfo__v_; +text: .text%__1cHFreeRegGdo_cpu6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIRegAllocMset_free_cpu6Mi_v_; +text: .text%__1cNc1_AllocTableIset_free6Mi_v_; +text: .text%__1cIValueGenWrlock_result_with_hint6MpnLInstruction_pknEItem__nFRInfo__; +text: .text%__1cIValueGenFrlock6MpnLInstruction_pknEItem__nFRInfo__; +text: .text%__1cIRegAllocMget_lock_reg6MpnLInstruction_pnJValueType__nFRInfo__; +text: .text%__1cLLIR_EmitterKfield_load6MnFRInfo_pnHciField_pnLLIR_OprDesc_iiipnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListMload_mem_reg6MnFRInfo_i1nJBasicType_pnMCodeEmitInfo_nHLIR_Op1NLIR_PatchCode__v_; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_LIR.o; +text: .text%__1cIRegAllocHset_reg6MnFRInfo_ipnLInstruction__v_; +text: .text%__1cGSetRegGdo_cpu6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIRegAllocLset_cpu_reg6MiipnLInstruction__v_; +text: .text%__1cIValueGenNdo_StoreLocal6MpnKStoreLocal__v_; +text: .text%__1cEItemRhandle_float_kind6M_v_; +text: .text%__1cEItemNset_from_item6Mpk0_v_: c1_Items.o; +text: .text%__1cIValueGenXcan_inline_any_constant6kM_i_; +text: .text%__1cIValueGenSmust_copy_register6MpnEItem__i_; +text: .text%__1cIValueGenUcheck_float_register6MpnEItem__v_; +text: .text%__1cIRegAllocLis_free_reg6kMnFRInfo__i_; +text: .text%__1cJIsFreeRegGdo_cpu6Mi_v_: c1_RegAlloc.o; +text: .text%__1cNc1_AllocTableHis_free6kMi_i_; +text: .text%__1cLLIR_EmitterJopr2local6MipnLLIR_OprDesc__v_; +text: .text%__1cILIR_ListQreg2single_stack6MnFRInfo_inJBasicType__v_: c1_LIREmitter.o; +text: .text%__1cIValueGenFdo_If6MpnCIf__v_; +text: .text%__1cIHintItemNset_from_item6MpknEItem__v_; +text: .text%__1cIHintItemEtype6kM_pnJValueType__: c1_Items.o; +text: .text%__1cJValueTypeMas_FloatType6M_pnJFloatType__: c1_ValueType.o; +text: .text%__1cIValueGenLdo_Constant6MpnIConstant__v_; +text: .text%__1cJValueTypeRas_ObjectConstant6M_pnOObjectConstant__: c1_Canonicalizer.o; +text: .text%__1cIValueGenOdont_load_item6MpnEItem__v_; +text: .text%__1cIValueGenWdont_load_item_nocheck6MpnEItem__v_; +text: .text%__1cLLIR_OprFactKvalue_type6FpnJValueType__pnLLIR_OprDesc__; +text: .text%__1cLLIR_EmitterFif_op6MinLInstructionJCondition_pnLLIR_OprDesc_4pnKBlockBegin_66pnMCodeEmitInfo__v_; +text: .text%__1cJLIR_ConstEtype6kM_nJBasicType__: c1_CacheLocals.o; +text: .text%__1cJLIR_ConstLas_constant6M_p0_: c1_CacheLocals.o; +text: .text%__1cLLIR_EmitterIlir_cond6MnLInstructionJCondition__nMLIR_OpBranchNLIR_Condition__; +text: .text%__1cILIR_ListDcmp6MnMLIR_OpBranchNLIR_Condition_pnLLIR_OprDesc_4pnMCodeEmitInfo__v_: c1_LIREmitter.o; +text: .text%__1cILIR_ListGbranch6MnMLIR_OpBranchNLIR_Condition_pnKBlockBegin__v_; +text: .text%__1cMLIR_OpBranch2t6Mn0ANLIR_Condition_pnKBlockBegin_pnMCodeEmitInfo__v_; +text: .text%__1cEItemEtype6kM_pnJValueType__: c1_CodeGenerator.o; +text: .text%__1cJArrayTypeMas_ArrayType6M_p0_: c1_ValueType.o; +text: .text%__1cLLIR_EmitterHopr2int6MpnLLIR_OprDesc__i_; +text: .text%__1cILIR_ListJint2stack6Mii_v_: c1_LIREmitter.o; +text: .text%__1cLInstructionGas_Phi6M_pnDPhi__: c1_Loops.o; +text: .text%__1cNCachingChangeFvisit6MpnSInstructionVisitor__v_: c1_Loops.o; +text: .text%__1cIValueGenQdo_CachingChange6MpnNCachingChange__v_; +text: .text%__1cIValueGenPdo_ArithmeticOp6MpnMArithmeticOp__v_; +text: .text%__1cIValueGenTdo_ArithmeticOp_Int6MpnMArithmeticOp__v_; +text: .text%__1cIValueGenOload_item_hint6MpnEItem_pk1_v_; +text: .text%__1cEItemRget_jint_constant6kM_i_; +text: .text%__1cLLIR_EmitterRarithmetic_op_int6MnJBytecodesECode_pnLLIR_OprDesc_44nFRInfo__v_; +text: .text%__1cLLIR_EmitterNarithmetic_op6MnJBytecodesECode_pnLLIR_OprDesc_44inFRInfo_pnMCodeEmitInfo__v_; +text: .text%__1cLLIR_EmitterYstrength_reduce_multiply6MpnLLIR_OprDesc_i22_i_; +text: .text%__1cILIR_ListHreg2reg6MnFRInfo_1nJBasicType__v_: c1_LIREmitter_x86.o; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_LIREmitter_x86.o; +text: .text%__1cLlog2_intptr6Fi_i_: c1_LIREmitter_x86.o; +text: .text%__1cILIR_ListKshift_left6MpnLLIR_OprDesc_222_v_; +text: .text%__1cILIR_ListDsub6MpnLLIR_OprDesc_22pnMCodeEmitInfo__v_: c1_LIREmitter_x86.o; +text: .text%__1cIValueGenWcan_inline_as_constant6MpnEItem__i_; +text: .text%__1cIRegAllocPget_register_rc6kMnFRInfo__i_; +text: .text%__1cLGetRefCountGdo_cpu6Mi_v_: c1_RegAlloc.o; +text: .text%__1cILIR_ListHreg2reg6MnFRInfo_1nJBasicType__v_: c1_LIREmitter.o; +text: .text%__1cILIR_ListDadd6MpnLLIR_OprDesc_22_v_: c1_LIREmitter.o; +text: .text%__1cIValueGenOdo_LoadIndexed6MpnLLoadIndexed__v_; +text: .text%__1cJValueTypeLas_LongType6M_pnILongType__: c1_ValueType.o; +text: .text%__1cLAccessArrayKlock_stack6kM_pnKValueStack__: c1_Instruction.o; +text: .text%__1cMCodeEmitInfoVfill_expression_stack6M_v_; +text: .text%__1cLLIR_EmitterRarray_range_check6MpnLLIR_OprDesc_2pnMCodeEmitInfo_4_v_; +text: .text%__1cORangeCheckStub2t6MpnMCodeEmitInfo_nFRInfo_ii_v_; +text: .text%__1cMCodeEmitInfo2t6Mp0i_v_; +text: .text%__1cLLIR_EmitterLcmp_reg_mem6MnMLIR_OpBranchNLIR_Condition_nFRInfo_3inJBasicType_pnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListLcmp_reg_mem6MnMLIR_OpBranchNLIR_Condition_nFRInfo_pnLLIR_Address_nJBasicType_pnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListGbranch6MnMLIR_OpBranchNLIR_Condition_pnICodeStub__v_; +text: .text%__1cMLIR_OpBranch2t6Mn0ANLIR_Condition_pnICodeStub_pnMCodeEmitInfo__v_; +text: .text%__1cLLIR_EmitterMindexed_load6MnFRInfo_nJBasicType_pnLLIR_OprDesc_4pnMCodeEmitInfo__v_; +text: .text%__1cLLIR_EmitterNarray_address6MpnLLIR_OprDesc_2inJBasicType__pnLLIR_Address__; +text: .text%__1cLLIR_AddressFscale6FnJBasicType__n0AFScale__; +text: .text%__1cILIR_ListEmove6MpnLLIR_Address_pnLLIR_OprDesc_pnMCodeEmitInfo__v_: c1_LIREmitter_x86.o; +text: .text%__1cIRegAllocNoops_in_spill6kM_pnIintStack__; +text: .text%__1cIRegAllocRoops_in_registers6kM_pnPRInfoCollection__; +text: .text%__1cIValueGenbDsafepoint_poll_needs_register6F_i_; +text: .text%__1cILIR_ListJsafepoint6MnFRInfo_pnMCodeEmitInfo__v_: c1_CodeGenerator.o; +text: .text%__1cLLIR_EmitterHgoto_op6MpnKBlockBegin_pnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListEjump6MpnKBlockBegin_pnMCodeEmitInfo__v_; +text: .text%__1cIValueGenNdo_StoreField6MpnKStoreField__v_; +text: .text%__1cIValueGenOscratch1_RInfo6kM_nFRInfo__; +text: .text%__1cIValueGenUprefer_alu_registers6kM_i_; +text: .text%__1cLLIR_EmitterLfield_store6MpnHciField_pnLLIR_OprDesc_i4iipnMCodeEmitInfo_nFRInfo__v_; +text: .text%__1cILIR_ListNstore_mem_reg6MnFRInfo_1inJBasicType_pnMCodeEmitInfo_nHLIR_Op1NLIR_PatchCode__v_; +text: .text%__1cIValueGenJdo_Return6MpnGReturn__v_; +text: .text%__1cJValueTypeLas_VoidType6M_pnIVoidType__: c1_ValueType.o; +text: .text%__1cIValueGenTresult_register_for6FpnJValueType_i_nFRInfo__; +text: .text%__1cIValueGenMreturn1RInfo6F_nFRInfo__; +text: .text%__1cIValueGenPload_item_force6MpnEItem_nFRInfo__v_; +text: .text%__1cIValueGenPlock_spill_temp6MpnLInstruction_nFRInfo__v_; +text: .text%__1cIRegAllocJlock_temp6MpnLInstruction_nFRInfo__v_; +text: .text%__1cLLIR_EmitterJreturn_op6MpnLLIR_OprDesc__v_; +text: .text%__1cNCodeGeneratorXclear_instruction_items6FpnKBlockBegin__v_; +text: .text%__1cQLIR_LocalCaching2t6MpnCIR__v_; +text: .text%__1cQLIR_LocalCachingQpreferred_locals6MpknIciMethod__pnMLocalMapping__; +text: .text%__1cMLocalMappingQinit_cached_regs6M_v_; +text: .text%__1cPRegisterManager2t6M_v_; +text: .text%__1cMLocalMappingNget_cache_reg6kMi_nFRInfo__; +text: .text%__1cQLIR_LocalCachingVcompute_cached_locals6M_v_; +text: .text%__1cQLIR_LocalCachingMcache_locals6M_v_; +text: .text%__1cLInstructionQas_CachingChange6M_pnNCachingChange__: c1_IR.o; +text: .text%__1cLInstructionQas_CachingChange6M_pnNCachingChange__: c1_Canonicalizer.o; +text: .text%__1cNCachingChangeQas_CachingChange6M_p0_: c1_Loops.o; +text: .text%__1cRBlockListScanInfo2t6MpnJBlockList__v_: c1_CacheLocals.o; +text: .text%__1cOLIR_OprRefList2t6M_v_: c1_CacheLocals.o; +text: .text%__1cRBlockListScanInfoItraverse6MpnKBlockBegin_pnKLIR_OpList__v_: c1_CacheLocals.o; +text: .text%__1cLLIR_OpLabelFvisit6MpnQLIR_OpVisitState__v_; +text: .text%__1cHLIR_Op1Fvisit6MpnQLIR_OpVisitState__v_; +text: .text%__1cPRegisterManagerElock6MnFRInfo__v_; +text: .text%__1cHLIR_Op2Fvisit6MpnQLIR_OpVisitState__v_; +text: .text%__1cMLIR_OpBranchFvisit6MpnQLIR_OpVisitState__v_; +text: .text%__1cORangeCheckStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; +text: .text%__1cQLIR_OpVisitStateGappend6MnFRInfo__v_: c1_CodeStubs_x86.o; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_CodeStubs_x86.o; +text: .text%__1cNc1_AllocTableFmerge6Mp0_v_; +text: .text%__1cGLIR_OpFvisit6MpnQLIR_OpVisitState__v_; +text: .text%__1cQLIR_LocalCachingXcache_locals_for_blocks6MpnJBlockList_pnPRegisterManager_i_pnMLocalMapping__; +text: .text%__1cLInstructionNas_StateSplit6M_pnKStateSplit__: c1_Loops.o; +text: .text%__1cLInstructionOas_AccessField6M_pnLAccessField__: c1_Loops.o; +text: .text%__1cLInstructionOas_AccessLocal6M_pnLAccessLocal__: c1_Loops.o; +text: .text%__1cKStateSplitNas_StateSplit6M_p0_: c1_IR.o; +text: .text%__1cLInstructionJas_Invoke6M_pnGInvoke__: c1_IR.o; +text: .text%__1cLInstructionLas_NewArray6M_pnINewArray__: c1_IR.o; +text: .text%__1cLInstructionOas_NewInstance6M_pnLNewInstance__: c1_IR.o; +text: .text%__1cLInstructionQas_AccessMonitor6M_pnNAccessMonitor__: c1_IR.o; +text: .text%__1cLInstructionMas_Intrinsic6M_pnJIntrinsic__: c1_IR.o; +text: .text%__1cKScanBlocksQmost_used_locals6M_pnKALocalList__; +text: .text%__1cKScanBlocksMint_count_at6kMi_i_; +text: .text%__1cKScanBlocksIcount_at6kMnIValueTag_i_i_; +text: .text%__1cKScanBlocksJget_array6kMnIValueTag__pknIintStack__; +text: .text%__1cKScanBlocksNlong_count_at6kMi_i_; +text: .text%__1cKScanBlocksMobj_count_at6kMi_i_; +text: .text%__1cKScanBlocksLis_obj_only6kMi_i_; +text: .text%__1cKScanBlocksLis_int_only6kMi_i_; +text: .text%__1cGALocalUsort_by_access_count6Fpp02_i_: c1_ScanBlocks.o; +text: .text%__1cQLIR_LocalCachingPcompute_caching6MpnKALocalList_pnPRegisterManager__pnMLocalMapping__; +text: .text%__1cPRegisterManagerMnum_free_cpu6M_i_; +text: .text%__1cMLocalMappingNget_cache_reg6kMinIValueTag__nFRInfo__; +text: .text%__1cPRegisterManagerMhas_free_reg6MnIValueTag__i_; +text: .text%__1cPRegisterManagerNlock_free_reg6MnIValueTag__nFRInfo__; +text: .text%__1cQLIR_LocalCachingQadd_at_all_names6FpnPRInfoCollection_inFRInfo_pnMWordSizeList__v_; +text: .text%__1cIintStackEgrow6Mki1_v_: c1_CacheLocals.o; +text: .text%__1cMLocalMappingFmerge6Mp0_v_; +text: .text%__1cGALocalNsort_by_index6Fpp02_i_: c1_CacheLocals.o; +text: .text%__1cSLocalMappingSetterIblock_do6MpnKBlockBegin__v_; +text: .text%__1cMLocalMappingEjoin6Mp0_v_; +text: .text%__1cPRegisterManagerLis_free_reg6MnFRInfo__i_; +text: .text%__1cQLIR_LocalCachingYinsert_transition_blocks6M_v_; +text: .text%__1cPBlockTransitionIblock_do6MpnKBlockBegin__v_: c1_CacheLocals.o; +text: .text%__1cGLIR_OpLas_OpBranch6M_pnMLIR_OpBranch__: c1_LIR.o; +text: .text%__1cMLocalMappingPemit_transition6FpnILIR_List_p03pnCIR__v_; +text: .text%__1cCIRThighest_used_offset6kM_i_; +text: .text%__1cILIR_ListQreg2single_stack6MnFRInfo_inJBasicType__v_: c1_CacheLocals.o; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_CacheLocals.o; +text: .text%__1cILIR_ListQsingle_stack2reg6MinFRInfo_nJBasicType__v_; +text: .text%__1cLInstructionQas_CachingChange6M_pnNCachingChange__: c1_Instruction.o; +text: .text%__1cLCompilationbBemit_code_prolog_non_native6MpnIFrameMap__v_; +text: .text%__1cHIRScopeJmax_stack6kM_i_; +text: .text%__1cNLIR_Optimizer2t6MpnCIR__v_; +text: .text%__1cRLIR_PeepholeState2t6M_v_; +text: .text%__1cRLIR_PeepholeStateKinitialize6MpnMLocalMapping__v_; +text: .text%__1cRLIR_PeepholeStateMclear_values6M_v_; +text: .text%__1cOLIR_OprRefList2t6M_v_: c1_LIROptimizer.o; +text: .text%__1cNLIR_OptimizerIoptimize6M_v_; +text: .text%__1cNLIR_OptimizerIoptimize6MpnJBlockList__v_; +text: .text%__1cNLIR_OptimizerIoptimize6MpnKBlockBegin__v_; +text: .text%__1cNLIR_OptimizerMblock_prolog6M_v_; +text: .text%__1cNLIR_OptimizerKprocess_op6M_v_; +text: .text%__1cGLIR_OpGas_Op16M_pnHLIR_Op1__: c1_LIR.o; +text: .text%__1cLLIR_OpLabelKas_OpLabel6M_p0_: c1_LIR.o; +text: .text%__1cRLIR_PeepholeStateVfinish_forward_branch6MpnFLabel__v_; +text: .text%__1cJLabelListIindex_of6kMkpnFLabel__i_: c1_LIROptimizer.o; +text: .text%__1cRLIR_PeepholeStateYset_disable_optimization6Mi_v_; +text: .text%__1cLLIR_OpLabelJemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerMemit_opLabel6MpnLLIR_OpLabel__v_; +text: .text%__1cNLIR_OptimizerFvisit6M_v_: c1_LIROptimizer_x86.o; +text: .text%__1cHLIR_Op0Jemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerIemit_op06MpnHLIR_Op0__v_; +text: .text%__1cHLIR_Op2Jemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerIemit_op26MpnHLIR_Op2__v_; +text: .text%__1cNLIR_OptimizerKhandle_opr6MpnLLIR_OprDesc_nQLIR_OpVisitStateHOprMode__2_; +text: .text%__1cNLIR_OptimizerJis_cached6MpnLLIR_OprDesc__i_; +text: .text%__1cNLIR_OptimizerUrecord_opr_reference6MpnLLIR_OprDesc__v_; +text: .text%__1cRLIR_PeepholeStateUrecord_opr_reference6MpnLLIR_OprDesc__i_; +text: .text%__1cRLIR_PeepholeStateLdefining_op6MpnLLIR_OprDesc__i_; +text: .text%__1cRLIR_PeepholeStateJreg2index6MpnLLIR_OprDesc__i_; +text: .text%__1cIintStackEgrow6Mki1_v_: c1_LIROptimizer.o; +text: .text%__1cNLIR_OptimizerMblock_epilog6M_v_; +text: .text%__1cRLIR_PeepholeStateRis_safe_to_delete6kMi_i_; +text: .text%__1cHLIR_Op1Gas_Op16M_p0_: c1_LIR.o; +text: .text%__1cHLIR_Op1Jemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerIemit_op16MpnHLIR_Op1__v_; +text: .text%__1cNLIR_OptimizerMprocess_move6MpnHLIR_Op1__v_; +text: .text%__1cMLocalMappingNget_cache_reg6kMpnLLIR_OprDesc__2_; +text: .text%__1cRLIR_PeepholeStateTmark_safe_to_delete6Mi_v_; +text: .text%__1cNLIR_OptimizerRreplace_stack_opr6MpnLLIR_OprDesc__2_; +text: .text%__1cNLIR_OptimizerNoptimize_move6MpnHLIR_Op1_rpnLLIR_OprDesc_5_i_; +text: .text%__1cRLIR_PeepholeStatebFequivalent_register_or_constant6MpnLLIR_OprDesc__2_; +text: .text%__1cRLIR_PeepholeStateOequivalent_opr6MpnLLIR_OprDesc__2_; +text: .text%__1cNLIR_OptimizerKmaybe_opto6MpnLLIR_OprDesc_2_2_: c1_LIROptimizer_x86.o; +text: .text%__1cNLIR_OptimizerMis_cache_reg6MpnLLIR_OprDesc__i_; +text: .text%__1cMLocalMappingMis_cache_reg6kMpnLLIR_OprDesc__i_; +text: .text%__1cMLocalMappingMis_cache_reg6kMnFRInfo__i_; +text: .text%__1cRLIR_PeepholeStateSequivalent_address6MpnLLIR_OprDesc__2_; +text: .text%__1cNLIR_OptimizerRresult_substitute6M_v_; +text: .text%__1cNLIR_OptimizerRnext_op_with_code6MnILIR_Code__pnGLIR_Op__; +text: .text%__1cNLIR_OptimizerFop_at6Mi_pnGLIR_Op__; +text: .text%__1cRLIR_PeepholeStateMkill_operand6MpnLLIR_OprDesc_i_v_; +text: .text%__1cRLIR_PeepholeStateQkill_equivalents6MpnLLIR_OprDesc__v_; +text: .text%__1cRLIR_PeepholeStateNkill_register6Mi_v_; +text: .text%__1cRLIR_PeepholeStateSrecord_defining_op6MpnLLIR_OprDesc_i_v_; +text: .text%__1cRLIR_PeepholeStatePset_defining_op6Mii_v_; +text: .text%__1cRLIR_PeepholeStateHdo_move6MpnLLIR_OprDesc_2_v_; +text: .text%__1cLLIR_OprListEgrow6MkikpnLLIR_OprDesc__v_: c1_LIROptimizer.o; +text: .text%__1cLLIR_AddressKas_address6M_p0_: c1_LIR.o; +text: .text%__1cRLIR_PeepholeStateTequivalent_register6MpnLLIR_OprDesc__2_; +text: .text%__1cKLIR_OprPtrLas_constant6M_pnJLIR_Const__: c1_LIR.o; +text: .text%__1cNLIR_OptimizerKallow_opto6M_i_; +text: .text%__1cNLIR_OptimizerLrecord_opto6MpnLLIR_OprDesc_2_2_; +text: .text%__1cLLIR_AddressEtype6kM_nJBasicType__: c1_LIR.o; +text: .text%__1cRLIR_PeepholeStateNincrement_ref6Mi_v_; +text: .text%__1cKLIR_OprPtrKas_address6M_pnLLIR_Address__: c1_CacheLocals.o; +text: .text%__1cMLIR_OpBranchLas_OpBranch6M_p0_: c1_LIR.o; +text: .text%__1cMLIR_OpBranchJemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerNemit_opBranch6MpnMLIR_OpBranch__v_; +text: .text%__1cNLIR_OptimizerQopr_live_on_exit6MpnLLIR_OprDesc__i_; +text: .text%__1cNResourceArrayJremove_at6MIi_v_; +text: .text%__1cRLIR_PeepholeStateLstack2index6MpnLLIR_OprDesc__i_; +text: .text%__1cRLIR_PeepholeStatePkill_stack_slot6Mi_v_; +text: .text%__1cRLIR_PeepholeStatebCequivalent_register_or_stack6MpnLLIR_OprDesc__2_; +text: .text%__1cNLIR_OptimizerKmaybe_opto6MpnLLIR_OprDesc_2_2_: c1_LIROptimizer.o; +text: .text%__1cNLIR_OptimizerLhandle_info6MpnMCodeEmitInfo__v_; +text: .text%__1cMCodeEmitInfoRset_local_mapping6MpnMLocalMapping__v_; +text: .text%__1cNLIR_OptimizerUrecord_register_oops6MpnMCodeEmitInfo__v_; +text: .text%__1cNLIR_OptimizerOemit_code_stub6MpnICodeStub__v_; +text: .text%__1cLCompilationOemit_code_body6MpnLCodeOffsets__i_; +text: .text%__1cNLIR_Assembler2t6MpnLCompilation_pnLCodeOffsets__v_; +text: .text%__1cNConstantTable2t6M_v_; +text: .text%__1cNLIR_AssemblerJemit_code6MpnJBlockList__v_; +text: .text%__1cQCollectConstantsIblock_do6MpnKBlockBegin__v_: c1_LIRAssembler.o; +text: .text%__1cLInstructionLas_Constant6M_pnIConstant__: c1_IR.o; +text: .text%__1cLInstructionLas_Constant6M_pnIConstant__: c1_Canonicalizer.o; +text: .text%__1cLInstructionLas_Constant6M_pnIConstant__: c1_Instruction.o; +text: .text%__1cJValueTypeNas_DoubleType6M_pnKDoubleType__: c1_Canonicalizer.o; +text: .text%__1cJValueTypeMas_FloatType6M_pnJFloatType__: c1_Canonicalizer.o; +text: .text%__1cLInstructionLas_Constant6M_pnIConstant__: c1_Loops.o; +text: .text%__1cNLIR_AssemblerOemit_constants6M_v_; +text: .text%__1cNConstantTableMemit_entries6MpnOMacroAssembler_i_v_; +text: .text%__1cLLIR_CodeGenIblock_do6MpnKBlockBegin__v_; +text: .text%__1cNLIR_AssemblerPcheck_codespace6M_v_; +text: .text%__1cNLIR_AssemblerMemit_opLabel6MpnLLIR_OpLabel__v_; +text: .text%__1cNLIR_AssemblerIemit_op06MpnHLIR_Op0__v_; +text: .text%__1cNLIR_AssemblerIemit_op26MpnHLIR_Op2__v_; +text: .text%__1cNLIR_AssemblerMneeds_icache6kMpnIciMethod__i_; +text: .text%__1cFRInfoLas_register6kM_pnMRegisterImpl__; +text: .text%__1cNLIR_AssemblerMcheck_icache6MpnMRegisterImpl_2_i_; +text: .text%__1cRC1_MacroAssemblerSinline_cache_check6MpnMRegisterImpl_2_v_; +text: .text%__1cRC1_MacroAssemblerOverified_entry6M_v_; +text: .text%__1cNLIR_AssemblerLbuild_frame6M_v_; +text: .text%__1cNLIR_AssemblerbBinitial_frame_size_in_bytes6M_i_; +text: .text%__1cIFrameMapJframesize6kM_i_; +text: .text%__1cRC1_MacroAssemblerLbuild_frame6Mi_v_; +text: .text%__1cRAbstractAssemblerbDgenerate_stack_overflow_check6Mi_v_; +text: .text%__1cOMacroAssemblerWbang_stack_with_offset6Mi_v_: c1_Compiler.o; +text: .text%__1cNLIR_AssemblerVsetup_locals_at_entry6M_v_; +text: .text%__1cIFrameMapYsignature_type_array_for6FpknIciMethod__pnNBasicTypeList__; +text: .text%__1cIFrameMapScalling_convention6FpknIciMethod_pnIintArray__pnRCallingConvention__; +text: .text%__1cIFrameMapScalling_convention6FirknOBasicTypeArray_pnIintArray__pnRCallingConvention__; +text: .text%__1cIintArray2t6Mki1_v_: c1_FrameMap_x86.o; +text: .text%__1cIFrameMapRname_for_argument6Fi_i_; +text: .text%__1cIFrameMapSfp_offset_for_name6kMiii_i_; +text: .text%__1cIFrameMapPnum_local_names6kM_i_; +text: .text%__1cIFrameMapNlocal_to_slot6kMii_i_; +text: .text%__1cIFrameMapSfp_offset_for_slot6kMi_i_; +text: .text%__1cQArgumentLocation2t6Mci_v_: c1_FrameMap_x86.o; +text: .text%__1cQArgumentLocationSset_stack_location6Mi_v_; +text: .text%__1cIFrameMapQaddress_for_name6kMiii_nHAddress__; +text: .text%__1cIFrameMapQmake_new_address6kMi_nHAddress__; +text: .text%__1cNLIR_AssemblerIemit_op16MpnHLIR_Op1__v_; +text: .text%__1cNLIR_AssemblerHmove_op6MpnLLIR_OprDesc_2nJBasicType_nHLIR_Op1NLIR_PatchCode_pnMCodeEmitInfo__v_; +text: .text%__1cNLIR_AssemblerHmem2reg6MpnLLIR_Address_nFRInfo_nJBasicType_nHLIR_Op1NLIR_PatchCode_pnMCodeEmitInfo__v_; +text: .text%__1cNLIR_AssemblerKas_Address6MpnLLIR_Address__nHAddress__; +text: .text%__1cNLIR_AssemblerHcomp_op6MnMLIR_OpBranchNLIR_Condition_pnLLIR_OprDesc_4nJBasicType__v_; +text: .text%__1cNLIR_AssemblerNemit_opBranch6MpnMLIR_OpBranch__v_; +text: .text%__1cNLIR_AssemblerJreg2stack6MnFRInfo_inJBasicType__v_; +text: .text%__1cNLIR_AssemblerLconst2stack6MpnJLIR_Const_i_v_; +text: .text%__1cNLIR_AssemblerJstack2reg6MpnLLIR_OprDesc_2nJBasicType__v_; +text: .text%__1cNLIR_AssemblerHreg2reg6MnFRInfo_1_v_; +text: .text%__1cNLIR_AssemblerJmove_regs6MpnMRegisterImpl_2_v_; +text: .text%__1cNLIR_AssemblerIshift_op6MnILIR_Code_nFRInfo_i2_v_; +text: .text%__1cNLIR_AssemblerIarith_op6MnILIR_Code_pnLLIR_OprDesc_33pnMCodeEmitInfo__v_; +text: .text%__1cNLIR_AssemblerbIadd_debug_info_for_null_check_here6MpnMCodeEmitInfo__v_; +text: .text%__1cNLIR_AssemblerLcode_offset6kM_i_; +text: .text%__1cNLIR_AssemblerbDadd_debug_info_for_null_check6MipnMCodeEmitInfo__v_; +text: .text%__1cNLIR_AssemblerOemit_code_stub6MpnICodeStub__v_; +text: .text%__1cVImplicitNullCheckStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; +text: .text%__1cNLIR_AssemblerCpc6kM_pC_; +text: .text%__1cICodeStubLset_code_pc6MpC_v_: c1_CodeStubs_x86.o; +text: .text%__1cICodeStubMis_call_stub6kM_i_: c1_CodeStubs_x86.o; +text: .text%__1cNCodeStubArrayIindex_of6kMkpnICodeStub__i_: c1_LIRAssembler.o; +text: .text%__1cORangeCheckStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; +text: .text%__1cNLIR_AssemblerOsafepoint_poll6MnFRInfo_pnMCodeEmitInfo__v_; +text: .text%__1cNLIR_AssemblerZadd_debug_info_for_branch6MpnMCodeEmitInfo__v_; +text: .text%__1cPpoll_RelocationEtype6M_nJrelocInfoJrelocType__: codeBlob.o; +text: .text%__1cMCodeEmitInfoRrecord_debug_info6MpnYDebugInformationRecorder_ii_v_; +text: .text%__1cMCodeEmitInfoHoop_map6M_pnGOopMap__; +text: .text%__1cMCodeEmitInfoScompute_debug_info6M_v_; +text: .text%__1cMCodeEmitInfoOcreate_oop_map6M_pnGOopMap__; +text: .text%__1cIFrameMapRoop_map_arg_count6M_i_; +text: .text%__1cMCodeEmitInfoTrecord_spilled_oops6kMpnIFrameMap_pnGOopMap__v_; +text: .text%__1cKciLocalMapNindex_for_bci6kMi_i_; +text: .text%__1cSciLocalMapIteratorJfind_next6M_v_: c1_LIREmitter.o; +text: .text%__1cJLocalSlotIfor_type6MpnJValueType_ii_pnFLocal__: c1_LIREmitter.o; +text: .text%__1cMCodeEmitInfoNget_cache_reg6kMinIValueTag__nFRInfo__; +text: .text%__1cIFrameMapTsingle_word_regname6kMi_nHOptoRegEName__; +text: .text%__1cIFrameMapMfp2sp_offset6kMi_i_; +text: .text%__1cGOopMapHset_oop6MnHOptoRegEName_ii_v_; +text: .text%__1cMCodeEmitInfoVlir_stack2value_stack6MpnNGrowableArray4CpnLLIR_OprDesc____pnNGrowableArray4CpnKScopeValue____; +text: .text%__1cMCodeEmitInfobCcompute_debug_info_for_scope6MpnHIRScope_ipnNGrowableArray4CpnKScopeValue___inGValues_i_pnQIRScopeDebugInfo__; +text: .text%__1cMCodeEmitInfobCscope_value_for_local_offset6MinILocationEType_ppnKScopeValue__4_; +text: .text%__1cMCodeEmitInfobEget_cache_reg_for_local_offset6kMi_nFRInfo__; +text: .text%__1cMLocalMappingbEget_cache_reg_for_local_offset6kMi_nFRInfo__; +text: .text%__1cMCodeEmitInfoZlocation_for_local_offset6MinILocationEType__1_; +text: .text%__1cIFrameMapZlocation_for_local_offset6kMinILocationEType_p1_i_; +text: .text%__1cIFrameMapWlocation_for_fp_offset6kMinILocationEType_p1_i_; +text: .text%__1cILocationVlegal_offset_in_bytes6Fi_i_; +text: .text%__1cMCodeEmitInfoYscope_value_for_register6MnFRInfo_ppnKScopeValue_4nILocationEType__v_; +text: .text%__1cGOopMapJdeep_copy6M_p0_; +text: .text%__1cGOopMap2t6Mn0ANDeepCopyToken_p0_v_; +text: .text%__1cMOopMapStream2t6MpnGOopMap__v_; +text: .text%__1cMOopMapStreamJfind_next6M_v_; +text: .text%__1cUCompressedReadStreamIread_int6M_i_: oopMap.o; +text: .text%__1cYDebugInformationRecorderNadd_safepoint6MiipnGOopMap__v_; +text: .text%__1cYDebugInformationRecorderLcheck_phase6Mn0AFPhase__v_; +text: .text%__1cYDebugInformationRecorderKadd_oopmap6MiipnGOopMap__v_; +text: .text%__1cYDebugInformationRecorderTcreate_scope_values6MpnNGrowableArray4CpnKScopeValue____pnKDebugToken__; +text: .text%__1cYDebugInformationRecorderWserialize_scope_values6MpnNGrowableArray4CpnKScopeValue____i_; +text: .text%__1cVCompressedWriteStreamJwrite_int6Mi_v_: debugInfoRec.o; +text: .text%__1cNLocationValueIwrite_on6MpnUDebugInfoWriteStream__v_; +text: .text%__1cVCompressedWriteStreamJwrite_int6Mi_v_: debugInfo.o; +text: .text%__1cILocationIwrite_on6MpnUDebugInfoWriteStream__v_; +text: .text%__1cVCompressedWriteStreamJwrite_int6Mi_v_: location.o; +text: .text%__1cYDebugInformationRecorderVcreate_monitor_values6MpnNGrowableArray4CpnMMonitorValue____pnKDebugToken__; +text: .text%__1cYDebugInformationRecorderYserialize_monitor_values6MpnNGrowableArray4CpnMMonitorValue____i_; +text: .text%__1cYDebugInformationRecorderOdescribe_scope6MpnIciMethod_ipnKDebugToken_44_v_; +text: .text%__1cYDebugInformationRecorderNappend_handle6MpnI_jobject__i_; +text: .text%__1cLOopRecorderOallocate_index6MpnI_jobject__i_; +text: .text%__1cLCompilationbEadd_exception_handlers_for_pco6MiipnOExceptionScope__v_; +text: .text%__1cNExceptionInfo2t6MiipnOExceptionScope__v_; +text: .text%__1cJAssemblerFtestl6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cNLIR_AssemblerHreg2mem6MnFRInfo_pnLLIR_Address_nJBasicType_nHLIR_Op1NLIR_PatchCode_pnMCodeEmitInfo__v_; +text: .text%__1cLLIR_OprDescGis_oop6kM_i_; +text: .text%__1cNLIR_AssemblerJreturn_op6MnFRInfo_i_v_; +text: .text%__1cWpoll_return_RelocationEtype6M_nJrelocInfoJrelocType__: codeBlob.o; +text: .text%__1cRC1_MacroAssemblerLmethod_exit6Mi_v_; +text: .text%__1cLCompilationQemit_code_epilog6MpnNLIR_Assembler__v_; +text: .text%__1cNLIR_AssemblerUemit_slow_case_stubs6M_v_; +text: .text%__1cNLIR_AssemblerKemit_stubs6MpnMCodeStubList__v_; +text: .text%__1cVImplicitNullCheckStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%__1cWImplicitExceptionTableGappend6MII_v_; +text: .text%__1cZresource_reallocate_bytes6FpcII_0_; +text: .text%__1cFArenaIArealloc6MpvII_1_; +text: .text%__1cNLIR_AssemblerNadd_call_info6MipnMCodeEmitInfo__v_; +text: .text%__1cOdummy_location6FnIValueTag__pnKScopeValue__: c1_LIREmitter.o; +text: .text%__1cQConstantIntValueIwrite_on6MpnUDebugInfoWriteStream__v_; +text: .text%__1cORangeCheckStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%__1cNLIR_AssemblerWemit_exception_handler6M_i_; +text: .text%__1cRC1_MacroAssemblerRexception_handler6Mii_v_; +text: .text%__1cNLIR_AssemblerPemit_call_stubs6M_v_; +text: .text%__1cNLIR_AssemblerbCmaybe_adjust_stack_alignment6MpnIciMethod__v_; +text: .text%__1cKreal_index6FpnIFrameMap_i_i_: c1_LIRAssembler_x86.o; +text: .text%__1cLCompilationbEgenerate_exception_range_table6M_v_; +text: .text%__1cOExceptionScopeGequals6kMp0_i_; +text: .text%__1cLCompilationbBadd_exception_range_entries6MiipnOExceptionScope_ip2pi_v_; +text: .text%__1cTExceptionRangeTablebCcompute_modified_at_call_pco6Fii_i_; +text: .text%__1cOExceptionScopeMcaller_scope6kM_p0_; +text: .text%__1cLLIR_EmitterKframe_size6M_i_; +text: .text%__1cNLIR_Assembler2T6M_v_; +text: .text%__1cLCompilationMinstall_code6MpnLCodeOffsets_i_v_; +text: .text%__1cFciEnvPregister_method6MpnIciMethod_iiiiiipnKCodeBuffer_ipnJOopMapSet_pnVExceptionHandlerTable_pnWImplicitExceptionTable_pnTExceptionRangeTable_pnQAbstractCompiler_ii_v_; +text: .text%__1cFciEnvbOcheck_for_system_dictionary_modification6MpnIciMethod__v_; +text: .text%__1cFciEnvbUsystem_dictionary_modification_counter_changed6M_i_; +text: .text%__1cHnmethodLnew_nmethod6FnMmethodHandle_iiiiiipnYDebugInformationRecorder_pnKCodeBuffer_ipnJOopMapSet_pnVExceptionHandlerTable_pnWImplicitExceptionTable_pnTExceptionRangeTable_pnQAbstractCompiler__p0_; +text: .text%__1cLOopRecorderIoop_size6M_i_; +text: .text%__1cYDebugInformationRecorderIpcs_size6M_i_; +text: .text%__1cYDebugInformationRecorderJdata_size6M_i_; +text: .text%__1cHnmethod2n6FIi_pv_; +text: .text%__1cHnmethod2t6MpnNmethodOopDesc_iiiiiiipnYDebugInformationRecorder_pnKCodeBuffer_ipnJOopMapSet_pnVExceptionHandlerTable_pnWImplicitExceptionTable_pnTExceptionRangeTable_pnQAbstractCompiler__v_; +text: .text%__1cKRelocationWfix_relocation_at_move6Mi_v_: codeBlob.o; +text: .text%__1cLPcDescCache2t6M_v_; +text: .text%__1cHnmFlagsFclear6M_v_; +text: .text%__1cYDebugInformationRecorderHcopy_to6MpnHnmethod__v_; +text: .text%__1cLOopRecorderHcopy_to6MpnICodeBlob__v_; +text: .text%__1cICodeBlobJcopy_oops6MppnI_jobject_i_v_; +text: .text%__1cIUniverseMnon_oop_word6F_pv_; +text: .text%__1cHnmethodQcopy_scopes_data6MpCi_v_; +text: .text%__1cGPcDesc2t6Miii_v_; +text: .text%__1cHnmethodKcopy_pc_at6MipnGPcDesc__v_; +text: .text%__1cHnmethodSresolve_JNIHandles6M_v_; +text: .text%__1cNRelocIteratorEnext6M_i_: nmethod.o; +text: .text%__1cJCodeCacheGcommit6FpnICodeBlob__v_; +text: .text%__1cHnmethodKis_nmethod6kM_i_: nmethod.o; +text: .text%__1cHnmethodUnumber_of_dependents6kM_i_: nmethod.o; +text: .text%__1cFVTuneOcreate_nmethod6FpnHnmethod__v_; +text: .text%__1cWImplicitExceptionTableHcopy_to6MpnHnmethod__v_; +text: .text%__1cTExceptionRangeTableHcopy_to6MpnHnmethod__v_; +text: .text%__1cKNativeJumpbEcheck_verified_entry_alignment6FpC1_v_; +text: .text%__1cGEventsDlog6FpkcE_v_: nmethod.o; +text: .text%__1cFciEnvKcompile_id6M_I_; +text: .text%__1cNmethodOopDescIset_code6MpnHnmethod__v_; +text: .text%__1cFciEnvbFpost_compiled_method_load_event6MpnHnmethod__v_; +text: .text%__1cLCompilation2T6M_v_; +text: .text%__1cFArena2T6M_v_; +text: .text%__1cFArenaRdestruct_contents6M_v_; +text: .text%__1cICHeapObj2k6Fpv_v_; +text: .text%__1cTExceptionRangeTable2T6M_v_; +text: .text%__1cFciEnvVnum_inlined_bytecodes6kM_i_; +text: .text%__1cMelapsedTimerDadd6M0_v_; +text: .text%__1cFciEnv2T6M_v_; +text: .text%__1cNCompileBrokerUpop_jni_handle_block6F_v_; +text: .text%__1cNCompileBrokerScollect_statistics6FpnOCompilerThread_nMelapsedTimer_pnLCompileTask__v_; +text: .text%__1cHnmethodKtotal_size6kM_i_; +text: .text%__1cHnmethodJcode_size6kM_i_: nmethod.o; +text: .text%__1cHnmethodOexception_size6kM_i_: nmethod.o; +text: .text%__1cHnmethodJstub_size6kM_i_: nmethod.o; +text: .text%__1cHnmethodQscopes_data_size6kM_i_: nmethod.o; +text: .text%__1cHnmethodPscopes_pcs_size6kM_i_: nmethod.o; +text: .text%__1cLAccessFlagsRatomic_clear_bits6Mi_v_; +text: .text%__1cSCompileTaskWrapper2T6M_v_; +text: .text%__1cNCompileBrokerJfree_task6FpnLCompileTask__v_; +text: .text%__1cLCompileTaskEfree6M_v_; +text: .text%__1cKJNIHandlesOdestroy_global6FpnI_jobject_i_v_; +text: .text%__1cNSignatureInfoGdo_int6M_v_: reflection.o; +text: .text%__1cNArgumentCountDset6MinJBasicType__v_: reflection.o; +text: .text%__1cZget_mirror_from_signature6FnMmethodHandle_pnPSignatureStream_pnGThread__pnHoopDesc__; +text: .text%__1cPjava_lang_ClassQprimitive_mirror6FnJBasicType__pnHoopDesc__; +text: .text%__1cNSignatureInfoHdo_long6M_v_: reflection.o; +text: .text%__1cNSignatureInfoJdo_object6Mii_v_: reflection.o; +text: .text%__1cPSignatureStreamJas_symbol6MpnGThread__pnNsymbolOopDesc__; +text: .text%__1cKReflectionbFbasic_type_mirror_to_basic_type6FpnHoopDesc_pnGThread__nJBasicType__; +text: .text%__1cPjava_lang_ClassOprimitive_type6FpnHoopDesc__nJBasicType__; +text: .text%__1cQSystemDictionaryQjava_mirror_type6FpnHoopDesc__nJBasicType__; +text: .text%__1cKReflectionTunbox_for_primitive6FpnHoopDesc_pnGjvalue_pnGThread__nJBasicType__; +text: .text%__1cXjava_lang_boxing_objectJget_value6FpnHoopDesc_pnGjvalue__nJBasicType__; +text: .text%__1cUGenericGrowableArrayGgrow646Mi_v_; +text: .text%__1cRComputeEntryStackGdo_int6M_v_: generateOopMap.o; +text: .text%__1cOGenerateOopMapJppdupswap6Mipkc_v_; +text: .text%__1cOGenerateOopMapJdo_method6Miiii_v_; +text: .text%__1cQComputeCallStackHdo_void6M_v_: generateOopMap.o; +text: .text%__1cQComputeCallStackGdo_int6M_v_: generateOopMap.o; +text: .text%__1cLciSignatureHtype_at6kMi_pnGciType__; +text: .text%__1cLInstructionMas_CompareOp6M_pnJCompareOp__: c1_GraphBuilder.o; +text: .text%__1cLInstructionNas_InstanceOf6M_pnKInstanceOf__: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderMnew_instance6Mi_v_; +text: .text%__1cQciBytecodeStreamJget_klass6kM_pnHciKlass__; +text: .text%__1cQciBytecodeStreamPget_klass_index6kM_i_; +text: .text%__1cVLoaderConstraintTableWfind_constrained_klass6MnMsymbolHandle_nGHandle__pnMklassOopDesc__; +text: .text%__1cIciSymbolHbyte_at6Mi_i_; +text: .text%__1cPciInstanceKlassNloader_handle6M_pnI_jobject__; +text: .text%__1cPciInstanceKlassYprotection_domain_handle6M_pnI_jobject__; +text: .text%__1cGciTypeMis_classless6kM_i_: ciInstanceKlass.o; +text: .text%__1cMGraphBuilderMappend_split6MpnKStateSplit__pnLInstruction__; +text: .text%__1cLNewInstanceFvisit6MpnSInstructionVisitor__v_: c1_Instruction.o; +text: .text%__1cNCanonicalizerOdo_NewInstance6MpnLNewInstance__v_; +text: .text%__1cLInstructionEhash6kM_i_: c1_Instruction.o; +text: .text%__1cKStateSplitNas_StateSplit6M_p0_: c1_Instruction.o; +text: .text%__1cLInstructionJas_Invoke6M_pnGInvoke__: c1_Instruction.o; +text: .text%__1cKValueStackMclear_locals6M_v_; +text: .text%__1cKValueStackMclear_stores6M_v_; +text: .text%__1cKValueStackZpin_stack_for_state_split6M_v_; +text: .text%__1cLNewInstanceIcan_trap6kM_i_: c1_Instruction.o; +text: .text%__1cMGraphBuilderIstack_op6MnJBytecodesECode__v_; +text: .text%__1cMGraphBuilderGinvoke6MnJBytecodesECode__v_; +text: .text%__1cQciBytecodeStreamKget_method6kM_pnIciMethod__; +text: .text%__1cQciBytecodeStreamQget_method_index6kM_i_; +text: .text%__1cFciEnvTget_method_by_index6MpnPciInstanceKlass_inJBytecodesECode__pnIciMethod__; +text: .text%__1cFciEnvYget_method_by_index_impl6MpnPciInstanceKlass_inJBytecodesECode__pnIciMethod__; +text: .text%__1cFciEnvbTget_instance_klass_for_declared_method_holder6FpnHciKlass__pnPciInstanceKlass__; +text: .text%__1cPciObjectFactoryTget_unloaded_method6MpnPciInstanceKlass_pnIciSymbol_4_pnIciMethod__; +text: .text%__1cIciMethod2t6MpnPciInstanceKlass_pnIciSymbol_4_v_; +text: .text%__1cNciMethodKlassEmake6F_p0_; +text: .text%__1cIciObjectMis_classless6kM_i_: ciMethod.o; +text: .text%__1cQciBytecodeStreambAget_declared_method_holder6M_pnHciKlass__; +text: .text%__1cQciBytecodeStreamXget_method_holder_index6M_i_; +text: .text%__1cLciSignatureLreturn_type6kM_pnGciType__; +text: .text%__1cKValueStackNpop_arguments6Mi_pnGValues__; +text: .text%__1cGInvoke2t6MnJBytecodesECode_pnJValueType_pnLInstruction_pnGValues_iiii_v_; +text: .text%__1cGInvokeFvisit6MpnSInstructionVisitor__v_: c1_Instruction.o; +text: .text%__1cNCanonicalizerJdo_Invoke6MpnGInvoke__v_; +text: .text%__1cGInvokeJas_Invoke6M_p0_: c1_Instruction.o; +text: .text%__1cLInstructionMas_LoadLocal6M_pnJLoadLocal__: c1_Instruction.o; +text: .text%__1cGInvokeIcan_trap6kM_i_: c1_Instruction.o; +text: .text%__1cMGraphBuilderIthrow_op6M_v_; +text: .text%__1cFThrowFvisit6MpnSInstructionVisitor__v_: c1_Instruction.o; +text: .text%__1cNCanonicalizerIdo_Throw6MpnFThrow__v_; +text: .text%__1cIBlockEndLas_BlockEnd6M_p0_: c1_Instruction.o; +text: .text%__1cFThrowIcan_trap6kM_i_: c1_Instruction.o; +text: .text%__1cLInstructionJas_Return6M_pnGReturn__: c1_Instruction.o; +text: .text%__1cFThrowIas_Throw6M_p0_: c1_Instruction.o; +text: .text%__1cLInstructionFas_If6M_pnCIf__: c1_Instruction.o; +text: .text%__1cLInstructionHas_Goto6M_pnEGoto__: c1_Instruction.o; +text: .text%__1cKStateSplitPinput_values_do6MpFppnLInstruction__v_v_: c1_Instruction.o; +text: .text%__1cQNullCheckVisitorOdo_NewInstance6MpnLNewInstance__v_; +text: .text%__1cTNullCheckEliminatorShandle_NewInstance6MpnLNewInstance__v_; +text: .text%__1cGInvokePinput_values_do6MpFppnLInstruction__v_v_: c1_Instruction.o; +text: .text%__1cQNullCheckVisitorJdo_Invoke6MpnGInvoke__v_; +text: .text%__1cTNullCheckEliminatorNhandle_Invoke6MpnGInvoke__v_; +text: .text%__1cFThrowPinput_values_do6MpFppnLInstruction__v_v_: c1_Instruction.o; +text: .text%__1cQNullCheckVisitorIdo_Throw6MpnFThrow__v_; +text: .text%__1cPBlockBeginArrayIindex_of6kMkpnKBlockBegin__i_: c1_IR.o; +text: .text%__1cLInstructionGnegate6Fn0AJCondition__1_; +text: .text%__1cFThrowPstate_values_do6MpFppnLInstruction__v_v_; +text: .text%__1cFRInfoIoverlaps6kMk0_i_; +text: .text%__1cIValueGenOdo_NewInstance6MpnLNewInstance__v_; +text: .text%__1cIValueGenVspill_values_on_stack6MpnKValueStack_nFRInfo_i_v_; +text: .text%__1cIRegAllocNlock_register6MpnLInstruction_nFRInfo__v_; +text: .text%__1cHHideReg2t6MpnIValueGen_pnJValueType__v_; +text: .text%__1cHHideReg2T6M_v_; +text: .text%__1cLLIR_EmitterMnew_instance6MnFRInfo_pnPciInstanceKlass_1111pnMCodeEmitInfo__v_; +text: .text%__1cLLIR_EmitterZjobject2reg_with_patching6MnFRInfo_pnIciObject_pnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListNoop2reg_patch6MpnI_jobject_nFRInfo_pnMCodeEmitInfo__v_; +text: .text%__1cPNewInstanceStub2t6MnFRInfo_pnLLIR_OprDesc_pnPciInstanceKlass_pnMCodeEmitInfo_nIRuntime1GStubID__v_; +text: .text%__1cIValueGenJdo_Invoke6MpnGInvoke__v_; +text: .text%__1cIValueGenWinvoke_visit_arguments6MpnGInvoke_pnRCallingConvention__pnJItemArray__; +text: .text%__1cIValueGenNis_free_rinfo6MnFRInfo__i_; +text: .text%__1cGInvokeRsize_of_arguments6kM_i_; +text: .text%__1cLLIR_EmitterVstore_stack_parameter6MpnLLIR_OprDesc_i_v_; +text: .text%__1cILIR_ListFstore6MpnLLIR_OprDesc_pnLLIR_Address_nJBasicType_pnMCodeEmitInfo_nHLIR_Op1NLIR_PatchCode__v_; +text: .text%__1cHHideReg2t6MpnIValueGen_nFRInfo_i_v_; +text: .text%__1cIValueGenVinvoke_load_arguments6MpnGInvoke_pnJItemArray_pnRCallingConvention__v_; +text: .text%__1cIValueGenPinvoke_do_spill6MpnGInvoke_nFRInfo__v_; +text: .text%__1cIValueGenXis_caller_save_register6FnFRInfo__i_; +text: .text%__1cIValueGenLspill_value6MpnLInstruction__v_; +text: .text%__1cIValueGenKspill_item6MpnEItem__v_; +text: .text%__1cIValueGenQround_spill_item6MpnEItem_i_v_; +text: .text%__1cIRegAllocOget_lock_spill6MpnLInstruction_i_i_; +text: .text%__1cIValueGenJraw_rfree6MpnEItem__v_; +text: .text%__1cLLIR_EmitterFspill6MipnLLIR_OprDesc__v_; +text: .text%__1cIFrameMapKspill_name6kMi_i_; +text: .text%__1cIValueGenQinvoke_do_result6MpnGInvoke_ipnEItem__v_; +text: .text%__1cIVoidTypeLas_VoidType6M_p0_: c1_ValueType.o; +text: .text%__1cLCompilationXlir_opr_for_instruction6MpnLInstruction__pnLLIR_OprDesc__; +text: .text%__1cLLIR_EmitterHcall_op6MnJBytecodesECode_pknOBasicTypeArray_pnMCodeEmitInfo_iiinFRInfo_pnLLIR_OprDesc__v_; +text: .text%__1cILIR_ListKnull_check6MnFRInfo_pnMCodeEmitInfo__v_: c1_LIREmitter.o; +text: .text%__1cILIR_ListQcall_opt_virtual6MnFRInfo_pnLLIR_OprDesc_pCpnMCodeEmitInfo_pnOStaticCallStub__v_: c1_LIREmitter.o; +text: .text%__1cIValueGenIdo_Throw6MpnFThrow__v_; +text: .text%__1cLNewInstanceKexact_type6kM_pnGciType__; +text: .text%__1cOExceptionScopeLcould_catch6kMpnPciInstanceKlass_i_i_; +text: .text%__1cIValueGenRexceptionOopRInfo6F_nFRInfo__; +text: .text%__1cIValueGenFsfree6MpnEItem__v_; +text: .text%__1cIRegAllocKfree_spill6MipnJValueType__v_; +text: .text%__1cIRegAllocNis_free_spill6kMipnJValueType__i_; +text: .text%__1cLNewInstanceOas_NewInstance6M_p0_: c1_Instruction.o; +text: .text%__1cIValueGenQexceptionPcRInfo6F_nFRInfo__; +text: .text%__1cILIR_ListPthrow_exception6MnFRInfo_1pnMCodeEmitInfo__v_: c1_CodeGenerator.o; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_CodeGenerator.o; +text: .text%__1cPNewInstanceStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; +text: .text%__1cOLIR_OpJavaCallFvisit6MpnQLIR_OpVisitState__v_; +text: .text%__1cQLIR_OpVisitStateGappend6MnFRInfo__v_: c1_LIR.o; +text: .text%__1cOStaticCallStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; +text: .text%__1cIFrameMapWcaller_save_cpu_reg_at6Fi_pnLLIR_OprDesc__; +text: .text%__1cLInstructionLas_NewArray6M_pnINewArray__: c1_Instruction.o; +text: .text%__1cIVoidTypeDtag6kM_nIValueTag__: c1_ValueType.o; +text: .text%__1cLInstructionOas_NewInstance6M_pnLNewInstance__: c1_Instruction.o; +text: .text%__1cLInstructionQas_AccessMonitor6M_pnNAccessMonitor__: c1_Instruction.o; +text: .text%__1cRLIR_PeepholeStateHdo_call6M_v_; +text: .text%__1cOLIR_OpJavaCallJemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerJemit_call6MpnOLIR_OpJavaCall__v_; +text: .text%__1cNLIR_AssemblerJconst2reg6MpnJLIR_Const_nFRInfo_nHLIR_Op1NLIR_PatchCode_pnMCodeEmitInfo__v_; +text: .text%__1cMPatchingStubQalign_patch_site6MpnOMacroAssembler__v_; +text: .text%__1cJAssemblerEmovl6MpnMRegisterImpl_pnI_jobject__v_; +text: .text%__1cOoop_RelocationLunpack_data6M_v_; +text: .text%__1cKRelocationNunpack_2_ints6Mri1_v_: relocInfo.o; +text: .text%__1cOoop_RelocationEtype6M_nJrelocInfoJrelocType__: relocInfo.o; +text: .text%__1cOoop_RelocationJpack_data6M_i_; +text: .text%__1cNLIR_AssemblerPpatching_epilog6MpnMPatchingStub_nHLIR_Op1NLIR_PatchCode_pnMRegisterImpl_pnMCodeEmitInfo__v_; +text: .text%__1cMPatchingStubHinstall6MpnOMacroAssembler_nHLIR_Op1NLIR_PatchCode_pnMRegisterImpl_pnMCodeEmitInfo__v_: c1_LIRAssembler.o; +text: .text%__1cNLIR_AssemblerUappend_patching_stub6MpnMPatchingStub__v_; +text: .text%__1cPNewInstanceStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; +text: .text%__1cNLIR_AssemblerJemit_call6MpnOLIR_OpJavaCall__v_; +text: .text%__1cNLIR_AssemblerKalign_call6MnILIR_Code__v_; +text: .text%__1cICodeStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; +text: .text%__1cOStaticCallStubLset_code_pc6MpC_v_: c1_CodeStubs_x86.o; +text: .text%__1cOStaticCallStubMis_call_stub6kM_i_: c1_CodeStubs_x86.o; +text: .text%__1cNLIR_AssemblerEcall6MpCnJrelocInfoJrelocType_pnMCodeEmitInfo__v_; +text: .text%__1cbBopt_virtual_call_RelocationEtype6M_nJrelocInfoJrelocType__: relocInfo.o; +text: .text%__1cKRelocationJpack_data6M_i_: relocInfo.o; +text: .text%__1cMCodeEmitInfoSappend_scope_value6MpnLLIR_OprDesc_pnNGrowableArray4CpnKScopeValue____v_; +text: .text%__1cMCodeEmitInfoRopr2location_type6MpnLLIR_OprDesc__nILocationEType__; +text: .text%__1cMCodeEmitInfoRlocation_for_name6MinILocationEType_ii_1_; +text: .text%__1cIFrameMapRlocation_for_name6kMinILocationEType_p1ii_i_; +text: .text%__1cNLIR_AssemblerIthrow_op6MnFRInfo_1pnMCodeEmitInfo_i_v_; +text: .text%__1cMCodeEmitInfoQadd_register_oop6MnFRInfo__v_; +text: .text%__1cIintArrayIindex_of6kMki_i_: c1_LIREmitter.o; +text: .text%__1cMCodeEmitInfoYadd_registers_to_oop_map6MpnGOopMap__v_; +text: .text%__1cYinternal_word_RelocationEtype6M_nJrelocInfoJrelocType__: relocInfo.o; +text: .text%__1cYinternal_word_RelocationJpack_data6M_i_; +text: .text%__1cJrelocInfoKset_format6Mi_v_; +text: .text%__1cMPatchingStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%__1cRAbstractAssemblerGa_byte6Mi_v_; +text: .text%__1cRNativeGeneralJumpUinsert_unconditional6FpC1_v_; +text: .text%__1cNRelocIterator2t6MpnKCodeBuffer_pC3_v_; +text: .text%__1cJrelocInfobDchange_reloc_info_for_address6FpnNRelocIterator_pCn0AJrelocType_4_v_; +text: .text%__1cJrelocInfoIset_type6Mn0AJrelocType__v_; +text: .text%__1cPNewInstanceStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%__1cJOopMapSetMgrow_om_data6M_v_; +text: .text%__1cOStaticCallStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%__1cWstatic_stub_RelocationEtype6M_nJrelocInfoJrelocType__: relocInfo.o; +text: .text%__1cWstatic_stub_RelocationJpack_data6M_i_; +text: .text%__1cNRelocIteratorTadvance_over_prefix6M_v_; +text: .text%__1cOCallRelocationFvalue6M_pC_: relocInfo.o; +text: .text%__1cYinternal_word_RelocationLunpack_data6M_v_; +text: .text%__1cYinternal_word_RelocationWfix_relocation_at_move6Mi_v_; +text: .text%__1cYinternal_word_RelocationFvalue6M_pC_: relocInfo.o; +text: .text%__1cYinternal_word_RelocationGtarget6M_pC_; +text: .text%__1cODataRelocationJset_value6MpC_v_: relocInfo.o; +text: .text%__1cODataRelocationGoffset6M_i_: relocInfo.o; +text: .text%__1cKRelocationRpd_set_data_value6MpCi_v_; +text: .text%__1cKRelocationSpd_address_in_code6M_ppC_; +text: .text%__1cWstatic_stub_RelocationLunpack_data6M_v_; +text: .text%__1cPBoundRelocationLunpack_data6MnJrelocInfoJrelocType__v_: nmethod.o; +text: .text%__1cOoop_RelocationHoops_do6MpFppnHoopDesc__v_v_; +text: .text%__1cOoop_RelocationIoop_addr6M_ppnHoopDesc__; +text: .text%__1cRresolve_and_patch6FppnHoopDesc__v_; +text: .text%__1cMPeriodicTaskOreal_time_tick6FI_v_; +text: .text%__1cPStatSamplerTaskEtask6M_v_: statSampler.o; +text: .text%__1cLStatSamplerOcollect_sample6F_v_; +text: .text%__1cLStatSamplerLsample_data6FpnMPerfDataList__v_; +text: .text%jni_GetPrimitiveArrayCritical: jni.o; +text: .text%jni_ReleasePrimitiveArrayCritical: jni.o; +text: .text%jni_SetBooleanField: jni.o; +text: .text%__1cNFingerprinterIdo_float6M_v_: dump.o; +text: .text%__1cXNativeSignatureIteratorIdo_float6M_v_: interpreterRuntime.o; +text: .text%JVM_IsNaN; +text: .text%__1cNFingerprinterJdo_double6M_v_: dump.o; +text: .text%__1cXNativeSignatureIteratorJdo_double6M_v_: interpreterRuntime.o; +text: .text%__1cXNativeSignatureIteratorLpass_double6M_v_: interpreterRuntime.o; +text: .text%__1cKExceptionsL_throw_args6FpnGThread_pkcinMsymbolHandle_5pnRJavaCallArguments__v_; +text: .text%jni_GetArrayLength: jni.o; +text: .text%JVM_Read; +text: .text%__1cDhpiEread6FipvI_I_: jvm.o; +text: .text%__1cKJNIHandlesKmake_local6FpnGThread_pnHoopDesc__pnI_jobject__; +text: .text%__1cRComputeEntryStackJdo_object6Mii_v_: generateOopMap.o; +text: .text%__1cQComputeCallStackHdo_char6M_v_: generateOopMap.o; +text: .text%__1cQComputeCallStackJdo_object6Mii_v_: generateOopMap.o; +text: .text%__1cFciEnvNlookup_method6MpnNinstanceKlass_2pnNsymbolOopDesc_4nJBytecodesECode__pnNmethodOopDesc__; +text: .text%__1cMLinkResolverbNlinktime_resolve_virtual_method_or_null6FnLKlassHandle_nMsymbolHandle_21i_nMmethodHandle__; +text: .text%__1cIciMethodXfind_monomorphic_target6MpnHciKlass_22_p0_; +text: .text%__1cDCHAManalyze_call6FnLKlassHandle_11nMsymbolHandle_2_pnJCHAResult__; +text: .text%__1cMLinkResolverbCresolve_virtual_call_or_null6FnLKlassHandle_1nMsymbolHandle_21_nMmethodHandle__; +text: .text%__1cJCHAResult2t6MnLKlassHandle_nMsymbolHandle_2pnNGrowableArray4n0B___pnNGrowableArray4nMmethodHandle___n0E_i_v_; +text: .text%__1cJCHAResultOis_monomorphic6kM_i_; +text: .text%__1cJCHAResultSmonomorphic_target6kM_nMmethodHandle__; +text: .text%__1cIciMethodJwill_link6MpnHciKlass_2nJBytecodesECode__i_; +text: .text%__1cMGraphBuilderKtry_inline6MpnIciMethod_i_i_; +text: .text%__1cMGraphBuilderUclear_inline_bailout6M_v_; +text: .text%__1cIciMethodOshould_exclude6M_i_; +text: .text%__1cIciMethodPcan_be_compiled6M_i_; +text: .text%__1cMGraphBuilderVtry_inline_intrinsics6MpnIciMethod__i_; +text: .text%__1cMGraphBuilderPtry_inline_full6MpnIciMethod_i_i_; +text: .text%__1cIciMethodIhas_jsrs6kM_i_; +text: .text%__1cMGraphBuilderWrecursive_inline_level6kMpnIciMethod__i_; +text: .text%__1cPciObjectFactoryMvm_symbol_at6Fi_pnIciSymbol__; +text: .text%__1cJNullCheckFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerMdo_NullCheck6MpnJNullCheck__v_; +text: .text%__1cJNullCheckIcan_trap6kM_i_: c1_GraphBuilder.o; +text: .text%__1cKObjectTypeEbase6kM_pnJValueType__: c1_ValueType.o; +text: .text%__1cKValueStackEpush6MpnJValueType_pnLInstruction__v_: c1_ValueStack.o; +text: .text%__1cMGraphBuilderKpush_scope6MpnIciMethod_pnKBlockBegin_i_v_; +text: .text%__1cKValueStackKpush_scope6MpnHIRScope__p0_; +text: .text%__1cOExceptionScopeKpush_scope6M_p0_; +text: .text%__1cOExceptionScope2t6Mp0_v_; +text: .text%__1cHIRScopeXcompute_lock_stack_size6M_v_; +text: .text%__1cMGraphBuilderJScopeDataRcaller_stack_size6kM_i_; +text: .text%__1cMGraphBuilderJScopeDataLnum_returns6M_i_; +text: .text%__1cMGraphBuilderJScopeDataXset_inline_cleanup_info6MpnKBlockBegin_pnLInstruction_pnKValueStack__v_; +text: .text%__1cMGraphBuilderJScopeDataQincr_num_returns6M_v_; +text: .text%__1cKValueStackJpop_scope6Mii_p0_; +text: .text%__1cMGraphBuilderJpop_scope6M_v_; +text: .text%__1cMGraphBuilderTpop_exception_scope6M_v_; +text: .text%__1cOExceptionScopeJpop_scope6M_p0_; +text: .text%__1cLCompilationVnotice_inlined_method6MpnIciMethod__v_; +text: .text%__1cFciEnvVnotice_inlined_method6MpnIciMethod__v_; +text: .text%__1cMLinkResolverbCresolve_special_call_or_null6FnLKlassHandle_nMsymbolHandle_21_nMmethodHandle__; +text: .text%__1cMGraphBuilderOinline_bailout6Mpkc_v_; +text: .text%__1cLInstructionEprev6MpnKBlockBegin__p0_; +text: .text%__1cKBlockBeginUresolve_substitution6M_v_; +text: .text%__1cKBlockBeginPblock_values_do6MpFppnLInstruction__v_v_; +text: .text%__1cZresolve_substituted_value6FppnLInstruction__v_: c1_Instruction.o; +text: .text%__1cLInstructionFsubst6M_p0_: c1_Instruction.o; +text: .text%__1cLInstructionPother_values_do6MpFpp0_v_v_: c1_GraphBuilder.o; +text: .text%__1cLInstructionPstate_values_do6MpFpp0_v_v_: c1_GraphBuilder.o; +text: .text%__1cLInstructionPstate_values_do6MpFpp0_v_v_: c1_Instruction.o; +text: .text%__1cIConstantPother_values_do6MpFppnLInstruction__v_v_; +text: .text%__1cIBlockEndPother_values_do6MpFppnLInstruction__v_v_; +text: .text%__1cHIntTypeEsize6kM_i_: c1_Canonicalizer.o; +text: .text%__1cJNullCheckPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorMdo_NullCheck6MpnJNullCheck__v_; +text: .text%__1cTNullCheckEliminatorQhandle_NullCheck6MpnJNullCheck__v_; +text: .text%__1cLInstructionOas_AccessLocal6M_pnLAccessLocal__: c1_GraphBuilder.o; +text: .text%__1cHIRScopeNtop_scope_bci6kM_i_; +text: .text%__1cQUseCountComputerPclear_use_count6FpnKBlockBegin__v_: c1_IR.o; +text: .text%__1cIValueGenMdo_NullCheck6MpnJNullCheck__v_; +text: .text%__1cJNullCheckKlock_stack6kM_pnKValueStack__: c1_GraphBuilder.o; +text: .text%__1cLLIR_EmitterKnull_check6MpnLLIR_OprDesc_pnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListDsub6MpnLLIR_OprDesc_22pnMCodeEmitInfo__v_: c1_LIREmitter.o; +text: .text%__1cIValueGenQlock_spill_rinfo6MpnLInstruction_nFRInfo__v_; +text: .text%__1cQIRScopeDebugInfoRrecord_debug_info6MpnYDebugInformationRecorder__v_: c1_LIREmitter.o; +text: .text%__1cIRuntime1Yresolve_opt_virtual_call6FpnKJavaThread_pnHoopDesc__pC_; +text: .text%__1cNSharedRuntimeOresolve_helper6FpnKJavaThread_iipnGThread__nMmethodHandle__; +text: .text%__1cNSharedRuntimeSresolve_sub_helper6FpnKJavaThread_iipnGThread__nMmethodHandle__; +text: .text%__1cFframeZsender_for_compiled_frame6kMpnLRegisterMap_pnICodeBlob_i_0_; +text: .text%__1cLRuntimeStubYcaller_must_gc_arguments6kMpnKJavaThread__i_: codeBlob.o; +text: .text%__1cHnmethodJis_zombie6kM_i_: nmethod.o; +text: .text%__1cNnmethodLocker2t6MpnHnmethod__v_; +text: .text%__1cNSharedRuntimeQfind_callee_info6FpnKJavaThread_rnJBytecodesECode_rnICallInfo_pnGThread__nGHandle__; +text: .text%__1cHnmethodQis_native_method6kM_i_: nmethod.o; +text: .text%__1cHnmethodKpc_desc_at6MpCi_pnGPcDesc__; +text: .text%__1cGPcDescHreal_pc6kMpknHnmethod__pC_; +text: .text%__1cLPcDescCacheKpc_desc_at6kMpnHnmethod_pCi_pnGPcDesc__; +text: .text%__1cLPcDescCacheLadd_pc_desc6MpnGPcDesc__v_; +text: .text%__1cSvframeStreamCommonYfill_from_compiled_frame6MpnHnmethod_i_v_; +text: .text%__1cUCompressedReadStreamMraw_read_int6FrpC_i_: vframe.o; +text: .text%__1cICodeBlobLoop_addr_at6kMi_ppnHoopDesc__; +text: .text%__1cNSharedRuntimeXfind_callee_info_helper6FpnKJavaThread_rnMvframeStream_rnJBytecodesECode_rnICallInfo_pnGThread__nGHandle__; +text: .text%__1cPBytecode_invokeNstatic_target6MpnGThread__nMmethodHandle__; +text: .text%__1cMLinkResolverOresolve_method6FrnMmethodHandle_rnLKlassHandle_nSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cKCompiledICZcompute_monomorphic_entry6FnMmethodHandle_nLKlassHandle_iirnOCompiledICInfo_pnGThread__v_; +text: .text%__1cKCompiledIC2t6MpnKNativeCall__v_; +text: .text%__1cXvirtual_call_RelocationIparse_ic6FrpnICodeBlob_rpC5rppnHoopDesc_pi_nNRelocIterator__; +text: .text%__1cKCompiledICIis_clean6kM_i_; +text: .text%__1cKCompiledICOic_destination6kM_pC_; +text: .text%__1cKCompiledICWis_in_transition_state6kM_i_; +text: .text%__1cRInlineCacheBufferIcontains6FpC_i_; +text: .text%__1cKCompiledICSset_to_monomorphic6MrknOCompiledICInfo__v_; +text: .text%__1cSCompiledStaticCallSset_to_interpreted6MnMmethodHandle_pC_v_; +text: .text%__1cSCompiledStaticCallJfind_stub6M_pC_; +text: .text%__1cNRelocIteratorEnext6M_i_: compiledIC.o; +text: .text%__1cPBoundRelocationLunpack_data6MnJrelocInfoJrelocType__v_: compiledIC.o; +text: .text%__1cbBopt_virtual_call_RelocationLstatic_stub6M_pC_; +text: .text%__1cKNativeCallXset_destination_mt_safe6MpC_v_; +text: .text%__1cNnmethodLocker2T6M_v_; +text: .text%__1cNmethodOopDescTverified_code_entry6M_pC_; +text: .text%jni_GetByteArrayRegion: jni.o; +text: .text%JVM_DefineClassWithSource; +text: .text%__1cXjvm_define_class_common6FpnHJNIEnv__pkcpnI_jobject_pkWi53pnGThread__pnH_jclass__: jvm.o; +text: .text%__1cQSystemDictionaryTresolve_from_stream6FnMsymbolHandle_nGHandle_2pnPClassFileStream_pnGThread__pnMklassOopDesc__; +text: .text%__1cPClassFileParserbDverify_legal_method_signature6MnMsymbolHandle_1pnGThread__i_; +text: .text%__1cPClassFileParserZskip_over_field_signature6MpciIpnGThread__1_; +text: .text%__1cPClassFileParserXverify_legal_class_name6MnMsymbolHandle_pnGThread__v_; +text: .text%__1cQput_after_lookup6FnMsymbolHandle_0ppnLNameSigHash__i_; +text: .text%__1cEhash6Fpkc1_I_; +text: .text%__1cKDictionarybAis_valid_protection_domain6MiInMsymbolHandle_nGHandle_2_i_; +text: .text%__1cPDictionaryEntrybAcontains_protection_domain6kMpnHoopDesc__i_; +text: .text%__1cQSystemDictionarybAvalidate_protection_domain6FnTinstanceKlassHandle_nGHandle_2pnGThread__v_; +text: .text%__1cKDictionaryVadd_protection_domain6MiInTinstanceKlassHandle_nGHandle_2pnGThread__v_; +text: .text%__1cPDictionaryEntryVadd_protection_domain6MpnHoopDesc__v_; +text: .text%__1cUverify_byte_codes_fn6F_pv_: verifier.o; +text: .text%JVM_GetClassCPEntriesCount; +text: .text%JVM_GetClassCPTypes; +text: .text%JVM_GetClassNameUTF; +text: .text%JVM_ReleaseUTF; +text: .text%JVM_FindClassFromClass; +text: .text%jni_IsSameObject: jni.o; +text: .text%JVM_GetClassFieldsCount; +text: .text%JVM_GetClassMethodsCount; +text: .text%JVM_GetMethodIxModifiers; +text: .text%JVM_GetMethodIxByteCodeLength; +text: .text%JVM_GetMethodIxByteCode; +text: .text%JVM_GetMethodIxExceptionTableLength; +text: .text%JVM_GetMethodIxLocalsCount; +text: .text%JVM_GetMethodIxArgsSize; +text: .text%JVM_GetMethodIxSignatureUTF; +text: .text%JVM_GetMethodIxMaxStack; +text: .text%JVM_GetMethodIxExceptionsCount; +text: .text%JVM_GetMethodIxExceptionIndexes; +text: .text%JVM_GetCPMethodNameUTF; +text: .text%JVM_GetCPMethodClassNameUTF; +text: .text%jni_NewLocalRef: jni.o; +text: .text%JVM_GetCPMethodModifiers; +text: .text%JVM_IsConstructorIx; +text: .text%JVM_GetCPMethodSignatureUTF; +text: .text%jni_DeleteGlobalRef: jni.o; +text: .text%__1cQSystemDictionaryVadd_loader_constraint6FnMsymbolHandle_nGHandle_2pnGThread__v_; +text: .text%__1cVLoaderConstraintTableJadd_entry6MnMsymbolHandle_pnMklassOopDesc_nGHandle_34pnGThread__i_; +text: .text%__1cVLoaderConstraintTableJnew_entry6MIpnNsymbolOopDesc_pnMklassOopDesc_ii_pnVLoaderConstraintEntry__; +text: .text%jni_ToReflectedMethod: jni.o; +text: .text%__1cKReflectionKnew_method6FnMmethodHandle_iipnGThread__pnHoopDesc__; +text: .text%__1cNSignatureInfoIdo_array6Mii_v_: reflection.o; +text: .text%__1cYjava_lang_reflect_MethodGcreate6FpnGThread__nGHandle__; +text: .text%__1cYjava_lang_reflect_MethodJset_clazz6FpnHoopDesc_2_v_; +text: .text%__1cYjava_lang_reflect_MethodIset_slot6FpnHoopDesc_i_v_; +text: .text%__1cYjava_lang_reflect_MethodIset_name6FpnHoopDesc_2_v_; +text: .text%__1cYjava_lang_reflect_MethodPset_return_type6FpnHoopDesc_2_v_; +text: .text%__1cYjava_lang_reflect_MethodTset_parameter_types6FpnHoopDesc_2_v_; +text: .text%__1cYjava_lang_reflect_MethodTset_exception_types6FpnHoopDesc_2_v_; +text: .text%__1cYjava_lang_reflect_MethodNset_modifiers6FpnHoopDesc_i_v_; +text: .text%__1cYjava_lang_reflect_MethodThas_signature_field6F_i_; +text: .text%__1cYjava_lang_reflect_MethodVhas_annotations_field6F_i_; +text: .text%__1cYjava_lang_reflect_MethodPset_annotations6FpnHoopDesc_2_v_; +text: .text%__1cYjava_lang_reflect_MethodbFhas_parameter_annotations_field6F_i_; +text: .text%__1cYjava_lang_reflect_MethodZset_parameter_annotations6FpnHoopDesc_2_v_; +text: .text%__1cYjava_lang_reflect_MethodbChas_annotation_default_field6F_i_; +text: .text%__1cNmethodOopDescSannotation_default6kM_pnQtypeArrayOopDesc__; +text: .text%__1cYjava_lang_reflect_MethodWset_annotation_default6FpnHoopDesc_2_v_; +text: .text%jni_CallIntMethod: jni.o; +text: .text%jni_CallStaticVoidMethod: jni.o; +text: .text%jni_DetachCurrentThread; +text: .text%__1cKJavaThreadEexit6Mi_v_; +text: .text%__1cQjava_lang_ThreadLthreadGroup6FpnHoopDesc__2_; +text: .text%JVM_MonitorNotifyAll; +text: .text%__1cNThreadServiceWcurrent_thread_exiting6FpnKJavaThread__v_; +text: .text%__1cLensure_join6FpnKJavaThread__v_: thread.o; +text: .text%__1cQjava_lang_ThreadNset_stillborn6FpnHoopDesc__v_; +text: .text%__1cKJavaThreadYremove_stack_guard_pages6M_v_; +text: .text%__1cWThreadLocalAllocBufferFclear6M_v_; +text: .text%__1cHThreadsGremove6FpnKJavaThread__v_; +text: .text%__1cNThreadServiceNremove_thread6FpnKJavaThread_i_v_; +text: .text%__SLIP.DELETER__A: thread.o; +text: .text%__1cKJavaThread2T6M_v_; +text: .text%__1cGParker2T6M_v_; +text: .text%__1cHMonitor2T6M_v_; +text: .text%__1cFMutex2T6M_v_; +text: .text%lwp_cond_destroy: os_solaris.o; +text: .text%lwp_mutex_destroy: os_solaris.o; +text: .text%__1cUThreadSafepointStateHdestroy6FpnKJavaThread__v_; +text: .text%__1cUThreadSafepointState2T6M_v_; +text: .text%__1cGThread2T5B6M_v_; +text: .text%__1cCosLfree_thread6FpnIOSThread__v_; +text: .text%__1cIOSThread2T6M_v_; +text: .text%__1cIOSThreadKpd_destroy6M_v_; +text: .text%jni_DestroyJavaVM; +text: .text%jni_AttachCurrentThread; +text: .text%attach_current_thread: jni.o; +text: .text%__1cCosWcreate_attached_thread6FpnGThread__i_; +text: .text%__1cKJavaThreadSallocate_threadObj6MnGHandle_pcipnGThread__v_; +text: .text%__1cHThreadsKdestroy_vm6F_i_; +text: .text%__1cKJavaThreadVinvoke_shutdown_hooks6M_v_; +text: .text%__1cLbefore_exit6FpnKJavaThread__v_; +text: .text%__1cNWatcherThreadEstop6F_v_; +text: .text%__1cLStatSamplerJdisengage6F_v_; +text: .text%__1cMPeriodicTaskJdisenroll6M_v_; +text: .text%__1cMPeriodicTask2T5B6M_v_; +text: .text%__1cMPeriodicTaskLis_enrolled6kM_i_; +text: .text%__1cLStatSamplerHdestroy6F_v_; +text: .text%__1cMPerfDataList2T6M_v_; +text: .text%__1cLJvmtiExportNpost_vm_death6F_v_; +text: .text%__1cUJvmtiEventControllerIvm_death6F_v_; +text: .text%__1cCosXterminate_signal_thread6F_v_; +text: .text%__1cCosNsigexitnum_pd6F_i_; +text: .text%__1cCosNsignal_notify6Fi_v_; +text: .text%__1cQprint_statistics6F_v_; +text: .text%__1cFVTuneEexit6F_v_; +text: .text%__1cIVMThreadXwait_for_vm_thread_exit6F_v_; +text: .text%__1cUSafepointSynchronizeFbegin6F_v_; +text: .text%__1cORuntimeServiceWrecord_safepoint_begin6F_v_; +text: .text%__1cJTimeStampSticks_since_update6kM_x_; +text: .text%__1cTAbstractInterpreterRnotice_safepoints6F_v_; +text: .text%__1cKcopy_table6FppC1i_v_: interpreter.o; +text: .text%__1cUSafepointSynchronizeFblock6FpnKJavaThread__v_; +text: .text%__1cCosRcurrent_thread_id6F_i_; +text: .text%__1cJttyLockerbCbreak_tty_lock_for_safepoint6Fi_v_; +text: .text%__1cCosbCmake_polling_page_unreadable6F_v_; +text: .text%__1cUThreadSafepointStateXexamine_state_of_thread6Mi_v_; +text: .text%__1cUSafepointSynchronizeOsafepoint_safe6FpnKJavaThread_nPJavaThreadState__i_; +text: .text%__1cUThreadSafepointStateMroll_forward6Mn0AMsuspend_type_pnHnmethod_i_v_; +text: .text%__1cORuntimeServicebDrecord_safepoint_synchronized6F_v_; +text: .text%__1cUSafepointSynchronizeQdo_cleanup_tasks6F_v_; +text: .text%__1cSObjectSynchronizerVdeflate_idle_monitors6F_v_; +text: .text%__1cNObjectMonitorHis_busy6kM_i_; +text: .text%__1cRInlineCacheBufferUupdate_inline_caches6F_v_; +text: .text%__1cMCounterDecayFdecay6F_v_; +text: .text%__1cQSystemDictionaryRnumber_of_classes6F_i_; +text: .text%__1cQSystemDictionaryStry_get_next_class6F_pnMklassOopDesc__; +text: .text%__1cKDictionaryStry_get_next_class6M_pnMklassOopDesc__; +text: .text%__1cNinstanceKlassKmethods_do6MpFpnNmethodOopDesc__v_v_; +text: .text%__1cJdo_method6FpnNmethodOopDesc__v_: recompilationMonitor.o; +text: .text%__1cONMethodSweeperFsweep6F_v_; +text: .text%__1cNCompileBrokerQset_should_block6F_v_; +text: .text%__1cHVM_ExitbJwait_for_threads_in_native_to_block6F_i_; +text: .text%__1cURecompilationMonitorbFstop_recompilation_monitor_task6F_v_; +text: .text%__1cIVMThreadHdestroy6F_v_; +text: .text%__SLIP.DELETER__A: vmThread.o; +text: .text%__1cSThreadLocalStorageRpd_invalidate_all6F_v_; +text: .text%__1cHVM_ExitNset_vm_exited6F_i_; +text: .text%__1cMexit_globals6F_v_; +text: .text%__1cVverificationType_exit6F_v_; +text: .text%__1cQVerificationTypeIfinalize6F_v_; +text: .text%__1cPperfMemory_exit6F_v_; +text: .text%__1cPPerfDataManagerHdestroy6F_v_; +text: .text%__1cIPerfData2T6M_v_; +text: .text%__1cKPerfMemoryHdestroy6F_v_; +text: .text%__1cKPerfMemoryUdelete_memory_region6F_v_; +text: .text%__1cUdelete_shared_memory6FpcI_v_: perfMemory_solaris.o; +text: .text%__1cLremove_file6Fpkc_v_: perfMemory_solaris.o; +text: .text%__1cMostream_exit6F_v_; +text: .text%__SLIP.DELETER__C: ostream.o; +text: .text%__SLIP.FINAL__A: c1_Items.o; +# Test Exit +text: .text%__1cPSignatureStreamHis_done6kM_i_; +text: .text%JVM_Halt; +text: .text%__1cHvm_exit6Fi_v_; +text: .text%__1cIVMThreadHexecute6FpnMVM_Operation__v_; +text: .text%__1cMVM_OperationNdoit_prologue6M_i_: vm_operations.o; +text: .text%__1cGThreadMget_priority6Fkpk0_nOThreadPriority__; +text: .text%__1cCosMget_priority6FkpknGThread_rnOThreadPriority__nIOSReturn__; +text: .text%__1cCosTget_native_priority6FkpknGThread_pi_nIOSReturn__; +text: .text%__1cMVM_OperationSset_calling_thread6MpnGThread_nOThreadPriority__v_; +text: .text%__1cMVM_OperationPevaluation_mode6kM_n0AEMode__: vm_operations.o; +text: .text%__1cMVM_OperationSis_cheap_allocated6kM_i_: vm_operations.o; +text: .text%__1cQVMOperationQdDueueDadd6MpnMVM_Operation__i_; +text: .text%__1cQVMOperationQdDueueOqueue_add_back6MipnMVM_Operation__v_; +text: .text%__1cQVMOperationQdDueueGinsert6MpnMVM_Operation_2_v_; +text: .text%__1cQVMOperationQdDueueGunlink6MpnMVM_Operation__v_; +text: .text%__1cHVM_ExitEname6kM_pkc_: vm_operations.o; +text: .text%__1cJEventMark2t6MpkcE_v_: vmThread.o; +text: .text%__1cCosJyield_all6Fi_v_; +text: .text%__1cGThreadRis_Watcher_thread6kM_i_: vmThread.o; +text: .text%__1cSInterpreterRuntimeMat_safepoint6FpnKJavaThread__v_; +text: .text%__1cIVMThreadSevaluate_operation6MpnMVM_Operation__v_; +text: .text%__1cMVM_OperationIevaluate6M_v_; +text: .text%__1cHVM_ExitEdoit6M_v_; +# Test Hello +text: .text%JVM_GetCPFieldSignatureUTF; +text: .text%JVM_Write; +text: .text%__1cDhpiFwrite6FipkvI_I_: jvm.o; +# Test Sleep +text: .text%JVM_GetMethodIxExceptionTableEntry; +text: .text%JVM_GetCPClassNameUTF; +text: .text%JVM_Sleep; +text: .text%__1cCosHSolarisTsetup_interruptible6F_pnKJavaThread__; +text: .text%__1cCosHSolarisTsetup_interruptible6FpnKJavaThread__v_; +text: .text%__1cUSafepointSynchronizeRis_cleanup_needed6F_i_; +text: .text%__1cRInlineCacheBufferIis_empty6F_i_; +text: .text%__1cCosHSolarisVcleanup_interruptible6FpnKJavaThread__v_; +text: .text%__1cCosOunguard_memory6FpcI_i_; +# Test IntToString +text: .text%__1cQChunkPoolCleanerEtask6M_v_: allocation.o; +text: .text%__1cJChunkPoolMfree_all_but6MI_v_: allocation.o; +# Test LoadToolkit +text: .text%JVM_GetClassContext; +text: .text%__1cNCollectedHeapMobj_allocate6FnLKlassHandle_ipnGThread__pnHoopDesc__: jvm.o; +text: .text%jni_IsAssignableFrom: jni.o; +text: .text%__1cOGenerateOopMapGdo_ldc6Mii_v_; +text: .text%__1cQComputeCallStackIdo_array6Mii_v_: generateOopMap.o; +text: .text%__1cMGraphBuilderNload_constant6M_v_; +text: .text%__1cQciBytecodeStreamMget_constant6kM_nKciConstant__; +text: .text%__1cQciBytecodeStreamSget_constant_index6kM_i_; +text: .text%__1cFciEnvVget_constant_by_index6MpnPciInstanceKlass_i_nKciConstant__; +text: .text%__1cFciEnvbAget_constant_by_index_impl6MpnPciInstanceKlass_i_nKciConstant__; +text: .text%__1cMLinkResolverbBresolve_static_call_or_null6FnLKlassHandle_nMsymbolHandle_21_nMmethodHandle__; +text: .text%__1cLInstructionMas_LoadLocal6M_pnJLoadLocal__: c1_Canonicalizer.o; +text: .text%__1cTsort_by_start_block6FppnELoop_2_i_: c1_Loops.o; +text: .text%__1cILIR_ListLcall_static6MpnLLIR_OprDesc_pCpnMCodeEmitInfo_pnOStaticCallStub__v_: c1_LIREmitter.o; +text: .text%__1cLLIR_EmitterLcmp_mem_int6MnMLIR_OpBranchNLIR_Condition_nFRInfo_iipnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListLcmp_mem_int6MnMLIR_OpBranchNLIR_Condition_nFRInfo_iipnMCodeEmitInfo__v_; +text: .text%__1cJValueTypeLas_VoidType6M_pnIVoidType__: c1_Canonicalizer.o; +text: .text%__1cILIR_ListHint2reg6MinFRInfo__v_: c1_LIREmitter.o; +text: .text%__1cWstatic_call_RelocationEtype6M_nJrelocInfoJrelocType__: relocInfo.o; +text: .text%__1cRComputeEntryStackIdo_array6Mii_v_: generateOopMap.o; +text: .text%__1cKValueStackEpush6MpnJValueType_pnLInstruction__v_: c1_Optimizer.o; +text: .text%__1cEIfOpPinput_values_do6MpFppnLInstruction__v_v_: c1_Instruction.o; +text: .text%__1cEIfOpFvisit6MpnSInstructionVisitor__v_: c1_Instruction.o; +text: .text%__1cQNullCheckVisitorHdo_IfOp6MpnEIfOp__v_; +text: .text%__1cIValueGenHdo_IfOp6MpnEIfOp__v_; +text: .text%__1cLLIR_EmitterLifop_phase16MnLInstructionJCondition_pnLLIR_OprDesc_4_v_; +text: .text%__1cLLIR_EmitterLifop_phase26MnFRInfo_pnLLIR_OprDesc_3nLInstructionJCondition__v_; +text: .text%__1cILIR_ListGbranch6MnMLIR_OpBranchNLIR_Condition_pnFLabel__v_; +text: .text%__1cRLIR_PeepholeStateUstart_forward_branch6MpnFLabel__v_; +text: .text%__1cOGenerateOopMapMdo_checkcast6M_v_; +text: .text%__1cMGraphBuilderLinstance_of6Mi_v_; +text: .text%__1cKInstanceOfFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerNdo_InstanceOf6MpnKInstanceOf__v_; +text: .text%__1cJTypeCheckIcan_trap6kM_i_: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderOdirect_compare6MpnHciKlass__i_; +text: .text%__1cKInstanceOfNas_InstanceOf6M_p0_: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderKcheck_cast6Mi_v_; +text: .text%__1cJCheckCastFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerMdo_CheckCast6MpnJCheckCast__v_; +text: .text%__1cJValueTypeKas_IntType6M_pnHIntType__: c1_ValueType.o; +text: .text%__1cJTypeCheckPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorNdo_InstanceOf6MpnKInstanceOf__v_; +text: .text%__1cQNullCheckVisitorMdo_CheckCast6MpnJCheckCast__v_; +text: .text%__1cIValueGenNdo_InstanceOf6MpnKInstanceOf__v_; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_CodeGenerator_x86.o; +text: .text%__1cLLIR_EmitterNinstanceof_op6MpnLLIR_OprDesc_2pnHciKlass_nFRInfo_5ipnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListKinstanceof6MpnLLIR_OprDesc_2pnHciKlass_22ipnMCodeEmitInfo__v_; +text: .text%__1cPLIR_OpTypeCheck2t6MnILIR_Code_pnLLIR_OprDesc_3pnHciKlass_33ipnMCodeEmitInfo_7pnICodeStub__v_; +text: .text%__1cIValueGenMdo_CheckCast6MpnJCheckCast__v_; +text: .text%__1cILIR_ListJcheckcast6MpnLLIR_OprDesc_2pnHciKlass_22ipnMCodeEmitInfo_6pnICodeStub__v_; +text: .text%__1cILIR_ListJsafepoint6MnFRInfo_pnMCodeEmitInfo__v_: c1_CodeGenerator_x86.o; +text: .text%__1cPLIR_OpTypeCheckFvisit6MpnQLIR_OpVisitState__v_; +text: .text%__1cTSimpleExceptionStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; +text: .text%__1cPLIR_OpTypeCheckJemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerQemit_opTypeCheck6MpnPLIR_OpTypeCheck__v_; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_LIROptimizer.o; +text: .text%__1cIintArrayIindex_of6kMki_i_: c1_LIROptimizer.o; +text: .text%__1cNLIR_AssemblerQemit_opTypeCheck6MpnPLIR_OpTypeCheck__v_; +text: .text%__1cIciObjectIencoding6M_pnI_jobject__; +text: .text%__1cJAssemblerEcmpl6MnHAddress_pnI_jobject__v_; +text: .text%__1cTSimpleExceptionStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; +text: .text%__1cTSimpleExceptionStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%__1cJLoadFieldIis_equal6kMpnLInstruction__i_: c1_Instruction.o; +text: .text%__1cJLoadFieldMas_LoadField6M_p0_: c1_Instruction.o; +text: .text%__1cDPhiPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cDPhiFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorGdo_Phi6MpnDPhi__v_; +text: .text%__1cLInstructionIas_Local6M_pnFLocal__: c1_GraphBuilder.o; +text: .text%__1cDPhiGas_Phi6M_p0_: c1_GraphBuilder.o; +text: .text%__1cIValueGenScompute_phi_arrays6MpnKValueStack_pnGValues_pnIintStack_i_pnLInstruction__; +text: .text%__1cLLIR_EmitterTset_fpu_stack_empty6M_v_; +text: .text%__1cIRegAllocKlock_spill6MpnLInstruction_ii_v_; +text: .text%__1cIRegAllocRextend_spill_area6Mi_v_; +text: .text%__1cRclear_state_items6FppnLInstruction__v_: c1_CodeGenerator.o; +text: .text%__1cNLIR_AssemblerTset_fpu_stack_empty6M_v_; +text: .text%__1cIFrameMapLFpuStackSimFclear6M_v_; +text: .text%jni_GetEnv; +text: .text%jni_CallStaticBooleanMethod: jni.o; +text: .text%__1cOtypeArrayKlassQarray_klass_impl6MipnGThread__pnMklassOopDesc__; +text: .text%__1cOtypeArrayKlassKinitialize6MpnGThread__v_; +text: .text%__1cVcreate_gc_point_array6FpnFArena_i_pnNGrowableArray4Ci___; +text: .text%__1cOGenerateOopMapRdo_exception_edge6MpnOBytecodeStream__v_; +text: .text%__1cOGenerateOopMapIppop_any6Mi_v_; +text: .text%__1cYciExceptionHandlerStreamEnext6M_v_: c1_IR.o; +text: .text%__1cMGraphBuilderQhandle_exception6Mi_v_; +text: .text%__1cOExceptionScopeFclear6M_v_; +text: .text%__1cMGraphBuilderJScopeDataJxhandlers6kM_pnJXHandlers__; +text: .text%__1cTciConstantPoolCache2t6MpnFArena_i_v_; +text: .text%__1cTciConstantPoolCacheDget6Mi_pv_; +text: .text%__1cTciConstantPoolCacheEfind6Mi_i_; +text: .text%__1cTciConstantPoolCacheGinsert6Mipv_v_; +text: .text%__1cMGraphBuilderHif_null6MpnJValueType_nLInstructionJCondition__v_; +text: .text%__1cOObjectConstantRas_ObjectConstant6M_p0_: c1_ValueType.o; +text: .text%__1cMas_ValueType6FnKciConstant__pnJValueType__; +text: .text%__1cLInstructionGmirror6Fn0AJCondition__1_; +text: .text%__1cHis_true6FxnLInstructionJCondition_x_i_: c1_Canonicalizer.o; +text: .text%__1cNCanonicalizerNset_canonical6MpnLInstruction__v_; +text: .text%__1cKBlockBeginVadd_exception_handler6Mp0_v_; +text: .text%__1cPBlockBeginArrayIindex_of6kMkpnKBlockBegin__i_: c1_Instruction.o; +text: .text%__1cOExceptionScopeLadd_handler6MpnIXHandler__v_; +text: .text%__1cIciObjectEhash6M_i_; +text: .text%__1cPciObjectFactoryPinsert_non_perm6Mrpn0ANNonPermObject_pnHoopDesc_pnIciObject__v_; +text: .text%__1cIciObjectMhas_encoding6M_i_; +text: .text%__1cJValueTypeRas_ObjectConstant6M_pnOObjectConstant__: c1_ValueType.o; +text: .text%__1cNClassConstantQas_ClassConstant6M_p0_: c1_ValueType.o; +text: .text%__1cOExceptionScopeKhandler_at6kMi_pnIXHandler__; +text: .text%__1cLInstructionMas_LoadLocal6M_pnJLoadLocal__: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderIlogic_op6MpnJValueType_nJBytecodesECode__v_; +text: .text%__1cHLogicOpFvisit6MpnSInstructionVisitor__v_: c1_Instruction.o; +text: .text%__1cNCanonicalizerKdo_LogicOp6MpnHLogicOp__v_; +text: .text%__1cHLogicOpEhash6kM_i_: c1_Instruction.o; +text: .text%__1cHLogicOpEname6kM_pkc_: c1_Instruction.o; +text: .text%__1cLInstructionIcan_trap6kM_i_: c1_Instruction.o; +text: .text%__1cMGraphBuilderHconvert6MnJBytecodesECode_nJBasicType_3_v_; +text: .text%__1cHConvertFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerKdo_Convert6MpnHConvert__v_; +text: .text%__1cHConvertEhash6kM_i_: c1_GraphBuilder.o; +text: .text%__1cHConvertEname6kM_pkc_: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderNstore_indexed6MnJBasicType__v_; +text: .text%__1cIValueMapKkill_array6MpnJValueType__v_; +text: .text%__1cGBucketKkill_array6MpnJValueType__v_; +text: .text%__1cLInstructionOas_LoadIndexed6M_pnLLoadIndexed__: c1_GraphBuilder.o; +text: .text%__1cLInstructionOas_LoadIndexed6M_pnLLoadIndexed__: c1_Instruction.o; +text: .text%__1cKValueStackRpin_stack_indexed6MpnJValueType__v_; +text: .text%__1cMStoreIndexedFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerPdo_StoreIndexed6MpnMStoreIndexed__v_; +text: .text%__1cLAccessArrayIcan_trap6kM_i_: c1_GraphBuilder.o; +text: .text%__1cLAccessFieldPother_values_do6MpFppnLInstruction__v_v_; +text: .text%__1cLInstructionPother_values_do6MpFpp0_v_v_: c1_Instruction.o; +text: .text%__1cIciObjectOis_null_object6kM_i_: ciInstance.o; +text: .text%__1cMStoreIndexedPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cHConvertPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorKdo_LogicOp6MpnHLogicOp__v_; +text: .text%__1cQNullCheckVisitorKdo_Convert6MpnHConvert__v_; +text: .text%__1cQNullCheckVisitorPdo_StoreIndexed6MpnMStoreIndexed__v_; +text: .text%__1cTNullCheckEliminatorThandle_StoreIndexed6MpnMStoreIndexed__v_; +text: .text%__1cMciNullObjectMis_classless6kM_i_: ciNullObject.o; +text: .text%__1cJValueTypeQas_ClassConstant6M_pnNClassConstant__: c1_ValueType.o; +text: .text%__1cOObjectConstantIencoding6kM_pnI_jobject__; +text: .text%__1cIValueGenbBrlock_byte_result_with_hint6MpnLInstruction_pknEItem__nFRInfo__; +text: .text%__1cNc1_AllocTableThas_one_free_masked6kMnKc1_RegMask__i_; +text: .text%__1cIRegAllocMget_lock_reg6MpnLInstruction_nKc1_RegMask__nFRInfo__; +text: .text%__1cIRegAllocMget_free_reg6MnKc1_RegMask__nFRInfo__; +text: .text%__1cNc1_AllocTablePget_free_masked6MnKc1_RegMask__i_; +text: .text%__1cNClassConstantIencoding6kM_pnI_jobject__; +text: .text%__1cLLIR_EmitterLopr2jobject6MpnLLIR_OprDesc__pnI_jobject__; +text: .text%__1cILIR_ListHoop2reg6MpnI_jobject_nFRInfo__v_: c1_LIREmitter.o; +text: .text%__1cIValueGenMrelease_item6MpnEItem__v_; +text: .text%__1cIValueGenPdo_StoreIndexed6MpnMStoreIndexed__v_; +text: .text%__1cIValueGenKdo_Convert6MpnHConvert__v_; +text: .text%__1cIValueGenKdo_LogicOp6MpnHLogicOp__v_; +text: .text%__1cLLIR_EmitterIlogic_op6MnJBytecodesECode_nFRInfo_pnLLIR_OprDesc_5_v_; +text: .text%__1cILIR_ListLlogical_and6MnFRInfo_pnLLIR_OprDesc_1_v_: c1_LIREmitter.o; +text: .text%__1cLLIR_EmitterKconvert_op6MnJBytecodesECode_pnLLIR_OprDesc_nFRInfo_i_v_; +text: .text%__1cILIR_ListHconvert6MnJBytecodesECode_pnLLIR_OprDesc_4i_v_: c1_LIREmitter.o; +text: .text%__1cIValueGenKmust_round6MpnLInstruction_pknEItem__i_; +text: .text%__1cLAccessArrayKlock_stack6kM_pnKValueStack__: c1_GraphBuilder.o; +text: .text%__1cLLIR_EmitterNindexed_store6MnJBasicType_pnLLIR_OprDesc_33nFRInfo_pnMCodeEmitInfo__v_; +text: .text%__1cLLIR_EmitterXlo_word_offset_in_bytes6kM_i_; +text: .text%__1cLLIR_EmitterXhi_word_offset_in_bytes6kM_i_; +text: .text%__1cILIR_ListLstore_array6MnFRInfo_pnLLIR_Address_nJBasicType_pnMCodeEmitInfo__v_; +text: .text%__1cIValueGenXexception_handler_start6MpnHIRScope_ipnKValueStack__v_; +text: .text%__1cLLIR_EmitterNhandler_entry6M_v_; +text: .text%__1cLLIR_OprFactQdummy_value_type6FpnJValueType__pnLLIR_OprDesc__; +text: .text%__1cLInstructionKexact_type6kM_pnGciType__: c1_GraphBuilder.o; +text: .text%__1cLInstructionNdeclared_type6kM_pnGciType__: c1_GraphBuilder.o; +text: .text%__1cILIR_ListKnull_check6MnFRInfo_pnMCodeEmitInfo__v_: c1_CodeGenerator.o; +text: .text%__1cNLIR_OpConvertJemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerOemit_opConvert6MpnNLIR_OpConvert__v_; +text: .text%__1cJAssemblerEcmpl6MpnMRegisterImpl_pnI_jobject__v_; +text: .text%__1cJAssemblerKemit_arith6MiipnMRegisterImpl_pnI_jobject__v_; +text: .text%__1cNLIR_AssemblerIlogic_op6MnILIR_Code_pnLLIR_OprDesc_33_v_; +text: .text%__1cNLIR_AssemblerOemit_opConvert6MpnNLIR_OpConvert__v_; +text: .text%__1cNLIR_AssemblerNarray_move_op6MpnLLIR_OprDesc_2nJBasicType_pnMCodeEmitInfo__v_; +text: .text%__1cNLIR_AssemblerJreg2array6MnFRInfo_pnLLIR_Address_nJBasicType_pnMCodeEmitInfo__v_; +text: .text%__1cNLIR_AssemblerPas_ArrayAddress6MpnLLIR_Address_nJBasicType__nHAddress__; +text: .text%__1cVConstantOopWriteValueIwrite_on6MpnUDebugInfoWriteStream__v_; +text: .text%__1cUDebugInfoWriteStreamMwrite_handle6MpnI_jobject__v_; +text: .text%__1cTExceptionRangeTableJadd_entry6Miiiiii_v_; +text: .text%__1cTExceptionRangeEntry2t6Miiiiii_v_; +text: .text%__1cTExceptionRangeTableJadd_entry6MnTExceptionRangeEntry__v_; +text: .text%__1cOExceptionScopeCid6kM_i_; +text: .text%__1cTExceptionRangeTableTentry_index_for_pco6kMi_i_; +text: .text%__1cTExceptionRangeTableIentry_at6kMi_pnTExceptionRangeEntry__; +text: .text%jni_CallStaticVoidMethodV: jni.o; +text: .text%JVM_GetLastErrorString; +text: .text%jni_Throw: jni.o; +text: .text%__1cKExceptionsK_throw_oop6FpnGThread_pkcipnHoopDesc__v_; +text: .text%JVM_DisableCompiler; +text: .text%__1cNinstanceKlassbFlookup_method_in_all_interfaces6kMpnNsymbolOopDesc_2_pnNmethodOopDesc__; +text: .text%JVM_Available; +text: .text%__1cOGenerateOopMapKpp_new_ref6MpnNCellTypeState_i_v_; +text: .text%__1cLInstructionMas_LoadField6M_pnJLoadField__: c1_Instruction.o; +text: .text%__1cHLogicOpOis_commutative6kM_i_; +text: .text%__1cDCHANprocess_class6FnLKlassHandle_pnNGrowableArray4n0B___pnNGrowableArray4nMmethodHandle___nMsymbolHandle_6_v_; +text: .text%__1cUGenericGrowableArrayMraw_contains6kMpknEGrET__i_; +text: .text%__1cLArrayLengthFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerOdo_ArrayLength6MpnLArrayLength__v_; +text: .text%__1cLArrayLengthEhash6kM_i_: c1_GraphBuilder.o; +text: .text%__1cLArrayLengthEname6kM_pkc_: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderOnew_type_array6M_v_; +text: .text%__1cMNewTypeArrayFvisit6MpnSInstructionVisitor__v_: c1_Instruction.o; +text: .text%__1cNCanonicalizerPdo_NewTypeArray6MpnMNewTypeArray__v_; +text: .text%__1cINewArrayIcan_trap6kM_i_: c1_Instruction.o; +text: .text%__1cJIntrinsicFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerMdo_Intrinsic6MpnJIntrinsic__v_; +text: .text%__1cJIntrinsicMas_Intrinsic6M_p0_: c1_GraphBuilder.o; +text: .text%__1cJIntrinsicIcan_trap6kM_i_: c1_GraphBuilder.o; +text: .text%__1cLAccessArrayPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorOdo_ArrayLength6MpnLArrayLength__v_; +text: .text%__1cTNullCheckEliminatorShandle_ArrayLength6MpnLArrayLength__v_; +text: .text%__1cINewArrayPinput_values_do6MpFppnLInstruction__v_v_: c1_Instruction.o; +text: .text%__1cQNullCheckVisitorPdo_NewTypeArray6MpnMNewTypeArray__v_; +text: .text%__1cTNullCheckEliminatorPhandle_NewArray6MpnINewArray__v_; +text: .text%__1cJIntrinsicPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorMdo_Intrinsic6MpnJIntrinsic__v_; +text: .text%__1cJLoopArrayIindex_of6kMkpnELoop__i_: c1_Loops.o; +text: .text%__1cINewArrayLas_NewArray6M_p0_: c1_Instruction.o; +text: .text%__1cILIR_ListOcall_icvirtual6MnFRInfo_pnLLIR_OprDesc_pCpnMCodeEmitInfo__v_: c1_LIREmitter.o; +text: .text%__1cILIR_ListNstore_mem_int6MinFRInfo_inJBasicType_pnMCodeEmitInfo_nHLIR_Op1NLIR_PatchCode__v_; +text: .text%__1cIValueGenOdo_ArrayLength6MpnLArrayLength__v_; +text: .text%__1cLLIR_EmitterMarray_length6MnFRInfo_pnLLIR_OprDesc_pnMCodeEmitInfo__v_; +text: .text%__1cLlog2_intptr6Fi_i_: c1_LIREmitter.o; +text: .text%__1cIValueGenPdo_NewTypeArray6MpnMNewTypeArray__v_; +text: .text%__1cLLIR_EmitterOnew_type_array6MnFRInfo_nJBasicType_pnLLIR_OprDesc_11111pnMCodeEmitInfo__v_; +text: .text%__1cQNewTypeArrayStub2t6MnFRInfo_11pnMCodeEmitInfo__v_; +text: .text%__1cQciTypeArrayKlassEmake6FnJBasicType__p0_; +text: .text%__1cQciTypeArrayKlassJmake_impl6FnJBasicType__p0_; +text: .text%__1cILIR_ListHoop2reg6MpnI_jobject_nFRInfo__v_: c1_LIREmitter_x86.o; +text: .text%__1cILIR_ListOallocate_array6MnFRInfo_11111nJBasicType_1pnICodeStub__v_; +text: .text%__1cIValueGenMdo_Intrinsic6MpnJIntrinsic__v_; +text: .text%__1cIValueGenMdo_ArrayCopy6MpnJIntrinsic__v_; +text: .text%__1cIValueGenQarraycopy_helper6MpnJIntrinsic_pippnMciArrayKlass__v_; +text: .text%__1cJLoadFieldKexact_type6kM_pnGciType__; +text: .text%__1cJLoadFieldNdeclared_type6kM_pnGciType__; +text: .text%__1cQciTypeArrayKlassTis_type_array_klass6M_i_: ciTypeArrayKlass.o; +text: .text%__1cOas_array_klass6FpnGciType__pnMciArrayKlass__: c1_CodeGenerator.o; +text: .text%__1cMciArrayKlassOis_array_klass6M_i_: ciTypeArrayKlass.o; +text: .text%__1cMNewTypeArrayKexact_type6kM_pnGciType__; +text: .text%__1cLInstructionNdeclared_type6kM_pnGciType__: c1_Instruction.o; +text: .text%__1cRpositive_constant6FpnLInstruction__i_: c1_CodeGenerator.o; +text: .text%__1cLArrayLengthOas_ArrayLength6M_p0_: c1_GraphBuilder.o; +text: .text%__1cQis_constant_zero6FpnLInstruction__i_: c1_CodeGenerator.o; +text: .text%__1cILIR_ListJarraycopy6MpnLLIR_OprDesc_22222pnMciArrayKlass_ipnMCodeEmitInfo__v_: c1_CodeGenerator_x86.o; +text: .text%__1cLLIR_EmitterNwrite_barrier6MpnLLIR_OprDesc_2_v_; +text: .text%__1cILIR_ListUunsigned_shift_right6MnFRInfo_i1_v_: c1_LIREmitter_x86.o; +text: .text%__1cILIR_ListUunsigned_shift_right6MpnLLIR_OprDesc_222_v_; +text: .text%__1cQLIR_OpAllocArrayFvisit6MpnQLIR_OpVisitState__v_; +text: .text%__1cQNewTypeArrayStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; +text: .text%__1cPLIR_OpArrayCopyFvisit6MpnQLIR_OpVisitState__v_; +text: .text%__1cQLIR_OpAllocArrayJemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerQemit_alloc_array6MpnQLIR_OpAllocArray__v_; +text: .text%__1cPLIR_OpArrayCopyJemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerOemit_arraycopy6MpnPLIR_OpArrayCopy__v_; +text: .text%__1cNLIR_AssemblerHic_call6MpCpnMCodeEmitInfo__v_; +text: .text%__1cJAssemblerEcall6MpCrknQRelocationHolder__v_; +text: .text%__1cXvirtual_call_RelocationEtype6M_nJrelocInfoJrelocType__: relocInfo.o; +text: .text%__1cXvirtual_call_RelocationJpack_data6M_i_; +text: .text%__1cNLIR_AssemblerJconst2mem6MpnJLIR_Const_pnLLIR_Address_nJBasicType_pnMCodeEmitInfo__v_; +text: .text%__1cNLIR_AssemblerQemit_alloc_array6MpnQLIR_OpAllocArray__v_; +text: .text%__1cNLIR_AssemblerSarray_element_size6kMnJBasicType__nHAddressLScaleFactor__; +text: .text%__1cRC1_MacroAssemblerOallocate_array6MpnMRegisterImpl_222inHAddressLScaleFactor_2rnFLabel__v_; +text: .text%__1cRC1_MacroAssemblerMtry_allocate6MpnMRegisterImpl_2i22rnFLabel__v_; +text: .text%__1cQNewTypeArrayStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; +text: .text%__1cNLIR_AssemblerOemit_arraycopy6MpnPLIR_OpArrayCopy__v_; +text: .text%__1cMciArrayKlassMelement_type6M_pnGciType__; +text: .text%__1cNArrayCopyStub2t6MpnMCodeEmitInfo_pnOStaticCallStub__v_; +text: .text%__1cFRInfoMset_word_reg6MkpnMRegisterImpl__v_; +text: .text%__1cNArrayCopyStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; +text: .text%__1cNLIR_AssemblerOpush_parameter6MpnMRegisterImpl_i_v_; +text: .text%__1cQNewTypeArrayStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%__1cNArrayCopyStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%__1cXvirtual_call_RelocationLunpack_data6M_v_; +text: .text%__1cIRuntime1Uresolve_virtual_call6FpnKJavaThread_pnHoopDesc__pC_; +text: .text%__1cKoopFactoryUnew_compiledICHolder6FnMmethodHandle_nLKlassHandle_pnGThread__pnXcompiledICHolderOopDesc__; +text: .text%__1cVcompiledICHolderKlassIallocate6MpnGThread__pnXcompiledICHolderOopDesc__; +text: .text%__1cNCollectedHeapWpermanent_obj_allocate6FnLKlassHandle_ipnGThread__pnHoopDesc__: compiledICHolderKlass.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: compiledICHolderKlass.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: compiledICHolderKlass.o; +text: .text%__1cXvirtual_call_RelocationJfirst_oop6M_pC_; +text: .text%__1cXvirtual_call_RelocationJoop_limit6M_pC_; +text: .text%__1cNRelocIteratorJset_limit6MpC_v_; +text: .text%__1cRInlineCacheBufferWcreate_transition_stub6FpnKCompiledIC_pnHoopDesc_pC_v_; +text: .text%__1cGICStubIset_stub6MpnKCompiledIC_pnHoopDesc_pC_v_; +text: .text%__1cRInlineCacheBufferXassemble_ic_buffer_code6FpCpnHoopDesc_1_v_; +text: .text%__1cKCompiledICSset_ic_destination6MpC_v_; +text: .text%__1cRInlineCacheBufferLnew_ic_stub6F_pnGICStub__; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: objArrayKlass.o; +text: .text%JVM_NewArray; +text: .text%__1cKReflectionRreflect_new_array6FpnHoopDesc_ipnGThread__pnMarrayOopDesc__; +text: .text%__1cSInterpreterRuntimeOmultianewarray6FpnKJavaThread_pi_v_; +text: .text%__1cNobjArrayKlassOmulti_allocate6MipiipnGThread__pnHoopDesc__; +text: .text%__1cNinstanceKlassSlookup_osr_nmethod6kMkpnNmethodOopDesc_i_pnHnmethod__; +text: .text%__1cQSimpleCompPolicyYmethod_back_branch_event6MnMmethodHandle_iipnGThread__v_; +text: .text%__1cICompilerMsupports_osr6M_i_: c1_Compiler.o; +text: .text%__1cHciKlassOis_subclass_of6Mp0_i_; +text: .text%__1cMGraphBuilderQnew_object_array6M_v_; +text: .text%__1cONewObjectArrayFvisit6MpnSInstructionVisitor__v_: c1_Instruction.o; +text: .text%__1cNCanonicalizerRdo_NewObjectArray6MpnONewObjectArray__v_; +text: .text%__1cPciObjArrayKlass2t6MnLKlassHandle__v_; +text: .text%__1cPciObjArrayKlassGloader6M_pnHoopDesc__: ciObjArrayKlass.o; +text: .text%__1cMGraphBuilderIshift_op6MpnJValueType_nJBytecodesECode__v_; +text: .text%__1cHShiftOpFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerKdo_ShiftOp6MpnHShiftOp__v_; +text: .text%__1cHShiftOpEhash6kM_i_: c1_GraphBuilder.o; +text: .text%__1cHShiftOpEname6kM_pkc_: c1_GraphBuilder.o; +text: .text%__1cLLoadIndexedOas_LoadIndexed6M_p0_: c1_Instruction.o; +text: .text%__1cMArithmeticOpIis_equal6kMpnLInstruction__i_: c1_Instruction.o; +text: .text%__1cDOp2Gas_Op26M_p0_: c1_Instruction.o; +text: .text%__1cLInstructionMas_LoadField6M_pnJLoadField__: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorRdo_NewObjectArray6MpnONewObjectArray__v_; +text: .text%__1cDOp2Pinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorKdo_ShiftOp6MpnHShiftOp__v_; +text: .text%__1cHciKlassMaccess_flags6M_i_; +text: .text%__1cILIR_ListPallocate_object6MnFRInfo_111ii1pnICodeStub__v_; +text: .text%__1cLLIR_EmitterOmembar_release6M_v_; +text: .text%__1cLLIR_EmitterGmembar6M_v_; +text: .text%__1cIValueGenRdo_NewObjectArray6MpnONewObjectArray__v_; +text: .text%__1cLLIR_EmitterQnew_object_array6MnFRInfo_pnHciKlass_pnLLIR_OprDesc_11111pnMCodeEmitInfo_7_v_; +text: .text%__1cSNewObjectArrayStub2t6MnFRInfo_11pnMCodeEmitInfo__v_; +text: .text%__1cPciObjArrayKlassEmake6FpnHciKlass__p0_; +text: .text%__1cPciObjArrayKlassJmake_impl6FpnHciKlass__p0_; +text: .text%__1cLLIR_EmitterOmembar_acquire6M_v_; +text: .text%__1cIValueGenKdo_ShiftOp6MpnHShiftOp__v_; +text: .text%__1cIValueGenPshiftCountRInfo6F_nFRInfo__; +text: .text%__1cLLIR_EmitterIshift_op6MnJBytecodesECode_nFRInfo_pnLLIR_OprDesc_53_v_; +text: .text%__1cILIR_ListKshift_left6MnFRInfo_i1_v_: c1_LIREmitter.o; +text: .text%__1cILIR_ListKlogical_or6MnFRInfo_pnLLIR_OprDesc_1_v_: c1_LIREmitter.o; +text: .text%__1cOLIR_OpAllocObjFvisit6MpnQLIR_OpVisitState__v_; +text: .text%__1cSNewObjectArrayStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; +text: .text%__1cOLIR_OpAllocObjJemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerOemit_alloc_obj6MpnOLIR_OpAllocObj__v_; +text: .text%__1cNLIR_AssemblerOemit_alloc_obj6MpnOLIR_OpAllocObj__v_; +text: .text%__1cRC1_MacroAssemblerPallocate_object6MpnMRegisterImpl_22ii2rnFLabel__v_; +text: .text%__1cNLIR_AssemblerOmembar_release6M_v_; +text: .text%__1cNLIR_AssemblerGmembar6M_v_; +text: .text%__1cSNewObjectArrayStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; +text: .text%__1cNLIR_AssemblerOmembar_acquire6M_v_; +text: .text%__1cEBaseHas_Base6M_p0_: c1_IR.o; +text: .text%__1cNLIR_AssemblerOemit_osr_entry6MpnHIRScope_ipnFLabel_i_v_; +text: .text%__1cSNewObjectArrayStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%__1cNinstanceKlassPadd_osr_nmethod6MpnHnmethod__v_; +text: .text%__1cUGenericGrowableArrayLraw_at_grow6MipknEGrET__pv_; +text: .text%__1cNSignatureInfoIdo_short6M_v_: bytecode.o; +text: .text%jni_MonitorEnter: jni.o; +text: .text%__1cSObjectSynchronizerJjni_enter6FnGHandle_pnGThread__v_; +text: .text%jni_MonitorExit: jni.o; +text: .text%__1cSObjectSynchronizerIjni_exit6FpnHoopDesc_pnGThread__v_; +text: .text%jni_CallVoidMethod: jni.o; +text: .text%__1cXJNI_ArgumentPusherVaArgHget_int6M_v_: jni.o; +text: .text%jni_CallStaticBooleanMethodV: jni.o; +text: .text%JVM_GetStackTraceDepth; +text: .text%__1cTjava_lang_ThrowableVget_stack_trace_depth6FpnHoopDesc_pnGThread__i_; +text: .text%__1cTjava_lang_ThrowableJbacktrace6FpnHoopDesc__2_; +text: .text%JVM_GetStackTraceElement; +text: .text%__1cTjava_lang_ThrowableXget_stack_trace_element6FpnHoopDesc_ipnGThread__2_; +text: .text%__1cbBjava_lang_StackTraceElementGcreate6FnMmethodHandle_ipnGThread__pnHoopDesc__; +text: .text%__1cbBjava_lang_StackTraceElementNset_className6FpnHoopDesc_2_v_; +text: .text%__1cbBjava_lang_StackTraceElementOset_methodName6FpnHoopDesc_2_v_; +text: .text%__1cbBjava_lang_StackTraceElementMset_fileName6FpnHoopDesc_2_v_; +text: .text%__1cNmethodOopDescUline_number_from_bci6kMi_i_; +text: .text%__1cbECompressedLineNumberReadStream2t6MpC_v_; +text: .text%__1cbECompressedLineNumberReadStreamJread_pair6M_i_; +text: .text%__1cUCompressedReadStreamIread_int6M_i_: methodOop.o; +text: .text%__1cbBjava_lang_StackTraceElementOset_lineNumber6FpnHoopDesc_i_v_; +text: .text%__1cFKlassNoop_is_method6kM_i_: typeArrayKlass.o; +text: .text%__1cFKlassRoop_is_methodData6kM_i_: typeArrayKlass.o; +text: .text%__1cIciObjectOis_null_object6kM_i_: ciObjectFactory.o; +text: .text%__1cNObjectMonitorJnotifyAll6MpnGThread__v_; +text: .text%__1cNObjectMonitorREntryQdDueue_insert6MpnMObjectWaiter_i_v_; +text: .text%__1cNObjectMonitorbAEntryQdDueue_SelectSuccessor6M_pnMObjectWaiter__; +text: .text%__1cLServiceUtilLvisible_oop6FpnHoopDesc__i_: objectMonitor_solaris.o; +text: .text%__1cNObjectMonitorGEnterI6MpnGThread__v_; +text: .text%JVM_EnableCompiler; +text: .text%__1cCosHSolarisFEventEpark6Mx_i_: objectMonitor_solaris.o; +text: .text%__1cJStubQdDueueKremove_all6M_v_; +text: .text%__1cJStubQdDueueMremove_first6Mi_v_; +text: .text%__1cJStubQdDueueMremove_first6M_v_; +text: .text%__1cPICStubInterfaceIfinalize6MpnEStub__v_: icBuffer.o; +text: .text%__1cGICStubIfinalize6M_v_; +text: .text%__1cGICStubKcached_oop6kM_pnHoopDesc__; +text: .text%__1cRInlineCacheBufferUic_buffer_cached_oop6FpC_pnHoopDesc__; +text: .text%__1cKCompiledICOset_cached_oop6MpnHoopDesc__v_; +text: .text%__1cOoop_RelocationSfix_oop_relocation6M_v_; +text: .text%__1cGICStubLdestination6kM_pC_; +text: .text%__1cRInlineCacheBufferVic_buffer_entry_point6FpC_1_; +text: .text%__1cPICStubInterfaceEsize6kMpnEStub__i_: icBuffer.o; +text: .text%__1cUSafepointSynchronizeDend6F_v_; +text: .text%__1cCosbAmake_polling_page_readable6F_v_; +text: .text%__1cTAbstractInterpreterRignore_safepoints6F_v_; +text: .text%__1cGThreadQunboost_priority6Fp0_v_; +text: .text%__1cUThreadSafepointStateHrestart6M_v_; +text: .text%__1cORuntimeServiceUrecord_safepoint_end6F_v_; +text: .text%__1cKJavaThreadbScheck_safepoint_and_suspend_for_native_trans6Fp0_v_; +# Test LoadFrame +text: .text%__1cNObjectMonitorGenter26MpnGThread__v_; +text: .text%__1cICompilerPsupports_native6M_i_: c1_Compiler.o; +text: .text%__1cLCompilationVcompile_native_method6MpnLCodeOffsets__i_; +text: .text%__1cIciMethodMnative_entry6M_pC_; +text: .text%__1cLCompilationUemit_code_for_native6MpCpnLCodeOffsets__v_; +text: .text%__1cLCompilationXemit_code_prolog_native6MpnIFrameMap__v_; +text: .text%__1cNLIR_AssemblerRemit_method_entry6MpnLLIR_Emitter_pnHIRScope__v_; +text: .text%__1cOMacroAssemblerHfat_nop6M_v_; +text: .text%__1cNLIR_AssemblerQemit_native_call6MpCpnMCodeEmitInfo__v_; +text: .text%__1cMCodeEmitInfobGcreate_oop_map_for_own_signature6M_pnGOopMap__; +text: .text%__1cNLIR_AssemblerXemit_native_method_exit6MpnMCodeEmitInfo__v_; +text: .text%__1cNSignatureInfoHdo_char6M_v_: reflection.o; +text: .text%__1cNSignatureInfoHdo_bool6M_v_: reflection.o; +text: .text%jni_CallObjectMethodV: jni.o; +text: .text%jni_SetObjectField: jni.o; +text: .text%jni_IsInstanceOf: jni.o; +text: .text%jni_GetStaticObjectField: jni.o; +text: .text%__1cbCTwoGenerationCollectorPolicybMshould_try_older_generation_allocation6kMI_i_; +text: .text%__1cQGenCollectedHeapSattempt_allocation6MIiii_pnIHeapWord__; +text: .text%__1cQDefNewGenerationIallocate6MIii_pnIHeapWord__: defNewGeneration.o; +text: .text%__1cKGenerationInext_gen6kM_p0_; +text: .text%__1cKGenerationYallocation_limit_reached6MpnFSpace_pnIHeapWord_I_4_: tenuredGeneration.o; +text: .text%__1cQDefNewGenerationTallocate_from_space6MI_pnIHeapWord__; +text: .text%__1cPVM_GC_OperationNdoit_prologue6M_i_; +text: .text%__1cPVM_GC_OperationZacquire_pending_list_lock6M_v_; +text: .text%__1cQinstanceRefKlassZacquire_pending_list_lock6FpnJBasicLock__v_; +text: .text%__1cXjava_lang_ref_ReferenceWpending_list_lock_addr6F_ppnHoopDesc__; +text: .text%__1cPVM_GC_OperationQgc_count_changed6kM_i_; +text: .text%__1cbAVM_GenCollectForAllocationEname6kM_pkc_: vm_operations.o; +text: .text%__1cbAVM_GenCollectForAllocationEdoit6M_v_; +text: .text%__1cNJvmtiGCMarker2t6Mi_v_; +text: .text%__1cQGenCollectedHeapZsatisfy_failed_allocation6MIiipi_pnIHeapWord__; +text: .text%__1cbCTwoGenerationCollectorPolicyZsatisfy_failed_allocation6MIiipi_pnIHeapWord__; +text: .text%__1cQGenCollectedHeapNdo_collection6MiiIiiipi_v_; +text: .text%__1cXTraceMemoryManagerStats2t6Mi_v_; +text: .text%__1cNMemoryServiceIgc_begin6Fi_v_; +text: .text%__1cPGCMemoryManagerIgc_begin6M_v_; +text: .text%__1cKManagementJtimestamp6F_x_; +text: .text%__1cKGCStatInfoMset_gc_usage6MinLMemoryUsage_i_v_; +text: .text%__1cTContiguousSpacePoolQget_memory_usage6M_nLMemoryUsage__; +text: .text%__1cTContiguousSpacePoolNused_in_bytes6M_I_: memoryPool.o; +text: .text%__1cbBSurvivorContiguousSpacePoolQget_memory_usage6M_nLMemoryUsage__; +text: .text%__1cbBSurvivorContiguousSpacePoolNused_in_bytes6M_I_: memoryPool.o; +text: .text%__1cOGenerationPoolQget_memory_usage6M_nLMemoryUsage__; +text: .text%__1cOGenerationPoolNused_in_bytes6M_I_: memoryPool.o; +text: .text%__1cQGenCollectedHeapLgc_prologue6Mi_v_; +text: .text%__1cNCollectedHeapbFaccumulate_statistics_all_tlabs6M_v_; +text: .text%__1cWThreadLocalAllocBufferbFaccumulate_statistics_before_gc6F_v_; +text: .text%__1cWThreadLocalAllocBufferVaccumulate_statistics6MIi_v_; +text: .text%__1cPGlobalTLABStatsHpublish6M_v_; +text: .text%__1cQGenCollectedHeapTensure_parseability6M_v_; +text: .text%__1cNCollectedHeapTensure_parseability6M_v_; +text: .text%__1cNCollectedHeapOfill_all_tlabs6M_v_; +text: .text%__1cQGenCollectedHeapSgeneration_iterate6Mpn0AKGenClosure_i_v_; +text: .text%__1cbCGenEnsureParseabilityClosureNdo_generation6MpnKGeneration__v_: genCollectedHeap.o; +text: .text%__1cKGenerationTensure_parseability6M_v_: defNewGeneration.o; +text: .text%__1cKGenerationTensure_parseability6M_v_: tenuredGeneration.o; +text: .text%__1cKGenerationTensure_parseability6M_v_: compactingPermGenGen.o; +text: .text%__1cSAllocationProfilerViterate_since_last_gc6F_v_; +text: .text%__1cUGenGCPrologueClosureNdo_generation6MpnKGeneration__v_: genCollectedHeap.o; +text: .text%__1cQDefNewGenerationLgc_prologue6Mi_v_: defNewGeneration.o; +text: .text%__1cRTenuredGenerationLgc_prologue6Mi_v_; +text: .text%__1cKGenerationLgc_prologue6Mi_v_: compactingPermGenGen.o; +text: .text%__1cKGenerationOshould_collect6MiIii_i_: defNewGeneration.o; +text: .text%__1cQDefNewGenerationKshort_name6kM_pkc_: defNewGeneration.o; +text: .text%__1cKGenerationIcounters6M_pnRCollectorCounters__: defNewGeneration.o; +text: .text%__1cQGenCollectedHeapKsave_marks6M_v_; +text: .text%__1cQDefNewGenerationKsave_marks6M_v_; +text: .text%__1cbCOneContigSpaceCardGenerationKsave_marks6M_v_; +text: .text%__1cQDefNewGenerationHcollect6MiiIii_v_; +text: .text%__1cQDefNewGenerationbAcollection_attempt_is_safe6M_i_; +text: .text%__1cRTenuredGenerationZpromotion_attempt_is_safe6kMIi_i_; +text: .text%__1cKGenerationYmax_contiguous_available6kM_I_; +text: .text%__1cbCOneContigSpaceCardGenerationUcontiguous_available6kM_I_; +text: .text%__1cQDefNewGenerationbIinit_assuming_no_promotion_failure6M_v_; +text: .text%__1cQDefNewGenerationOIsAliveClosure2t6MpnKGeneration__v_; +text: .text%__1cSScanWeakRefClosure2t6MpnQDefNewGeneration__v_; +text: .text%__1cLCardTableRSbGprepare_for_younger_refs_iterate6Mi_v_; +text: .text%__1cULRUCurrentHeapPolicy2t6M_v_; +text: .text%__1cPCollectorPolicyPis_train_policy6M_i_: collectorPolicy.o; +text: .text%__1cPFastScanClosure2t6MpnQDefNewGeneration_i_v_; +text: .text%__1cQDefNewGenerationbCFastEvacuateFollowersClosure2t6MpnQGenCollectedHeap_ip0pnPFastScanClosure_6_v_; +text: .text%__1cQGenCollectedHeapUprocess_strong_roots6Miiin0ATClassScanningOption_pnQOopsInGenClosure_3_v_; +text: .text%__1cKSharedHeapbAchange_strong_roots_parity6M_v_; +text: .text%__1cMSubTasksDonePis_task_claimed6Mi_i_; +text: .text%__1cIUniverseHoops_do6FpnKOopClosure_i_v_; +text: .text%__1cPFastScanClosureGdo_oop6MppnHoopDesc__v_: defNewGeneration.o; +text: .text%__1cQDefNewGenerationWcopy_to_survivor_space6MpnHoopDesc_p2_2_; +text: .text%__1cKJNIHandlesHoops_do6FpnKOopClosure__v_; +text: .text%__1cOJNIHandleBlockHoops_do6MpnKOopClosure__v_; +text: .text%__1cHThreadsHoops_do6FpnKOopClosure__v_; +text: .text%__1cKJavaThreadHoops_do6MpnKOopClosure__v_; +text: .text%__1cGThreadHoops_do6MpnKOopClosure__v_; +text: .text%__1cKHandleAreaHoops_do6MpnKOopClosure__v_; +text: .text%__1cNchunk_oops_do6FpnKOopClosure_pnFChunk_pc_I_: handles.o; +text: .text%__1cQStackFrameStream2t6MpnKJavaThread_i_v_; +text: .text%__1cFframeQoops_do_internal6MpnKOopClosure_pnLRegisterMap_i_v_; +text: .text%__1cFframeToops_interpreted_do6MpnKOopClosure_pknLRegisterMap_i_v_; +text: .text%__1cFframeVinterpreter_frame_bci6kM_i_; +text: .text%__1cFframebDinterpreter_frame_monitor_end6kM_pnPBasicObjectLock__; +text: .text%__1cFframebFinterpreter_frame_monitor_begin6kM_pnPBasicObjectLock__; +text: .text%__1cRInterpreterOopMap2t6M_v_; +text: .text%__1cRInterpreterOopMapKinitialize6M_v_; +text: .text%__1cNmethodOopDescImask_for6MipnRInterpreterOopMap__v_; +text: .text%__1cNinstanceKlassImask_for6MnMmethodHandle_ipnRInterpreterOopMap__v_; +text: .text%__1cLOopMapCache2t6M_v_; +text: .text%__1cLOopMapCacheGlookup6MnMmethodHandle_ipnRInterpreterOopMap__v_; +text: .text%__1cLOopMapCacheIentry_at6kMi_pnQOopMapCacheEntry__; +text: .text%__1cRInterpreterOopMapIis_empty6M_i_; +text: .text%__1cQOopMapCacheEntryEfill6MnMmethodHandle_i_v_; +text: .text%__1cQOopMapCacheEntryFflush6M_v_; +text: .text%__1cQOopMapCacheEntryTdeallocate_bit_mask6M_v_; +text: .text%__1cQOopMapCacheEntryPfill_for_native6M_v_; +text: .text%__1cQOopMapCacheEntryRallocate_bit_mask6M_v_; +text: .text%__1cTMaskFillerForNative2t6MnMmethodHandle_pIi_v_: oopMapCache.o; +text: .text%__1cNFingerprinterLfingerprint6M_X_: oopMapCache.o; +text: .text%__1cTMaskFillerForNativeLpass_object6M_v_: oopMapCache.o; +text: .text%__1cRInterpreterOopMapNresource_copy6MpnQOopMapCacheEntry__v_; +text: .text%__1cRInterpreterOopMapLiterate_oop6MpnNOffsetClosure__v_; +text: .text%__1cXInterpreterFrameClosureJoffset_do6Mi_v_: frame.o; +text: .text%__1cRInterpreterOopMap2T6M_v_; +text: .text%__1cTOopMapForCacheEntry2t6MnMmethodHandle_ipnQOopMapCacheEntry__v_; +text: .text%__1cTOopMapForCacheEntryLcompute_map6MpnGThread__v_; +text: .text%__1cTOopMapForCacheEntryRpossible_gc_point6MpnOBytecodeStream__i_; +text: .text%__1cTOopMapForCacheEntryOreport_results6kM_i_: oopMapCache.o; +text: .text%__1cOGenerateOopMapVresult_for_basicblock6Mi_v_; +text: .text%__1cTOopMapForCacheEntryZfill_stackmap_for_opcodes6MpnOBytecodeStream_pnNCellTypeState_4i_v_; +text: .text%__1cQOopMapCacheEntryIset_mask6MpnNCellTypeState_2i_v_; +text: .text%__1cFframeNoops_entry_do6MpnKOopClosure_pknLRegisterMap__v_; +text: .text%__1cPJavaCallWrapperHoops_do6MpnKOopClosure__v_; +text: .text%__1cXNativeSignatureIteratorHdo_long6M_v_: oopMapCache.o; +text: .text%__1cTMaskFillerForNativeJpass_long6M_v_: oopMapCache.o; +text: .text%__1cFframebHnext_monitor_in_interpreter_frame6kMpnPBasicObjectLock__2_; +text: .text%__1cOGenerateOopMapPdo_monitorenter6Mi_v_; +text: .text%__1cOGenerateOopMapXreplace_all_CTS_matches6MnNCellTypeState_1_v_; +text: .text%__1cOGenerateOopMapMmonitor_push6MnNCellTypeState__v_; +text: .text%__1cQComputeCallStackHdo_bool6M_v_: generateOopMap.o; +text: .text%__1cQComputeCallStackHdo_long6M_v_: generateOopMap.o; +text: .text%__1cOGenerateOopMapOdo_monitorexit6Mi_v_; +text: .text%__1cOGenerateOopMapLmonitor_pop6M_nNCellTypeState__; +text: .text%__1cRComputeEntryStackHdo_long6M_v_: generateOopMap.o; +text: .text%__1cPBytecode_invokeIis_valid6kM_i_: frame.o; +text: .text%__1cXNativeSignatureIteratorJdo_object6Mii_v_: oopMapCache.o; +text: .text%__1cFframebDoops_interpreted_arguments_do6MnMsymbolHandle_ipnKOopClosure__v_; +text: .text%__1cRArgumentOopFinderDset6MinJBasicType__v_: frame.o; +text: .text%__1cIVMThreadHoops_do6MpnKOopClosure__v_; +text: .text%__1cQVMOperationQdDueueHoops_do6MpnKOopClosure__v_; +text: .text%__1cQVMOperationQdDueueNqueue_oops_do6MipnKOopClosure__v_; +text: .text%__1cSObjectSynchronizerHoops_do6FpnKOopClosure__v_; +text: .text%__1cMFlatProfilerHoops_do6FpnKOopClosure__v_; +text: .text%__1cKManagementHoops_do6FpnKOopClosure__v_; +text: .text%__1cNMemoryServiceHoops_do6FpnKOopClosure__v_; +text: .text%__1cKMemoryPoolHoops_do6MpnKOopClosure__v_; +text: .text%__1cNMemoryManagerHoops_do6MpnKOopClosure__v_; +text: .text%__1cNThreadServiceHoops_do6FpnKOopClosure__v_; +text: .text%__1cLJvmtiExportHoops_do6FpnKOopClosure__v_; +text: .text%__1cXJvmtiCurrentBreakpointsHoops_do6FpnKOopClosure__v_; +text: .text%__1cbGJvmtiVMObjectAllocEventCollectorXoops_do_for_all_threads6FpnKOopClosure__v_; +text: .text%__1cQSystemDictionaryHoops_do6FpnKOopClosure__v_; +text: .text%__1cQSystemDictionaryRpreloaded_oops_do6FpnKOopClosure__v_; +text: .text%__1cKDictionaryHoops_do6MpnKOopClosure__v_; +text: .text%__1cPDictionaryEntrybDprotection_domain_set_oops_do6MpnKOopClosure__v_: dictionary.o; +text: .text%__1cQPlaceholderTableHoops_do6MpnKOopClosure__v_; +text: .text%__1cVLoaderConstraintTableHoops_do6MpnKOopClosure__v_; +text: .text%__1cUCompactingPermGenGenUyounger_refs_iterate6MpnQOopsInGenClosure__v_; +text: .text%__1cbCOneContigSpaceCardGenerationUyounger_refs_iterate6MpnQOopsInGenClosure__v_; +text: .text%__1cKGenerationbDyounger_refs_in_space_iterate6MpnFSpace_pnQOopsInGenClosure__v_; +text: .text%__1cLCardTableRSbDyounger_refs_in_space_iterate6MpnFSpace_pnQOopsInGenClosure__v_; +text: .text%__1cPContiguousSpaceLnew_dcto_cl6MpnKOopClosure_nRCardTableModRefBSOPrecisionStyle_pnIHeapWord__pnVDirtyCardToOopClosure__; +text: .text%__1cPContiguousSpaceZused_region_at_save_marks6kM_nJMemRegion__: space.o; +text: .text%__1cRCardTableModRefBSWnon_clean_card_iterate6MpnFSpace_nJMemRegion_pnVDirtyCardToOopClosure_pnQMemRegionClosure_i_v_; +text: .text%__1cRCardTableModRefBSbBnon_clean_card_iterate_work6MnJMemRegion_pnQMemRegionClosure_i_v_; +text: .text%__1cJMemRegionMintersection6kMk0_0_; +text: .text%__1cYClearNoncleanCardWrapperMdo_MemRegion6MnJMemRegion__v_: cardTableRS.o; +text: .text%__1cYClearNoncleanCardWrapperKclear_card6MpW_i_: cardTableRS.o; +text: .text%__1cVDirtyCardToOopClosureMdo_MemRegion6MnJMemRegion__v_; +text: .text%__1cWOffsetTableContigSpaceLblock_start6kMpkv_pnIHeapWord__: space.o; +text: .text%__1cbBBlockOffsetArrayContigSpaceSblock_start_unsafe6kMpkv_pnIHeapWord__; +text: .text%__1cPContiguousSpaceKblock_size6kMpknIHeapWord__I_; +text: .text%__1cUContiguousSpaceDCTOCOget_actual_top6MpnIHeapWord_2_2_; +text: .text%__1cPContiguousSpaceRtoContiguousSpace6M_p0_: space.o; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: instanceKlass.o; +text: .text%__1cPFiltering_DCTOCPwalk_mem_region6MnJMemRegion_pnIHeapWord_3_v_; +text: .text%__1cUContiguousSpaceDCTOCXwalk_mem_region_with_cl6MnJMemRegion_pnIHeapWord_3pnQFilteringClosure__v_; +text: .text%__1cFKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_: methodKlass.o; +text: .text%__1cLmethodKlassRoop_oop_iterate_m6MpnHoopDesc_pnKOopClosure_nJMemRegion__i_; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_: instanceKlassKlass.o; +text: .text%__1cSinstanceKlassKlassPoop_oop_iterate6MpnHoopDesc_pnKOopClosure__i_; +text: .text%__1cNinstanceKlassViterate_static_fields6MpnKOopClosure__v_; +text: .text%__1cLklassVtablePoop_oop_iterate6MpnKOopClosure__v_; +text: .text%__1cQFilteringClosureGdo_oop6MppnHoopDesc__v_; +text: .text%__1cLklassItablePoop_oop_iterate6MpnKOopClosure__v_; +text: .text%__1cKklassKlassPoop_oop_iterate6MpnHoopDesc_pnKOopClosure__i_; +text: .text%__1cKOopClosureXshould_remember_klasses6kM_ki_: space.o; +text: .text%__1cNinstanceKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_; +text: .text%__1cWconstantPoolCacheKlassIoop_size6kMpnHoopDesc__i_; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_: cpCacheKlass.o; +text: .text%__1cWconstantPoolCacheKlassPoop_oop_iterate6MpnHoopDesc_pnKOopClosure__i_; +text: .text%__1cWConstantPoolCacheEntryLoop_iterate6MpnKOopClosure__v_; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_: objArrayKlassKlass.o; +text: .text%__1cSobjArrayKlassKlassPoop_oop_iterate6MpnHoopDesc_pnKOopClosure__i_; +text: .text%__1cParrayKlassKlassPoop_oop_iterate6MpnHoopDesc_pnKOopClosure__i_; +text: .text%__1cNobjArrayKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_; +text: .text%__1cNinstanceKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_; +text: .text%__1cNobjArrayKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_: typeArrayKlass.o; +text: .text%__1cOtypeArrayKlassPoop_oop_iterate6MpnHoopDesc_pnKOopClosure__i_; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_: constMethodKlass.o; +text: .text%__1cQconstMethodKlassPoop_oop_iterate6MpnHoopDesc_pnKOopClosure__i_; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_: methodKlass.o; +text: .text%__1cLmethodKlassPoop_oop_iterate6MpnHoopDesc_pnKOopClosure__i_; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: constantPoolKlass.o; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: constantPoolKlass.o; +text: .text%__1cFKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_: constMethodKlass.o; +text: .text%__1cQconstMethodKlassRoop_oop_iterate_m6MpnHoopDesc_pnKOopClosure_nJMemRegion__i_; +text: .text%__1cFKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_: constantPoolKlass.o; +text: .text%__1cRconstantPoolKlassRoop_oop_iterate_m6MpnHoopDesc_pnKOopClosure_nJMemRegion__i_; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: constMethodKlass.o; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: constMethodKlass.o; +text: .text%__1cFKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_: symbolKlass.o; +text: .text%__1cLsymbolKlassRoop_oop_iterate_m6MpnHoopDesc_pnKOopClosure_nJMemRegion__i_; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_: symbolKlass.o; +text: .text%__1cLsymbolKlassPoop_oop_iterate6MpnHoopDesc_pnKOopClosure__i_; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_: constantPoolKlass.o; +text: .text%__1cRconstantPoolKlassPoop_oop_iterate6MpnHoopDesc_pnKOopClosure__i_; +text: .text%__1cFKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_: cpCacheKlass.o; +text: .text%__1cWconstantPoolCacheKlassRoop_oop_iterate_m6MpnHoopDesc_pnKOopClosure_nJMemRegion__i_; +text: .text%__1cWConstantPoolCacheEntryNoop_iterate_m6MpnKOopClosure_nJMemRegion__v_; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: cpCacheKlass.o; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: cpCacheKlass.o; +text: .text%__1cFKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_: typeArrayKlass.o; +text: .text%__1cOtypeArrayKlassRoop_oop_iterate_m6MpnHoopDesc_pnKOopClosure_nJMemRegion__i_; +text: .text%__1cFKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_: instanceKlassKlass.o; +text: .text%__1cSinstanceKlassKlassRoop_oop_iterate_m6MpnHoopDesc_pnKOopClosure_nJMemRegion__i_; +text: .text%__1cNinstanceKlassViterate_static_fields6MpnKOopClosure_nJMemRegion__v_; +text: .text%__1cLklassVtableRoop_oop_iterate_m6MpnKOopClosure_nJMemRegion__v_; +text: .text%__1cLklassItableRoop_oop_iterate_m6MpnKOopClosure_nJMemRegion__v_; +text: .text%__1cKklassKlassRoop_oop_iterate_m6MpnHoopDesc_pnKOopClosure_nJMemRegion__i_; +text: .text%__1cLOopMapCacheLoop_iterate6MpnKOopClosure_nJMemRegion__v_; +text: .text%__1cRInterpreterOopMapLoop_iterate6MpnKOopClosure_nJMemRegion__v_; +text: .text%__1cKOopClosureIdo_oop_v6MppnHoopDesc__v_: space.o; +text: .text%__1cLOopMapCacheLoop_iterate6MpnKOopClosure__v_; +text: .text%__1cRInterpreterOopMapLoop_iterate6MpnKOopClosure__v_; +text: .text%__1cVcompiledICHolderKlassIoop_size6kMpnHoopDesc__i_; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_: compiledICHolderKlass.o; +text: .text%__1cVcompiledICHolderKlassPoop_oop_iterate6MpnHoopDesc_pnKOopClosure__i_; +text: .text%__1cFKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_: klassKlass.o; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_: klassKlass.o; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_: typeArrayKlassKlass.o; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_: arrayKlassKlass.o; +text: .text%__1cLCardTableRSUyounger_refs_iterate6MpnKGeneration_pnQOopsInGenClosure__v_; +text: .text%__1cMSubTasksDoneTall_tasks_completed6M_v_; +text: .text%__1cQDefNewGenerationbCFastEvacuateFollowersClosureHdo_void6M_v_; +text: .text%__1cQGenCollectedHeapbCoop_since_save_marks_iterate6MipnPFastScanClosure_2_v_; +text: .text%__1cQDefNewGenerationbFoop_since_save_marks_iterate_nv6MpnPFastScanClosure__v_; +text: .text%__1cPContiguousSpacebFoop_since_save_marks_iterate_nv6MpnPFastScanClosure__v_; +text: .text%__1cNobjArrayKlassSoop_oop_iterate_nv6MpnHoopDesc_pnPFastScanClosure__i_; +text: .text%__1cNinstanceKlassSoop_oop_iterate_nv6MpnHoopDesc_pnPFastScanClosure__i_; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnPFastScanClosure__i_: typeArrayKlass.o; +text: .text%__1cQinstanceRefKlassSoop_oop_iterate_nv6MpnHoopDesc_pnPFastScanClosure__i_; +text: .text%__1cXjava_lang_ref_ReferenceNreferent_addr6FpnHoopDesc__p2_; +text: .text%__1cSReferenceProcessorSdiscover_reference6MpnHoopDesc_nNReferenceType__i_; +text: .text%__1cXjava_lang_ref_ReferenceJnext_addr6FpnHoopDesc__p2_; +text: .text%__1cXjava_lang_ref_ReferencePdiscovered_addr6FpnHoopDesc__p2_; +text: .text%__1cSReferenceProcessorTget_discovered_list6MnNReferenceType__ppnHoopDesc__; +text: .text%__1cKGenerationHpromote6MpnHoopDesc_Ip2_2_; +text: .text%__1cbCOneContigSpaceCardGenerationIallocate6MIii_pnIHeapWord__: tenuredGeneration.o; +text: .text%__1cbCOneContigSpaceCardGenerationbFoop_since_save_marks_iterate_nv6MpnPFastScanClosure__v_; +text: .text%__1cQGenCollectedHeapbAno_allocs_since_save_marks6Mi_i_; +text: .text%__1cQDefNewGenerationbAno_allocs_since_save_marks6M_i_; +text: .text%__1cbCOneContigSpaceCardGenerationbAno_allocs_since_save_marks6M_i_; +text: .text%__1cQDefNewGenerationUFastKeepAliveClosure2t6Mp0pnSScanWeakRefClosure__v_; +text: .text%__1cQDefNewGenerationQKeepAliveClosure2t6MpnSScanWeakRefClosure__v_; +text: .text%__1cbDReferenceProcessorInitializerIis_clean6kM_v_: concurrentMarkSweepGeneration.o; +text: .text%__1cSReferenceProcessorbDprocess_discovered_references6M_v_; +text: .text%__1cSReferenceProcessorbAprocess_discovered_reflist6MppnHoopDesc_pnPReferencePolicy_i_v_; +text: .text%__1cSReferenceProcessorOprocess_phase16MppnHoopDesc_pnPReferencePolicy_pnRBoolObjectClosure_pnKOopClosure_pnLVoidClosure__v_; +text: .text%__1cQDefNewGenerationOIsAliveClosureLdo_object_b6MpnHoopDesc__i_; +text: .text%__1cULRUCurrentHeapPolicyWshould_clear_reference6MpnHoopDesc__i_; +text: .text%__1cbBjava_lang_ref_SoftReferenceFclock6F_x_; +text: .text%__1cbBjava_lang_ref_SoftReferenceJtimestamp6FpnHoopDesc__x_; +text: .text%__1cXjava_lang_ref_ReferenceIset_next6FpnHoopDesc_2_v_; +text: .text%__1cQDefNewGenerationUFastKeepAliveClosureGdo_oop6MppnHoopDesc__v_; +text: .text%__1cSReferenceProcessorOprocess_phase26MppnHoopDesc_pnRBoolObjectClosure_pnKOopClosure__v_; +text: .text%__1cSReferenceProcessorOprocess_phase36MppnHoopDesc_ipnRBoolObjectClosure_pnKOopClosure_pnLVoidClosure__v_; +text: .text%__1cSReferenceProcessorQprocess_phaseJNI6M_v_; +text: .text%__1cKJNIHandlesMweak_oops_do6FpnRBoolObjectClosure_pnKOopClosure__v_; +text: .text%__1cOJNIHandleBlockMweak_oops_do6MpnRBoolObjectClosure_pnKOopClosure__v_; +text: .text%__1cQDefNewGenerationLswap_spaces6M_v_; +text: .text%__1cIageTablebAcompute_tenuring_threshold6MI_i_; +text: .text%__1cKGenerationWupdate_time_of_last_gc6Mx_v_: defNewGeneration.o; +text: .text%__1cSReferenceProcessorbDenqueue_discovered_references6M_i_; +text: .text%__1cXjava_lang_ref_ReferenceRpending_list_addr6F_ppnHoopDesc__; +text: .text%__1cSReferenceProcessorbBenqueue_discovered_reflists6MppnHoopDesc__v_; +text: .text%__1cSReferenceProcessorbAenqueue_discovered_reflist6MpnHoopDesc_p2_v_; +text: .text%__1cQGenCollectedHeapPupdate_gc_stats6Mii_v_: genCollectedHeap.o; +text: .text%__1cKGenerationPupdate_gc_stats6Mii_v_: defNewGeneration.o; +text: .text%__1cRTenuredGenerationPupdate_gc_stats6Mii_v_; +text: .text%__1cVAdaptivePaddedAverageGsample6Mf_v_; +text: .text%__1cKGenerationPupdate_gc_stats6Mii_v_: compactingPermGenGen.o; +text: .text%__1cRTenuredGenerationOshould_collect6MiIii_i_; +text: .text%__1cKGenerationPshould_allocate6MIii_i_: tenuredGeneration.o; +text: .text%__1cbCOneContigSpaceCardGenerationEfree6kM_I_; +text: .text%__1cQDefNewGenerationQcompute_new_size6M_v_; +text: .text%__1cNMemoryServiceStrack_memory_usage6F_v_; +text: .text%__1cRLowMemoryDetectorRdetect_low_memory6F_v_; +text: .text%__1cQGenCollectedHeapLgc_epilogue6Mi_v_; +text: .text%__1cNCollectedHeapQresize_all_tlabs6M_v_; +text: .text%__1cWThreadLocalAllocBufferQresize_all_tlabs6F_v_; +text: .text%__1cWThreadLocalAllocBufferGresize6M_v_; +text: .text%__1cUGenGCEpilogueClosureNdo_generation6MpnKGeneration__v_: genCollectedHeap.o; +text: .text%__1cQDefNewGenerationLgc_epilogue6Mi_v_; +text: .text%__1cRTenuredGenerationLgc_epilogue6Mi_v_; +text: .text%__1cbCOneContigSpaceCardGenerationLgc_epilogue6Mi_v_; +text: .text%__1cRTenuredGenerationPupdate_counters6M_v_; +text: .text%__1cUCompactingPermGenGenPupdate_counters6M_v_; +text: .text%__1cXTraceMemoryManagerStats2T6M_v_; +text: .text%__1cNMemoryServiceGgc_end6Fi_v_; +text: .text%__1cPGCMemoryManagerGgc_end6M_v_; +text: .text%__1cRLowMemoryDetectorWdetect_after_gc_memory6FpnKMemoryPool__v_; +text: .text%__1cNJvmtiGCMarker2T6M_v_; +text: .text%__1cPVM_GC_OperationNdoit_epilogue6M_v_; +text: .text%__1cPVM_GC_OperationbKrelease_and_notify_pending_list_lock6M_v_; +text: .text%__1cQinstanceRefKlassbKrelease_and_notify_pending_list_lock6FipnJBasicLock__v_; +text: .text%__1cXJNI_ArgumentPusherVaArgIget_long6M_v_: jni.o; +text: .text%jni_GetIntArrayRegion: jni.o; +text: .text%jni_SetIntArrayRegion: jni.o; +text: .text%jni_PushLocalFrame: jni.o; +text: .text%jni_PopLocalFrame: jni.o; +text: .text%__1cMGraphBuilderJnegate_op6MpnJValueType__v_; +text: .text%__1cINegateOpFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerLdo_NegateOp6MpnINegateOp__v_; +text: .text%__1cMLinkResolverbPlinktime_resolve_interface_method_or_null6FnLKlassHandle_nMsymbolHandle_21i_nMmethodHandle__; +text: .text%__1cPciInstanceKlassLimplementor6M_p0_; +text: .text%__1cINegateOpPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorLdo_NegateOp6MpnINegateOp__v_; +text: .text%__1cIValueGenJspill_one6MpnJValueType__v_; +text: .text%__1cIRegAllocbBget_smallest_value_to_spill6kMpnJValueType__pnLInstruction__; +text: .text%__1cLLIR_EmitterRarray_store_check6MpnLLIR_OprDesc_2nFRInfo_33pnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListLstore_check6MpnLLIR_OprDesc_2222pnMCodeEmitInfo__v_; +text: .text%__1cPLIR_OpTypeCheck2t6MnILIR_Code_pnLLIR_OprDesc_3333pnMCodeEmitInfo__v_; +text: .text%__1cXArrayStoreExceptionStub2t6MpnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListLshift_right6MnFRInfo_i1_v_: c1_LIREmitter.o; +text: .text%__1cILIR_ListLshift_right6MpnLLIR_OprDesc_222_v_; +text: .text%__1cIValueGenLdo_NegateOp6MpnINegateOp__v_; +text: .text%__1cLLIR_EmitterGnegate6MnFRInfo_pnLLIR_OprDesc__v_; +text: .text%__1cILIR_ListGnegate6MnFRInfo_1_v_: c1_LIREmitter.o; +text: .text%__1cXArrayStoreExceptionStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; +text: .text%__1cXArrayStoreExceptionStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; +text: .text%__1cNLIR_AssemblerEleal6MpnLLIR_OprDesc_2_v_; +text: .text%__1cNLIR_AssemblerGnegate6MpnLLIR_OprDesc_2_v_; +text: .text%__1cNCodeStubArrayIindex_of6kMkpnICodeStub__i_: c1_LIRAssembler_x86.o; +text: .text%__1cXArrayStoreExceptionStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%__1cIRuntime1Tresolve_static_call6FpnKJavaThread_pnHoopDesc__pC_; +text: .text%__1cSCompiledStaticCallNcompute_entry6FnMmethodHandle_rnOStaticCallInfo__v_; +text: .text%__1cSCompiledStaticCallIis_clean6kM_i_; +text: .text%__1cSCompiledStaticCallDset6MrknOStaticCallInfo__v_; +text: .text%__1cMLinkResolverYresolve_interface_method6FrnMmethodHandle_rnLKlassHandle_nSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cHciKlassSsuper_check_offset6M_I_; +text: .text%__1cIRuntime1Thandle_wrong_method6FpnKJavaThread_pnHoopDesc__pC_; +text: .text%__1cNSharedRuntimeTreresolve_call_site6FpnKJavaThread_pnGThread__nMmethodHandle__; +text: .text%__1cFframeRis_compiled_frame6kMpi_i_; +text: .text%__1cHnmethodOis_java_method6kM_i_: nmethod.o; +text: .text%__1cGEventsDlog6FpkcE_v_: sharedRuntime.o; +text: .text%__1cJCodeCacheMfind_nmethod6Fpv_pnHnmethod__; +text: .text%__1cNRelocIteratorEnext6M_i_: sharedRuntime.o; +text: .text%__1cKCompiledICMset_to_clean6M_v_; +text: .text%__1cKCompiledICMstub_address6kM_pC_; +text: .text%__1cGICStubFclear6M_v_; +text: .text%__1cNSharedRuntimeSfind_callee_method6FpnKJavaThread_pnGThread__nMmethodHandle__; +text: .text%__1cRInlineCacheBufferSic_destination_for6FpnKCompiledIC__pC_; +text: .text%__1cIRuntime1Jarraycopy6FpnHoopDesc_i2ii_i_; +text: .text%__1cMGraphBuilderNadd_dependent6MpnPciInstanceKlass_pnIciMethod__v_; +text: .text%__1cYDebugInformationRecorderNadd_dependent6MpnPciInstanceKlass_pnIciMethod__v_; +text: .text%__1cNinstanceKlassVadd_dependent_nmethod6MpnHnmethod__v_; +text: .text%__1cJCodeCacheXmark_for_deoptimization6FpnMklassOopDesc__i_; +text: .text%__1cNinstanceKlassXmark_dependent_nmethods6MpnMklassOopDesc__i_; +text: .text%jni_NewWeakGlobalRef: jni.o; +text: .text%__1cKJNIHandlesQmake_weak_global6FnGHandle__pnI_jobject__; +text: .text%__1cMLinkResolverbBlookup_method_in_interfaces6FrnMmethodHandle_nLKlassHandle_nMsymbolHandle_4pnGThread__v_; +text: .text%jni_CallIntMethodV: jni.o; +text: .text%Unsafe_GetObject; +text: .text%jni_CallBooleanMethod: jni.o; +text: .text%jni_CallVoidMethodV: jni.o; +text: .text%JVM_GetClassDeclaredMethods; +text: .text%JVM_InvokeMethod; +text: .text%__1cKReflectionNinvoke_method6FpnHoopDesc_nGHandle_nOobjArrayHandle_pnGThread__2_; +text: .text%__1cYjava_lang_reflect_MethodFclazz6FpnHoopDesc__2_; +text: .text%__1cYjava_lang_reflect_MethodEslot6FpnHoopDesc__i_; +text: .text%__1cYjava_lang_reflect_MethodPparameter_types6FpnHoopDesc__2_; +text: .text%__1cYjava_lang_reflect_MethodLreturn_type6FpnHoopDesc__2_; +text: .text%JVM_IsInterrupted; +# Test LoadJFrame +text: .text%__1cTresource_free_bytes6FpcI_v_; +text: .text%__1cRComputeEntryStackHdo_bool6M_v_: generateOopMap.o; +text: .text%__1cJFloatTypeDtag6kM_nIValueTag__: c1_ValueType.o; +text: .text%__1cJFloatTypeEbase6kM_pnJValueType__: c1_ValueType.o; +text: .text%__1cJFloatTypeMas_FloatType6M_p0_: c1_ValueType.o; +text: .text%__1cIValueGenTdo_ArithmeticOp_FPU6MpnMArithmeticOp__v_; +text: .text%__1cHLockRegIdo_float6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIRegAllocOset_locked_fpu6MipnLInstruction_i_v_; +text: .text%__1cIValueGenNis_32bit_mode6M_i_; +text: .text%__1cLGetRefCountIdo_float6Mi_v_: c1_RegAlloc.o; +text: .text%__1cJFloatTypeEsize6kM_i_: c1_ValueType.o; +text: .text%__1cHFreeRegIdo_float6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIRegAllocMset_free_fpu6Mi_v_; +text: .text%__1cQChangeSpillCountIdo_float6Mi_v_: c1_RegAlloc.o; +text: .text%__1cLLIR_EmitterRarithmetic_op_fpu6MnJBytecodesECode_pnLLIR_OprDesc_44i_v_; +text: .text%__1cILIR_ListDmul6MpnLLIR_OprDesc_22_v_: c1_LIREmitter.o; +text: .text%__1cIValueGenKround_item6MpnEItem__v_; +text: .text%__1cLLIR_EmitterFround6MipnLLIR_OprDesc__v_; +text: .text%__1cILIR_ListKround32bit6MnFRInfo_i_v_: c1_LIREmitter.o; +text: .text%__1cIValueGenOspill_register6MnFRInfo__v_; +text: .text%__1cIRegAllocTget_value_for_rinfo6kMnFRInfo__pnLInstruction__; +text: .text%__1cLGetValueForGdo_cpu6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIValueGenKdivInRInfo6F_nFRInfo__; +text: .text%__1cIValueGenLremOutRInfo6F_nFRInfo__; +text: .text%__1cMArithmeticOpKlock_stack6kM_pnKValueStack__: c1_Instruction.o; +text: .text%__1cLLIR_EmitterParithmetic_idiv6MnJBytecodesECode_pnLLIR_OprDesc_44nFRInfo_pnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListEirem6MnFRInfo_111pnMCodeEmitInfo__v_; +text: .text%__1cHLIR_Op3Fvisit6MpnQLIR_OpVisitState__v_; +text: .text%__1cHLIR_Op3Jemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerIemit_op36MpnHLIR_Op3__v_; +text: .text%__1cNLIR_AssemblerIfpu_push6MnFRInfo__v_; +text: .text%__1cIFrameMapLFpuStackSimEpush6Mi_v_; +text: .text%__1cNLIR_AssemblerKfpu_on_tos6MnFRInfo__v_; +text: .text%__1cIFrameMapLFpuStackSimPoffset_from_tos6kMi_i_; +text: .text%__1cIintArrayIindex_of6kMki_i_: c1_FrameMap_x86.o; +text: .text%__1cNLIR_AssemblerHfpu_pop6MnFRInfo__v_; +text: .text%__1cIFrameMapLFpuStackSimDpop6Mi_i_; +text: .text%__1cNLIR_AssemblerKround32_op6MpnLLIR_OprDesc_2_v_; +text: .text%__1cJAssemblerGfist_s6MnHAddress__v_; +text: .text%__1cNLIR_AssemblerJreset_FPU6M_v_; +text: .text%__1cNLIR_AssemblerIemit_op36MpnHLIR_Op3__v_; +text: .text%__1cNLIR_AssemblerParithmetic_idiv6MnILIR_Code_pnLLIR_OprDesc_333pnMCodeEmitInfo__v_; +text: .text%__1cNLIR_AssemblerXadd_debug_info_for_div06MipnMCodeEmitInfo__v_; +text: .text%__1cNDivByZeroStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; +text: .text%__1cNDivByZeroStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%__1cIciObjectSis_obj_array_klass6M_i_: ciTypeArrayKlass.o; +text: .text%__1cLInstructionOas_ArrayLength6M_pnLArrayLength__: c1_GraphBuilder.o; +text: .text%__1cLInstructionKas_ShiftOp6M_pnHShiftOp__: c1_Instruction.o; +text: .text%__1cILIR_ListLlogical_xor6MnFRInfo_pnLLIR_OprDesc_1_v_: c1_LIREmitter.o; +text: .text%__1cILIR_ListUunsigned_shift_right6MnFRInfo_i1_v_: c1_LIREmitter.o; +text: .text%__1cIRuntime1Ohandle_ic_miss6FpnKJavaThread_pnHoopDesc__pC_; +text: .text%__1cNSharedRuntimeVhandle_ic_miss_helper6FpnKJavaThread_pnGThread__nMmethodHandle__; +text: .text%__1cbEJvmtiDynamicCodeEventCollector2t6M_v_; +text: .text%__1cKCompiledICOis_megamorphic6kM_i_; +text: .text%__1cLVtableStubsOis_entry_point6FpC_i_; +text: .text%__1cKCompiledICSset_to_megamorphic6MpnICallInfo_nJBytecodesECode_pnGThread__v_; +text: .text%__1cLVtableStubsLcreate_stub6FiipnNmethodOopDesc__pC_; +text: .text%__1cLVtableStubsGlookup6Fiii_pnKVtableStub__; +text: .text%__1cLVtableStubsScreate_vtable_stub6Fii_pnKVtableStub__; +text: .text%__1cKVtableStubSpd_code_size_limit6Fi_i_; +text: .text%__1cKVtableStub2n6FIi_pv_; +text: .text%__1cKVtableStubRpd_code_alignment6F_i_; +text: .text%__1cLVtableStubsFenter6FiiipnKVtableStub__v_; +text: .text%__1cGEventsDlog6FpkcE_v_: compiledIC.o; +text: .text%__1cbEJvmtiDynamicCodeEventCollector2T6M_v_; +text: .text%Unsafe_EnsureClassInitialized; +text: .text%Unsafe_StaticFieldOffset; +text: .text%Unsafe_StaticFieldBaseFromField; +text: .text%Unsafe_GetIntVolatile; +text: .text%__1cUBytecode_tableswitchGlength6M_i_: generateOopMap.o; +text: .text%__1cUBytecode_tableswitchOdest_offset_at6kMi_i_; +text: .text%__1cUBytecode_tableswitchGlength6M_i_: c1_GraphBuilder.o; +text: .text%__1cLInstructionKas_ShiftOp6M_pnHShiftOp__: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderMtable_switch6M_v_; +text: .text%__1cLTableSwitchFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerOdo_TableSwitch6MpnLTableSwitch__v_; +text: .text%__1cLInstructionJas_Return6M_pnGReturn__: c1_GraphBuilder.o; +text: .text%__1cGSwitchPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorOdo_TableSwitch6MpnLTableSwitch__v_; +text: .text%__1cIValueGenOdo_TableSwitch6MpnLTableSwitch__v_; +text: .text%__1cIValueGenVsetup_phis_for_switch6MpnEItem_pnKValueStack__v_; +text: .text%__1cLLIR_EmitterOtableswitch_op6MpnLLIR_OprDesc_ipnKBlockBegin__v_; +text: .text%__1cWstatic_call_RelocationLstatic_stub6M_pC_; +text: .text%__1cSCompiledStaticCallMset_to_clean6M_v_; +# Test JHello +text: .text%__1cYjava_lang_reflect_MethodNset_signature6FpnHoopDesc_2_v_; +text: .text%JVM_InitializeSocketLibrary; +text: .text%__1cDhpiZinitialize_socket_library6F_i_; +text: .text%JVM_Socket; +text: .text%Unsafe_PageSize; +text: .text%__1cNFingerprinterHdo_byte6M_v_: dump.o; +text: .text%__1cXNativeSignatureIteratorHdo_byte6M_v_: interpreterRuntime.o; +text: .text%Unsafe_SetMemory; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: unsafe.o; +text: .text%__1cNSharedRuntimeElrem6Fxx_x_; +text: .text%Unsafe_DefineClass1; +text: .text%__1cSUnsafe_DefineClass6FpnHJNIEnv__pnI_jstring_pnL_jbyteArray_iipnI_jobject_7_pnH_jclass__: unsafe.o; +text: .text%JVM_DefineClass; +text: .text%__1cPClassFileParserXverify_unqualified_name6MpcIi_i_; +text: .text%__1cVLoaderConstraintTableYextend_loader_constraint6MpnVLoaderConstraintEntry_nGHandle_pnMklassOopDesc__v_; +text: .text%__1cVLoaderConstraintTablebHensure_loader_constraint_capacity6MpnVLoaderConstraintEntry_i_v_; +text: .text%__1cIciObjectIis_klass6M_i_: ciInstance.o; +text: .text%__1cQInstanceConstantIencoding6kM_pnI_jobject__; +text: .text%__1cLInstructionOas_ArrayLength6M_pnLArrayLength__: c1_Instruction.o; +text: .text%__1cILIR_ListQunwind_exception6MnFRInfo_1pnMCodeEmitInfo__v_: c1_CodeGenerator.o; +text: .text%__1cIRuntime1Tprimitive_arraycopy6FpnIHeapWord_2i_v_; +text: .text%__1cRComputeEntryStackHdo_char6M_v_: generateOopMap.o; +text: .text%jni_NewDirectByteBuffer; +text: .text%__1cbDinitializeDirectBufferSupport6FpnHJNIEnv___i_: jni.o; +text: .text%lookupDirectBufferClasses: jni.o; +text: .text%__1cJlookupOne6FpnHJNIEnv__pkcpnGThread__pnH_jclass__: jni.o; +text: .text%__1cHJNIEnv_JNewObject6MpnH_jclass_pnK_jmethodID_E_pnI_jobject__: jni.o; +text: .text%jni_GetDoubleArrayRegion: jni.o; +text: .text%__1cNSignatureInfoJdo_double6M_v_: bytecode.o; +text: .text%__1cXJNI_ArgumentPusherVaArgJget_float6M_v_: jni.o; +text: .text%__1cQComputeCallStackHdo_byte6M_v_: generateOopMap.o; +text: .text%__1cFKlassQup_cast_abstract6M_p0_; +text: .text%__1cRComputeEntryStackHdo_byte6M_v_: generateOopMap.o; +text: .text%__1cNSharedRuntimeDd2i6Fd_i_; +text: .text%__1cSInterpreterRuntimeWslow_signature_handler6FpnKJavaThread_pnNmethodOopDesc_pi5_pC_; +text: .text%__1cXNativeSignatureIteratorJdo_object6Mii_v_: interpreterRT_x86.o; +text: .text%__1cUSlowSignatureHandlerLpass_object6M_v_: interpreterRT_x86.o; +text: .text%__1cXNativeSignatureIteratorIdo_array6Mii_v_: interpreterRT_x86.o; +text: .text%__1cXNativeSignatureIteratorGdo_int6M_v_: interpreterRT_x86.o; +text: .text%__1cUSlowSignatureHandlerIpass_int6M_v_: interpreterRT_x86.o; +text: .text%__1cXNativeSignatureIteratorHdo_bool6M_v_: interpreterRT_x86.o; +text: .text%jni_GetFloatArrayRegion: jni.o; +text: .text%jni_GetCharArrayRegion: jni.o; +text: .text%jni_SetFloatField: jni.o; +text: .text%jni_NewFloatArray: jni.o; +text: .text%jni_SetFloatArrayRegion: jni.o; +# SwingSet +text: .text%JVM_GetFieldIxModifiers; +text: .text%JVM_GetCPFieldClassNameUTF; +text: .text%JVM_GetCPFieldModifiers; +text: .text%__1cPClassFileParserUverify_constantvalue6MiinSconstantPoolHandle_pnGThread__v_; +text: .text%__1cXjava_lang_ref_ReferenceOset_discovered6FpnHoopDesc_2_v_; +text: .text%__1cMStoreIndexedPother_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%JVM_MonitorNotify; +text: .text%__1cSObjectSynchronizerGnotify6FnGHandle_pnGThread__v_; +text: .text%__1cKValueStackElock6MpnHIRScope_pnLInstruction__i_; +text: .text%__1cKValueStackGunlock6M_i_; +text: .text%__1cLLIR_EmitterVmonitorenter_at_entry6MnFRInfo_pnMCodeEmitInfo__v_; +text: .text%__1cLLIR_EmitterNmonitor_enter6MnFRInfo_111ipnMCodeEmitInfo_3_v_; +text: .text%__1cQMonitorEnterStub2t6MnFRInfo_1pnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListbAload_stack_address_monitor6MinFRInfo__v_: c1_LIREmitter.o; +text: .text%__1cILIR_ListLlock_object6MnFRInfo_111pnICodeStub_pnMCodeEmitInfo__v_; +text: .text%__1cIValueGenNsyncTempRInfo6F_nFRInfo__; +text: .text%__1cLLIR_EmitterQreturn_op_prolog6Mi_v_; +text: .text%__1cLLIR_EmitterMmonitor_exit6MnFRInfo_11i_v_; +text: .text%__1cILIR_ListNunlock_object6MnFRInfo_11pnICodeStub__v_; +text: .text%__1cKLIR_OpLockFvisit6MpnQLIR_OpVisitState__v_; +text: .text%__1cQMonitorEnterStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; +text: .text%__1cRMonitorAccessStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; +text: .text%__1cKLIR_OpLockJemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerJemit_lock6MpnKLIR_OpLock__v_; +text: .text%__1cNLIR_AssemblerPmonitor_address6MinFRInfo__v_; +text: .text%__1cIFrameMapbEaddress_for_monitor_lock_index6kMi_nHAddress__; +text: .text%__1cIFrameMapbAfp_offset_for_monitor_lock6kMi_i_; +text: .text%__1cNLIR_AssemblerJemit_lock6MpnKLIR_OpLock__v_; +text: .text%__1cRC1_MacroAssemblerLlock_object6MpnMRegisterImpl_22rnFLabel__v_; +text: .text%__1cQMonitorEnterStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; +text: .text%__1cIFrameMapWmonitor_object_regname6kMi_nHOptoRegEName__; +text: .text%__1cIFrameMapbCfp_offset_for_monitor_object6kMi_i_; +text: .text%__1cMCodeEmitInfobHlocation_for_monitor_object_index6Mi_nILocation__; +text: .text%__1cIFrameMapbHlocation_for_monitor_object_index6kMipnILocation__i_; +text: .text%__1cMCodeEmitInfobFlocation_for_monitor_lock_index6Mi_nILocation__; +text: .text%__1cIFrameMapbFlocation_for_monitor_lock_index6kMipnILocation__i_; +text: .text%__1cMMonitorValue2t6MpnKScopeValue_nILocation__v_; +text: .text%__1cMMonitorValueIwrite_on6MpnUDebugInfoWriteStream__v_; +text: .text%__1cRC1_MacroAssemblerNunlock_object6MpnMRegisterImpl_22rnFLabel__v_; +text: .text%__1cPMonitorExitStubMis_call_stub6kM_i_: c1_CodeStubs_x86.o; +text: .text%__1cQMonitorEnterStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%__1cNLIR_AssemblerRload_receiver_reg6MpnMRegisterImpl__v_; +text: .text%__1cNLIR_AssemblerLmonitorexit6MnFRInfo_1pnMRegisterImpl_i3_v_; +text: .text%__1cPMonitorExitStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%jni_NewIntArray: jni.o; +text: .text%__1cNCollectedHeapYlarge_typearray_allocate6FnLKlassHandle_iipnGThread__pnHoopDesc__: typeArrayKlass.o; +text: .text%__1cFKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_: objArrayKlassKlass.o; +text: .text%__1cSobjArrayKlassKlassRoop_oop_iterate_m6MpnHoopDesc_pnKOopClosure_nJMemRegion__i_; +text: .text%__1cQinstanceRefKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_; +text: .text%__1cRTenuredGenerationKshort_name6kM_pkc_: tenuredGeneration.o; +text: .text%__1cKGenerationIcounters6M_pnRCollectorCounters__: tenuredGeneration.o; +text: .text%__1cRTenuredGenerationHcollect6MiiIii_v_; +text: .text%__1cRTenuredGenerationbJretire_alloc_buffers_before_full_gc6M_v_; +text: .text%__1cbCOneContigSpaceCardGenerationHcollect6MiiIii_v_; +text: .text%__1cMGenMarkSweepTinvoke_at_safepoint6FipnSReferenceProcessor_i_v_; +text: .text%__1cJCodeCacheLgc_prologue6F_v_; +text: .text%__1cHThreadsLgc_prologue6F_v_; +text: .text%__1cKJavaThreadLgc_prologue6M_v_; +text: .text%__1cKJavaThreadJframes_do6MpFpnFframe_pknLRegisterMap__v_v_; +text: .text%__1cRframe_gc_prologue6FpnFframe_pknLRegisterMap__v_: thread.o; +text: .text%__1cFframeLgc_prologue6M_v_; +text: .text%__1cQGenCollectedHeapRsave_used_regions6Mii_v_; +text: .text%__1cKGenerationQsave_used_region6M_v_: tenuredGeneration.o; +text: .text%__1cbCOneContigSpaceCardGenerationLused_region6kM_nJMemRegion__; +text: .text%__1cPContiguousSpaceLused_region6kM_nJMemRegion__: space.o; +text: .text%__1cKGenerationQsave_used_region6M_v_: defNewGeneration.o; +text: .text%__1cKGenerationLused_region6kM_nJMemRegion__: defNewGeneration.o; +text: .text%__1cKGenerationQsave_used_region6M_v_: compactingPermGenGen.o; +text: .text%__1cMGenMarkSweepPallocate_stacks6F_v_; +text: .text%__1cQGenCollectedHeapOgather_scratch6MpnKGeneration_I_pnMScratchBlock__; +text: .text%__1cQDefNewGenerationScontribute_scratch6MrpnMScratchBlock_pnKGeneration_I_v_; +text: .text%__1cKGenerationScontribute_scratch6MrpnMScratchBlock_p0I_v_: tenuredGeneration.o; +text: .text%__1cRsort_scratch_list6FrpnMScratchBlock__v_: genCollectedHeap.o; +text: .text%__1cVremoveSmallestScratch6FppnMScratchBlock__1_: genCollectedHeap.o; +text: .text%__1cMGenMarkSweepRmark_sweep_phase16Firii_v_; +text: .text%__1cJEventMark2t6MpkcE_v_: genMarkSweep.o; +text: .text%__1cJMarkSweepRFollowRootClosureGdo_oop6MppnHoopDesc__v_: markSweep.o; +text: .text%__1cJMarkSweepLfollow_root6FppnHoopDesc__v_; +text: .text%__1cParrayKlassKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cLklassVtableToop_follow_contents6M_v_; +text: .text%__1cJMarkSweepO_mark_and_push6FppnHoopDesc__v_; +text: .text%__1cKklassKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cJMarkSweepXrevisit_weak_klass_link6FpnFKlass__v_; +text: .text%__1cJMarkSweepMfollow_stack6F_v_; +text: .text%__1cNinstanceKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cSinstanceKlassKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cNinstanceKlassUfollow_static_fields6M_v_; +text: .text%__1cLklassItableToop_follow_contents6M_v_; +text: .text%__1cJMarkSweepNpreserve_mark6FpnHoopDesc_pnLmarkOopDesc__v_; +text: .text%__1cLsymbolKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cOtypeArrayKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cMjniIdMapBaseHoops_do6MpnKOopClosure__v_; +text: .text%__1cIjniIdMapHoops_do6MpnKOopClosure__v_; +text: .text%__1cJMarkSweepSMarkAndPushClosureGdo_oop6MppnHoopDesc__v_: markSweep.o; +text: .text%__1cNobjArrayKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cJMarkSweepPmark_and_follow6FppnHoopDesc__v_; +text: .text%__1cSobjArrayKlassKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cRconstantPoolKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cWconstantPoolCacheKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cWConstantPoolCacheEntryPfollow_contents6M_v_; +text: .text%__1cLmethodKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cQconstMethodKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cQinstanceRefKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cFJNIidHoops_do6MpnKOopClosure__v_; +text: .text%__1cQSystemDictionaryValways_strong_oops_do6FpnKOopClosure__v_; +text: .text%__1cQSystemDictionaryYalways_strong_classes_do6FpnKOopClosure__v_; +text: .text%__1cKDictionaryYalways_strong_classes_do6MpnKOopClosure__v_; +text: .text%__1cQSystemDictionaryPplaceholders_do6FpnKOopClosure__v_; +text: .text%__1cVLoaderConstraintTableYalways_strong_classes_do6MpnKOopClosure__v_; +text: .text%__1cJvmSymbolsHoops_do6FpnKOopClosure_i_v_; +text: .text%__1cJMarkSweepOIsAliveClosureLdo_object_b6MpnHoopDesc__i_: markSweep.o; +text: .text%__1cJMarkSweepQKeepAliveClosureGdo_oop6MppnHoopDesc__v_; +text: .text%__1cJMarkSweepSFollowStackClosureHdo_void6M_v_: markSweep.o; +text: .text%__1cQSystemDictionaryMdo_unloading6FpnRBoolObjectClosure_pnKOopClosure__i_; +text: .text%__1cKDictionaryMdo_unloading6MpnRBoolObjectClosure_pnKOopClosure__i_; +text: .text%__1cVLoaderConstraintTableYpurge_loader_constraints6MpnRBoolObjectClosure__v_; +text: .text%__1cJCodeCacheMdo_unloading6FpnRBoolObjectClosure_pnKOopClosure_iri_v_; +text: .text%__1cJCodeCacheFfirst6F_pnICodeBlob__; +text: .text%__1cICodeHeapLfirst_block6kM_pnJHeapBlock__; +text: .text%__1cICodeHeapJnext_free6kMpnJHeapBlock__pv_; +text: .text%__1cJCodeCacheFalive6FpnICodeBlob__2_; +text: .text%__1cKBufferBlobIis_alive6kM_i_: codeBlob.o; +text: .text%__1cKBufferBlobbIfollow_roots_or_mark_for_unloading6MpnRBoolObjectClosure_pnKOopClosure_iri_v_: codeBlob.o; +text: .text%__1cJCodeCacheEnext6FpnICodeBlob__2_; +text: .text%__1cICodeHeapLblock_start6kMpv_pnJHeapBlock__; +text: .text%__1cICodeHeapKnext_block6kMpnJHeapBlock__2_; +text: .text%__1cNSingletonBlobIis_alive6kM_i_: codeBlob.o; +text: .text%__1cNSingletonBlobbIfollow_roots_or_mark_for_unloading6MpnRBoolObjectClosure_pnKOopClosure_iri_v_: codeBlob.o; +text: .text%__1cLRuntimeStubIis_alive6kM_i_: codeBlob.o; +text: .text%__1cLRuntimeStubbIfollow_roots_or_mark_for_unloading6MpnRBoolObjectClosure_pnKOopClosure_iri_v_: codeBlob.o; +text: .text%__1cHnmethodIis_alive6kM_i_: nmethod.o; +text: .text%__1cHnmethodbIfollow_roots_or_mark_for_unloading6MpnRBoolObjectClosure_pnKOopClosure_iri_v_; +text: .text%__1cHnmethodOis_not_entrant6kM_i_: nmethod.o; +text: .text%__1cHnmethodbHfollow_root_or_mark_for_unloading6MpnRBoolObjectClosure_pnKOopClosure_ppnHoopDesc_iri_v_; +text: .text%__1cOoop_RelocationJoop_value6M_pnHoopDesc__; +text: .text%__1cVcompiledICHolderKlassSoop_being_unloaded6MpnRBoolObjectClosure_pnHoopDesc__i_; +text: .text%__1cVcompiledICHolderKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cJMarkSweepXfollow_weak_klass_links6F_v_; +text: .text%__1cFKlassXfollow_weak_klass_links6MpnRBoolObjectClosure_pnKOopClosure__v_; +text: .text%__1cNinstanceKlassXfollow_weak_klass_links6MpnRBoolObjectClosure_pnKOopClosure__v_; +text: .text%__1cJHashtableGunlink6MpnRBoolObjectClosure__v_; +text: .text%__1cMGenMarkSweepRmark_sweep_phase26F_v_; +text: .text%__1cQGenCollectedHeapWprepare_for_compaction6M_v_; +text: .text%__1cKGenerationWprepare_for_compaction6MpnMCompactPoint__v_; +text: .text%__1cbCOneContigSpaceCardGenerationWfirst_compaction_space6kM_pnQCompactibleSpace__: tenuredGeneration.o; +text: .text%__1cPContiguousSpaceWprepare_for_compaction6MpnMCompactPoint__v_; +text: .text%__1cWOffsetTableContigSpaceUinitialize_threshold6M_pnIHeapWord__; +text: .text%__1cMTenuredSpaceSallowed_dead_ratio6kM_i_; +text: .text%__1cQCompactibleSpaceHforward6MpnHoopDesc_IpnMCompactPoint_pnIHeapWord__6_; +text: .text%__1cWOffsetTableContigSpacePcross_threshold6MpnIHeapWord_2_2_; +text: .text%__1cQCompactibleSpaceQinsert_deadspace6MrIpnIHeapWord_I_i_; +text: .text%__1cQCompactibleSpaceVnext_compaction_space6kM_p0_: space.o; +text: .text%__1cQDefNewGenerationWfirst_compaction_space6kM_pnQCompactibleSpace__: defNewGeneration.o; +text: .text%__1cQCompactibleSpaceSallowed_dead_ratio6kM_i_: space.o; +text: .text%__1cbCOneContigSpaceCardGenerationWfirst_compaction_space6kM_pnQCompactibleSpace__: compactingPermGenGen.o; +text: .text%__1cPContigPermSpaceSallowed_dead_ratio6kM_i_; +text: .text%__1cMGenMarkSweepRmark_sweep_phase36Fi_v_; +text: .text%__1cUCompactingPermGenGenTpre_adjust_pointers6M_v_; +text: .text%__1cJMarkSweepUAdjustPointerClosureGdo_oop6MppnHoopDesc__v_: markSweep.o; +text: .text%__1cQGenCollectedHeapSprocess_weak_roots6MpnKOopClosure_2_v_; +text: .text%__1cJCodeCacheHoops_do6FpnKOopClosure__v_; +text: .text%__1cKBufferBlobHoops_do6MpnKOopClosure__v_: codeBlob.o; +text: .text%__1cSDeoptimizationBlobHoops_do6MpnKOopClosure__v_: codeBlob.o; +text: .text%__1cLRuntimeStubHoops_do6MpnKOopClosure__v_: codeBlob.o; +text: .text%__1cNSafepointBlobHoops_do6MpnKOopClosure__v_: codeBlob.o; +text: .text%__1cHnmethodHoops_do6MpnKOopClosure__v_; +text: .text%__1cJHashtableHoops_do6MpnKOopClosure__v_; +text: .text%__1cSReferenceProcessorPoops_do_statics6FpnKOopClosure__v_; +text: .text%__1cSReferenceProcessorHoops_do6MpnKOopClosure__v_; +text: .text%__1cJMarkSweepMadjust_marks6F_v_; +text: .text%__1cYGenAdjustPointersClosureNdo_generation6MpnKGeneration__v_: genMarkSweep.o; +text: .text%__1cKGenerationPadjust_pointers6M_v_; +text: .text%__1cbCOneContigSpaceCardGenerationNspace_iterate6MpnMSpaceClosure_i_v_; +text: .text%__1cVAdjustPointersClosureIdo_space6MpnFSpace__v_: generation.o; +text: .text%__1cQCompactibleSpacePadjust_pointers6M_v_; +text: .text%__1cOtypeArrayKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cNobjArrayKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cQinstanceRefKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cNinstanceKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cQDefNewGenerationNspace_iterate6MpnMSpaceClosure_i_v_; +text: .text%__1cUCompactingPermGenGenPadjust_pointers6M_v_; +text: .text%__1cKklassKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cLsymbolKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cParrayKlassKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cLklassVtableToop_adjust_pointers6M_v_; +text: .text%__1cSobjArrayKlassKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cRconstantPoolKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cQconstMethodKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cLmethodKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cSinstanceKlassKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cNinstanceKlassUadjust_static_fields6M_v_; +text: .text%__1cLklassItableToop_adjust_pointers6M_v_; +text: .text%__1cWconstantPoolCacheKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cWConstantPoolCacheEntryPadjust_pointers6M_v_; +text: .text%__1cVcompiledICHolderKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cMGenMarkSweepRmark_sweep_phase46F_v_; +text: .text%__1cUCompactingPermGenGenHcompact6M_v_; +text: .text%__1cQCompactibleSpaceHcompact6M_v_; +text: .text%__1cPContiguousSpaceWreset_after_compaction6M_v_: space.o; +text: .text%__1cRGenCompactClosureNdo_generation6MpnKGeneration__v_: genMarkSweep.o; +text: .text%__1cKGenerationHcompact6M_v_; +text: .text%__1cUCompactingPermGenGenMpost_compact6M_v_; +text: .text%__1cJMarkSweepNrestore_marks6F_v_; +text: .text%__1cMGenMarkSweepRdeallocate_stacks6F_v_; +text: .text%__1cLCardTableRSSclear_into_younger6MpnKGeneration_i_v_; +text: .text%__1cLCardTableRSFclear6MnJMemRegion__v_: cardTableRS.o; +text: .text%__1cRCardTableModRefBSFclear6MnJMemRegion__v_; +text: .text%__1cRCardTableModRefBSPclear_MemRegion6MnJMemRegion__v_; +text: .text%__1cHThreadsLgc_epilogue6F_v_; +text: .text%__1cKJavaThreadLgc_epilogue6M_v_; +text: .text%__1cRframe_gc_epilogue6FpnFframe_pknLRegisterMap__v_: thread.o; +text: .text%__1cFframeLgc_epilogue6M_v_; +text: .text%__1cFframeMpd_gc_epilog6M_v_; +text: .text%__1cJCodeCacheLgc_epilogue6F_v_; +text: .text%__1cICodeBlobTfix_oop_relocations6M_v_; +text: .text%__1cICodeBlobTfix_oop_relocations6MpC1_v_; +text: .text%__1cKRelocationSfix_oop_relocation6M_v_: codeBlob.o; +text: .text%__1cKRelocationSfix_oop_relocation6M_v_: relocInfo.o; +text: .text%__1cICodeBlobKis_nmethod6kM_i_: onStackReplacement.o; +text: .text%__1cQGenCollectedHeapWupdate_time_of_last_gc6Mx_v_: genMarkSweep.o; +text: .text%__1cKGenerationWupdate_time_of_last_gc6Mx_v_: tenuredGeneration.o; +text: .text%__1cKGenerationWupdate_time_of_last_gc6Mx_v_: compactingPermGenGen.o; +text: .text%__1cbCOneContigSpaceCardGenerationVunsafe_max_alloc_nogc6kM_I_; +text: .text%__1cRTenuredGenerationQcompute_new_size6M_v_; +text: .text%__1cKGenerationEspec6M_pnOGenerationSpec__; +text: .text%Unsafe_CompareAndSwapObject; +text: .text%__1cLVtableStubsScreate_itable_stub6Fii_pnKVtableStub__; +text: .text%__1cLLIR_EmitterDnop6M_v_; +text: .text%__1cJAssemblerEmovl6MnHAddress_pnI_jobject__v_; +text: .text%__1cMLinkResolverbEvtable_index_of_miranda_method6FnLKlassHandle_nMsymbolHandle_2pnGThread__i_; +text: .text%__1cLklassVtableQindex_of_miranda6MpnNsymbolOopDesc_2_i_; +text: .text%__1cLklassVtableTis_miranda_entry_at6Mi_i_; +text: .text%__1cRPrivilegedElementHoops_do6MpnKOopClosure__v_; +text: .text%__1cJCodeCacheIcontains6Fpv_i_; +text: .text%__1cFframeRoops_code_blob_do6MpnKOopClosure_pknLRegisterMap__v_; +text: .text%__1cJOopMapSetHoops_do6FpknFframe_pnICodeBlob_pknLRegisterMap_pnKOopClosure__v_; +text: .text%__1cJOopMapSetGall_do6FpknFframe_pnICodeBlob_pknLRegisterMap_pnKOopClosure_pFppnHoopDesc_9E_v9B9B_v_; +text: .text%__1cICodeBlobbAoop_map_for_return_address6MpCi_pnGOopMap__; +text: .text%__1cJOopMapSetSfind_map_at_offset6kMii_pnGOopMap__; +text: .text%__1cMOopMapStream2t6MpnGOopMap_i_v_; +text: .text%__1cFframeVoopmapreg_to_location6kMnFVMRegEName_pknLRegisterMap__ppnHoopDesc__; +text: .text%__1cKOopClosureLdo_nmethods6kM_ki_: defNewGeneration.o; +text: .text%__1cJOopMapSetTupdate_register_map6FpknFframe_pnICodeBlob_pnLRegisterMap__v_; +text: .text%__1cICodeBlobYcaller_must_gc_arguments6kMpnKJavaThread__i_: nmethod.o; +text: .text%__1cQComputeCallStackIdo_float6M_v_: generateOopMap.o; +text: .text%jni_DeleteWeakGlobalRef: jni.o; +text: .text%__1cKJNIHandlesTdestroy_weak_global6FpnI_jobject__v_; +text: .text%__1cILIR_ListJoop2stack6MpnI_jobject_i_v_: c1_LIREmitter.o; +text: .text%__1cNObjectMonitorREntryQdDueue_unlink6MpnMObjectWaiter__v_; +text: .text%JVM_IsSameClassPackage; +text: .text%__1cTGeneratePairingInfoRpossible_gc_point6MpnOBytecodeStream__i_: ciMethod.o; +text: .text%__1cTGeneratePairingInfoOreport_results6kM_i_: ciMethod.o; +text: .text%__1cMGraphBuilderMmonitorenter6MpnLInstruction__v_; +text: .text%__1cMMonitorEnterFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerPdo_MonitorEnter6MpnMMonitorEnter__v_; +text: .text%__1cNAccessMonitorIcan_trap6kM_i_: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderLmonitorexit6MpnLInstruction__v_; +text: .text%__1cLMonitorExitFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerOdo_MonitorExit6MpnLMonitorExit__v_; +text: .text%__1cILongTypeDtag6kM_nIValueTag__: c1_Canonicalizer.o; +text: .text%__1cILongTypeEsize6kM_i_: c1_Canonicalizer.o; +text: .text%__1cNAccessMonitorPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorPdo_MonitorEnter6MpnMMonitorEnter__v_; +text: .text%__1cTNullCheckEliminatorUhandle_AccessMonitor6MpnNAccessMonitor__v_; +text: .text%__1cQNullCheckVisitorOdo_MonitorExit6MpnLMonitorExit__v_; +text: .text%__1cIValueGenPdo_MonitorEnter6MpnMMonitorEnter__v_; +text: .text%__1cNc1_AllocTableMhas_two_free6kM_i_; +text: .text%__1cMLongConstantPas_LongConstant6M_p0_: c1_Canonicalizer.o; +text: .text%__1cFRInfoLas_rinfo_lo6kM_0_; +text: .text%__1cLLIR_EmitterJopr2intLo6MpnLLIR_OprDesc__i_; +text: .text%__1cFRInfoLas_rinfo_hi6kM_0_; +text: .text%__1cLLIR_EmitterJopr2intHi6MpnLLIR_OprDesc__i_; +text: .text%__1cIValueGenOdo_MonitorExit6MpnLMonitorExit__v_; +text: .text%__1cNAccessMonitorQas_AccessMonitor6M_p0_: c1_GraphBuilder.o; +text: .text%__1cJAssemblerFpushl6MpnI_jobject__v_; +text: .text%__1cNLIR_AssemblerNas_Address_hi6MpnLLIR_Address__nHAddress__; +text: .text%__1cFRInfoOas_register_hi6kM_pnMRegisterImpl__; +text: .text%__1cNLIR_AssemblerNas_Address_lo6MpnLLIR_Address__nHAddress__; +text: .text%__1cFRInfoOas_register_lo6kM_pnMRegisterImpl__; +text: .text%__1cCosHrealloc6FpvI_1_; +text: .text%Unsafe_GetNativeFloat; +text: .text%__1cIValueGenQdo_currentThread6MpnJIntrinsic__v_; +text: .text%__1cILIR_ListKget_thread6MnFRInfo__v_: c1_CodeGenerator_x86.o; +text: .text%__1cNLIR_AssemblerKget_thread6MpnLLIR_OprDesc__v_; +text: .text%__1cIValueGenSload_item_patching6MpnHIRScope_ipnEItem_pnKValueStack_pnOExceptionScope__v_; +text: .text%__1cEItemUget_jobject_constant6kM_pnIciObject__; +text: .text%__1cJValueTypeTas_InstanceConstant6M_pnQInstanceConstant__: c1_ValueType.o; +text: .text%__1cIintArrayIindex_of6kMki_i_: c1_CodeGenerator.o; +text: .text%__1cMLinkResolverbEresolve_interface_call_or_null6FnLKlassHandle_1nMsymbolHandle_21_nMmethodHandle__; +text: .text%__1cIciObjectTis_type_array_klass6M_i_: ciInstanceKlass.o; +text: .text%__1cGciTypeNis_subtype_of6Mp0_i_; +text: .text%__1cIValueGenOload_byte_item6MpnEItem__v_; +text: .text%__1cIValueGenPlock_free_rinfo6MpnLInstruction_nKc1_RegMask__nFRInfo__; +text: .text%__1cIRegAllocNget_lock_temp6MpnLInstruction_nKc1_RegMask__nFRInfo__; +text: .text%__1cQComputeCallStackIdo_short6M_v_: generateOopMap.o; +text: .text%__1cRComputeEntryStackIdo_short6M_v_: generateOopMap.o; +text: .text%__1cIFrameMapNis_byte_rinfo6FnFRInfo__i_; +text: .text%Unsafe_AllocateInstance; +text: .text%jni_AllocObject: jni.o; +text: .text%__1cQinstanceRefKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_; +text: .text%__1cNCanonicalizerMset_constant6Mi_v_: c1_Canonicalizer.o; +text: .text%__1cJTypeCheckPother_values_do6MpFppnLInstruction__v_v_; +text: .text%__1cNLIR_AssemblerMcheck_icache6M_i_; +text: .text%__1cRC1_MacroAssemblerTfast_ObjectHashCode6MpnMRegisterImpl_2_v_; +text: .text%__1cNLIR_AssemblerZjobject2reg_with_patching6MpnMRegisterImpl_pnMCodeEmitInfo__v_; +text: .text%__1cHLogicOpIis_equal6kMpnLInstruction__i_: c1_Instruction.o; +text: .text%__1cLAccessFieldKlock_stack6kM_pnKValueStack__: c1_GraphBuilder.o; +text: .text%__1cIRuntime1Mnew_instance6FpnKJavaThread_pnMklassOopDesc__v_; +text: .text%__1cQGenCollectedHeapXhandle_failed_promotion6MpnKGeneration_pnHoopDesc_Ip4_4_; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: instanceRefKlass.o; +text: .text%__1cbCOneContigSpaceCardGenerationTexpand_and_allocate6MIiii_pnIHeapWord__; +text: .text%__1cbCOneContigSpaceCardGenerationGexpand6MII_v_; +text: .text%__1cNGCMutexLocker2t6MpnFMutex__v_; +text: .text%__1cbCOneContigSpaceCardGenerationHgrow_by6MI_i_; +text: .text%__1cPContiguousSpaceNmangle_region6MnJMemRegion__v_; +text: .text%__1cJMarkSweepRFollowRootClosureLdo_nmethods6kM_ki_: markSweep.o; +text: .text%__1cQCompactibleSpaceUinitialize_threshold6M_pnIHeapWord__: space.o; +text: .text%__1cKOopClosureLdo_nmethods6kM_ki_: markSweep.o; +text: .text%__1cRAlwaysTrueClosureLdo_object_b6MpnHoopDesc__i_: genCollectedHeap.o; +text: .text%__1cLCardTableRSTinvalidate_or_clear6MpnKGeneration_ii_v_; +text: .text%__1cJMemRegionFminus6kMk0_0_; +text: .text%__1cLCardTableRSKinvalidate6MnJMemRegion__v_: cardTableRS.o; +text: .text%__1cRCardTableModRefBSKinvalidate6MnJMemRegion__v_; +text: .text%__1cIRuntime1Onew_type_array6FpnKJavaThread_pnMklassOopDesc_i_v_; +text: .text%__1cJFloatTypeDtag6kM_nIValueTag__: c1_Canonicalizer.o; +text: .text%__1cNFloatConstantQas_FloatConstant6M_p0_: c1_Canonicalizer.o; +text: .text%__1cILIR_ListNstore_mem_oop6MpnI_jobject_nFRInfo_inJBasicType_pnMCodeEmitInfo_nHLIR_Op1NLIR_PatchCode__v_; +text: .text%__1cJFloatTypeMas_FloatType6M_p0_: c1_Canonicalizer.o; +text: .text%__1cNConstantTableMappend_float6Mf_v_; +text: .text%__1cRAbstractAssemblerGa_long6Mi_v_; +text: .text%__1cNObjectMonitorGnotify6MpnGThread__v_; +text: .text%__1cDCHARprocess_interface6FnTinstanceKlassHandle_pnNGrowableArray4nLKlassHandle___pnNGrowableArray4nMmethodHandle___nMsymbolHandle_6_v_; +text: .text%__1cINewArrayPother_values_do6MpFppnLInstruction__v_v_; +text: .text%__1cLLIR_EmitterQfield_store_byte6MpnLLIR_OprDesc_i2nFRInfo_ipnMCodeEmitInfo__v_; +text: .text%__1cNLIR_AssemblerIshift_op6MnILIR_Code_nFRInfo_222_v_; +text: .text%__1cIRuntime1Mmonitorenter6FpnKJavaThread_pnHoopDesc_pnPBasicObjectLock__v_; +text: .text%__1cIRuntime1Lmonitorexit6FpnKJavaThread_pnPBasicObjectLock__v_; +text: .text%__1cHnmethodPis_dependent_on6MpnMklassOopDesc__i_; +text: .text%__1cHnmethodVis_dependent_on_entry6MpnMklassOopDesc_2pnNmethodOopDesc__i_; +text: .text%__1cNVM_DeoptimizeEname6kM_pkc_: vm_operations.o; +text: .text%__1cNVM_DeoptimizeEdoit6M_v_; +text: .text%__1cODeoptimizationVdeoptimize_dependents6F_i_; +text: .text%__1cHThreadsbFdeoptimized_wrt_marked_nmethods6F_v_; +text: .text%__1cKJavaThreadbFdeoptimized_wrt_marked_nmethods6M_v_; +text: .text%__1cFframeVshould_be_deoptimized6kM_i_; +text: .text%__1cICodeBlobOis_java_method6kM_i_: codeBlob.o; +text: .text%__1cJCodeCachebGmake_marked_nmethods_not_entrant6F_v_; +text: .text%__1cJCodeCacheNalive_nmethod6FpnICodeBlob__pnHnmethod__; +text: .text%__1cHnmethodbAmake_not_entrant_or_zombie6Mi_v_; +text: .text%__1cHnmethodNis_osr_method6kM_i_: nmethod.o; +text: .text%__1cKNativeJumpUpatch_verified_entry6FpC11_v_; +text: .text%__1cHnmethodVmark_as_seen_on_stack6M_v_; +text: .text%__1cTinc_decompile_count6FpnHnmethod__v_: nmethod.o; +text: .text%__1cMVM_OperationNdoit_epilogue6M_v_: vm_operations.o; +text: .text%__1cHThreadsLnmethods_do6F_v_; +text: .text%__1cKJavaThreadLnmethods_do6M_v_; +text: .text%__1cGThreadLnmethods_do6M_v_; +text: .text%__1cFframeLnmethods_do6M_v_; +text: .text%__1cFframeVnmethods_code_blob_do6M_v_; +text: .text%__1cILIR_ListEidiv6MnFRInfo_i11pnMCodeEmitInfo__v_; +text: .text%__1cLlog2_intptr6Fi_i_: c1_LIRAssembler_x86.o; +text: .text%__1cONMethodSweeperPprocess_nmethod6FpnHnmethod__v_; +text: .text%__1cHnmethodPis_locked_by_vm6kM_i_: nmethod.o; +text: .text%__1cHnmethodLis_unloaded6kM_i_: nmethod.o; +text: .text%__1cHnmethodVcleanup_inline_caches6M_v_; +text: .text%__1cKCompiledIC2t6MpnKRelocation__v_; +text: .text%__1cILongTypeDtag6kM_nIValueTag__: c1_ValueType.o; +text: .text%__1cILongTypeEsize6kM_i_: c1_ValueType.o; +text: .text%JVM_HoldsLock; +text: .text%__1cSObjectSynchronizerZcurrent_thread_holds_lock6FpnKJavaThread_nGHandle__i_; +text: .text%__1cIciObjectRis_instance_klass6M_i_: ciObjArrayKlass.o; +text: .text%__1cLLoadIndexedIis_equal6kMpnLInstruction__i_: c1_Instruction.o; +text: .text%__1cFciEnvWis_dependence_violated6FpnMklassOopDesc_pnNmethodOopDesc__i_; +text: .text%__1cFciEnvZcall_has_multiple_targets6FpnNinstanceKlass_nMsymbolHandle_3ri_i_; +text: .text%__1cFMutexbLwait_for_lock_blocking_implementation6MpnKJavaThread__v_; +text: .text%__1cHnmethodbCcan_not_entrant_be_converted6M_i_; +text: .text%__1cXNativeSignatureIteratorHdo_bool6M_v_: oopMapCache.o; +text: .text%__1cTMaskFillerForNativeIpass_int6M_v_: oopMapCache.o; +text: .text%__1cGThreadOis_Java_thread6kM_i_: vmThread.o; +text: .text%__1cMLocalMappingDadd6MinFRInfo__v_; +text: .text%__1cILongTypeEbase6kM_pnJValueType__: c1_ValueType.o; +text: .text%__1cLLIR_EmitterQfield_store_long6MpnLLIR_OprDesc_i2ipnMCodeEmitInfo__v_; +text: .text%__1cKScanBlocksMis_long_only6kMi_i_; +text: .text%__1cRLIR_PeepholeStateLreg2indexLo6MpnLLIR_OprDesc__i_; +text: .text%__1cRLIR_PeepholeStateLreg2indexHi6MpnLLIR_OprDesc__i_; +text: .text%__1cNSharedRuntimeDf2l6Ff_x_; +text: .text%__1cIValueGenLdo_getClass6MpnJIntrinsic__v_; +text: .text%__1cLLIR_EmitterIgetClass6MnFRInfo_1pnMCodeEmitInfo__v_; +text: .text%__1cMGraphBuilderKcompare_op6MpnJValueType_nJBytecodesECode__v_; +text: .text%__1cJCompareOpFvisit6MpnSInstructionVisitor__v_: c1_Instruction.o; +text: .text%__1cNCanonicalizerMdo_CompareOp6MpnJCompareOp__v_; +text: .text%__1cJCompareOpEhash6kM_i_: c1_Instruction.o; +text: .text%__1cJCompareOpEname6kM_pkc_: c1_Instruction.o; +text: .text%__1cJCompareOpMas_CompareOp6M_p0_: c1_Instruction.o; +text: .text%__1cCIf2t6MpnLInstruction_n0BJCondition_i2pnKBlockBegin_5pnKValueStack_i_v_: c1_Canonicalizer.o; +text: .text%__1cGSetRegIdo_float6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIRegAllocLset_fpu_reg6MiipnLInstruction__v_; +text: .text%__1cJIsFreeRegIdo_float6Mi_v_: c1_RegAlloc.o; +text: .text%__1cILIR_ListJfloat2reg6MfnFRInfo__v_: c1_LIREmitter.o; +text: .text%__1cILIR_ListMbranch_float6MnMLIR_OpBranchNLIR_Condition_pnFLabel_4_v_; +text: .text%__1cIValueGenNreturnF0RInfo6F_nFRInfo__; +text: .text%__1cLLIR_EmitterOset_fpu_result6MnFRInfo__v_; +text: .text%__1cILIR_ListIpush_fpu6MnFRInfo__v_: c1_LIREmitter.o; +text: .text%__1cNConstantTableZaddress_of_float_constant6Mf_pC_; +text: .text%__1cNLIR_AssemblerOfpu_two_on_tos6MnFRInfo_1i_v_; +text: .text%__1cIFrameMapLFpuStackSimEswap6M_v_; +text: .text%__1cIFrameMapLFpuStackSimRexchange_with_tos6Mi_v_; +text: .text%__1cHnmethodSflush_dependencies6MpnRBoolObjectClosure__v_; +text: .text%__1cNinstanceKlassYremove_dependent_nmethod6MpnHnmethod__v_; +text: .text%__1cFVTuneOdelete_nmethod6FpnHnmethod__v_; +text: .text%__1cQPlaceholderEntryHoops_do6MpnKOopClosure__v_; +text: .text%__1cHnmethodFflush6M_v_; +text: .text%__1cJEventMark2t6MpkcE_v_: nmethod.o; +text: .text%__1cICodeBlobFflush6M_v_; +text: .text%__1cJCodeCacheEfree6FpnICodeBlob__v_; +text: .text%__1cICodeHeapKdeallocate6Mpv_v_; +text: .text%__1cICodeHeapPadd_to_freelist6MpnJHeapBlock__v_; +text: .text%__1cICodeHeapPfollowing_block6MpnJFreeBlock__2_; +text: .text%__1cRComputeEntryStackIdo_float6M_v_: generateOopMap.o; +text: .text%__1cICodeHeapMinsert_after6MpnJFreeBlock_2_v_; +text: .text%__1cICodeHeapLmerge_right6MpnJFreeBlock__v_; +text: .text%__1cHnmethodbDpreserve_callee_argument_oops6MnFframe_pknLRegisterMap_pnKOopClosure__v_; +text: .text%__1cUCompressedReadStreamMraw_read_int6FrpC_i_: nmethod.o; +text: .text%__1cFframebAoops_compiled_arguments_do6MnMsymbolHandle_ipknLRegisterMap_pnKOopClosure__v_; +text: .text%__1cQComputeCallStackJdo_double6M_v_: generateOopMap.o; +text: .text%__1cbCOneContigSpaceCardGenerationGshrink6MI_v_; +text: .text%__1cbCOneContigSpaceCardGenerationJshrink_by6MI_v_; +text: .text%__1cMVirtualSpaceJshrink_by6MI_v_; +text: .text%__1cXNativeSignatureIteratorGdo_int6M_v_: oopMapCache.o; +text: .text%__1cRComputeEntryStackJdo_double6M_v_: generateOopMap.o; +text: .text%__1cKDoubleTypeDtag6kM_nIValueTag__: c1_ValueType.o; +text: .text%__1cKDoubleTypeDtag6kM_nIValueTag__: c1_Canonicalizer.o; +text: .text%__1cODoubleConstantRas_DoubleConstant6M_p0_: c1_Canonicalizer.o; +text: .text%__1cKDoubleTypeEbase6kM_pnJValueType__: c1_ValueType.o; +text: .text%__1cODoubleConstantLis_constant6kM_i_: c1_Canonicalizer.o; +text: .text%__1cKDoubleTypeEsize6kM_i_: c1_ValueType.o; +text: .text%__1cHLockRegJdo_double6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIRegAllocRset_locked_double6MipnLInstruction_i_v_; +text: .text%__1cKDoubleTypeNas_DoubleType6M_p0_: c1_ValueType.o; +text: .text%__1cIFrameMapUare_adjacent_indeces6kMii_i_; +text: .text%__1cQChangeSpillCountJdo_double6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIRegAllocZchange_double_spill_count6Mii_v_; +text: .text%__1cILIR_ListKdouble2reg6MdnFRInfo__v_: c1_LIREmitter.o; +text: .text%__1cHFreeRegJdo_double6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIRegAllocPset_free_double6Mi_v_; +text: .text%__1cILIR_ListDrem6MpnLLIR_OprDesc_22pnMCodeEmitInfo__v_: c1_LIREmitter.o; +text: .text%__1cLGetRefCountJdo_double6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIRegAllocNget_double_rc6kMi_i_; +text: .text%__1cLLIR_EmitterUcheck_double_address6Mi_v_; +text: .text%__1cILIR_ListQreg2double_stack6MnFRInfo_inJBasicType__v_: c1_LIREmitter.o; +text: .text%__1cRLIR_PeepholeStateNstack2indexHi6MpnLLIR_OprDesc__i_; +text: .text%__1cRLIR_PeepholeStateNstack2indexLo6MpnLLIR_OprDesc__i_; +text: .text%__1cKDoubleTypeNas_DoubleType6M_p0_: c1_Canonicalizer.o; +text: .text%__1cNConstantTableNappend_double6Md_v_; +text: .text%__1cNConstantTablebAaddress_of_double_constant6Md_pC_; +text: .text%__1cQGenCollectedHeapHcollect6MnHGCCauseFCause_i_v_; +text: .text%__1cQGenCollectedHeapOcollect_locked6MnHGCCauseFCause_i_v_; +text: .text%__1cRVM_GenCollectFullEname6kM_pkc_: vm_operations.o; +text: .text%__1cRVM_GenCollectFullEdoit6M_v_; +text: .text%__1cQGenCollectedHeapYmust_clear_all_soft_refs6M_i_; +text: .text%__1cQGenCollectedHeapSdo_full_collection6Miipi_v_; +text: .text%__1cKGenerationbHfull_collects_younger_generations6kM_i_: defNewGeneration.o; +text: .text%__1cKDoubleTypeEsize6kM_i_: c1_Canonicalizer.o; +text: .text%__1cKDoubleTypeEbase6kM_pnJValueType__: c1_Canonicalizer.o; +text: .text%__1cIValueMapNresize_bucket6MpnGBucket__v_; +text: .text%__1cNFloatConstantLis_constant6kM_i_: c1_Canonicalizer.o; +text: .text%__1cJNullCheckMas_NullCheck6M_p0_: c1_GraphBuilder.o; +text: .text%__1cLLIR_EmitterIopr2long6MpnLLIR_OprDesc__x_; +text: .text%__1cILIR_ListKlong2stack6Mxi_v_: c1_LIREmitter.o; +text: .text%__1cIValueGenNreturnD0RInfo6F_nFRInfo__; +text: .text%__1cJIsFreeRegJdo_double6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIRegAllocOis_free_double6kMi_i_; +text: .text%__1cGSetRegJdo_double6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIRegAllocOset_double_reg6MiipnLInstruction__v_; +text: .text%__1cLLIR_EmitterNcopy_fpu_item6MnFRInfo_pnLLIR_OprDesc__v_; +text: .text%__1cILIR_ListHdup_fpu6MnFRInfo_1_v_: c1_LIREmitter.o; +text: .text%__1cILIR_ListDdiv6MpnLLIR_OprDesc_22pnMCodeEmitInfo__v_: c1_LIREmitter.o; +text: .text%__1cJAssemblerFfsubp6Mi_v_; +text: .text%__1cNLIR_AssemblerHdup_fpu6MnFRInfo_1_v_; +text: .text%__1cIFrameMapLFpuStackSimLmove_on_tos6Mi_i_; +text: .text%__1cJAssemblerGfdiv_d6MnHAddress__v_; +text: .text%__1cJAssemblerFfdivp6Mi_v_; +text: .text%__1cIValueGenMreturn2RInfo6F_nFRInfo__; +text: .text%__1cJValueTypeQas_FloatConstant6M_pnNFloatConstant__: c1_Canonicalizer.o; +text: .text%__1cIRuntime1Qnew_object_array6FpnKJavaThread_pnMklassOopDesc_i_v_; +text: .text%__1cIValueGenLdivOutRInfo6F_nFRInfo__; +text: .text%__1cILIR_ListEidiv6MnFRInfo_111pnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListVvolatile_load_mem_reg6MnFRInfo_i1nJBasicType_pnMCodeEmitInfo_nHLIR_Op1NLIR_PatchCode__v_; +text: .text%__1cEItemSget_jlong_constant6kM_x_; +text: .text%__1cNLIR_AssemblerQvolatile_move_op6MpnLLIR_OprDesc_2nJBasicType_nHLIR_Op1NLIR_PatchCode_pnMCodeEmitInfo__v_; +text: .text%__1cFKlassNoop_is_method6kM_i_: objArrayKlass.o; +text: .text%__1cFKlassRoop_is_methodData6kM_i_: objArrayKlass.o; +text: .text%__1cIciObjectTis_type_array_klass6M_i_: ciObjArrayKlass.o; +text: .text%__1cMciArrayKlassOis_array_klass6M_i_: ciObjArrayKlass.o; +text: .text%__1cONewObjectArrayKexact_type6kM_pnGciType__; +text: .text%__1cPciObjArrayKlassSis_obj_array_klass6M_i_: ciObjArrayKlass.o; +text: .text%__1cPciObjArrayKlassNelement_klass6M_pnHciKlass__; +text: .text%__1cIRuntime1Noop_arraycopy6FpnIHeapWord_2i_v_; +text: .text%__1cILongTypeEbase6kM_pnJValueType__: c1_Canonicalizer.o; +text: .text%__1cMLongConstantLis_constant6kM_i_: c1_Canonicalizer.o; +text: .text%__1cIValueGenUdo_ArithmeticOp_Long6MpnMArithmeticOp__v_; +text: .text%__1cLLIR_EmitterSarithmetic_op_long6MnJBytecodesECode_pnLLIR_OprDesc_44pnMCodeEmitInfo__v_; +text: .text%__1cFKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_: compiledICHolderKlass.o; +text: .text%__1cVcompiledICHolderKlassRoop_oop_iterate_m6MpnHoopDesc_pnKOopClosure_nJMemRegion__i_; +text: .text%__1cIciObjectRis_instance_klass6M_i_: ciTypeArrayKlass.o; +text: .text%__1cLArrayLengthIis_equal6kMpnLInstruction__i_: c1_GraphBuilder.o; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: compiledICHolderKlass.o; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: compiledICHolderKlass.o; +text: .text%__1cTunsafe_intrinsic_id6FpnNsymbolOopDesc_1_nNmethodOopDescLIntrinsicId__; +text: .text%__1cMGraphBuilderVappend_unsafe_put_raw6MpnIciMethod_nJBasicType__i_; +text: .text%__1cMUnsafePutRawFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerPdo_UnsafePutRaw6MpnMUnsafePutRaw__v_; +text: .text%__1cNCanonicalizerOdo_UnsafeRawOp6MpnLUnsafeRawOp__v_; +text: .text%__1cFmatch6FpnLUnsafeRawOp_ppnLInstruction_4pi_i_: c1_Canonicalizer.o; +text: .text%__1cLInstructionPas_ArithmeticOp6M_pnMArithmeticOp__: c1_Instruction.o; +text: .text%__1cIUnsafeOpLas_UnsafeOp6M_p0_: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderVappend_unsafe_get_raw6MpnIciMethod_nJBasicType__i_; +text: .text%__1cMUnsafeGetRawFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerPdo_UnsafeGetRaw6MpnMUnsafeGetRaw__v_; +text: .text%__1cMGraphBuilderNlookup_switch6M_v_; +text: .text%__1cIintArray2t6Mki1_v_: c1_GraphBuilder.o; +text: .text%__1cMLookupSwitchFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerPdo_LookupSwitch6MpnMLookupSwitch__v_; +text: .text%__1cMUnsafePutRawPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorPdo_UnsafePutRaw6MpnMUnsafePutRaw__v_; +text: .text%__1cTNullCheckEliminatorPhandle_UnsafeOp6MpnIUnsafeOp__v_; +text: .text%__1cLUnsafeRawOpPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorPdo_UnsafeGetRaw6MpnMUnsafeGetRaw__v_; +text: .text%__1cQNullCheckVisitorPdo_LookupSwitch6MpnMLookupSwitch__v_; +text: .text%__1cIValueGenPdo_UnsafePutRaw6MpnMUnsafePutRaw__v_; +text: .text%__1cLLIR_EmitterOput_raw_unsafe6MpnLLIR_OprDesc_2i2nJBasicType__v_; +text: .text%__1cLLIR_EmitterMlong2address6MpnLLIR_OprDesc__nFRInfo__; +text: .text%__1cILIR_ListNstore_mem_reg6MnFRInfo_pnLLIR_Address_nJBasicType_pnMCodeEmitInfo_nHLIR_Op1NLIR_PatchCode__v_; +text: .text%__1cIValueGenPdo_UnsafeGetRaw6MpnMUnsafeGetRaw__v_; +text: .text%__1cLLIR_EmitterOget_raw_unsafe6MnFRInfo_pnLLIR_OprDesc_3inJBasicType__v_; +text: .text%__1cILIR_ListMload_mem_reg6MpnLLIR_Address_nFRInfo_nJBasicType_pnMCodeEmitInfo_nHLIR_Op1NLIR_PatchCode__v_; +text: .text%__1cIValueGenPdo_LookupSwitch6MpnMLookupSwitch__v_; +text: .text%__1cUcreate_lookup_ranges6FpnMLookupSwitch__pnQLookupRangeArray__: c1_CodeGenerator_x86.o; +text: .text%__1cLLIR_EmitterVlookupswitch_range_op6MpnLLIR_OprDesc_iipnKBlockBegin__v_; +text: .text%__1cNSharedRuntimeEldiv6Fxx_x_; +text: .text%Unsafe_GetObjectVolatile; +text: .text%signalHandler; +text: .text%JVM_handle_solaris_signal; +text: .text%__1cKJavaThreadUin_stack_yellow_zone6MpC_i_: os_solaris_x86.o; +text: .text%__1cICodeBlobRis_at_poll_return6MpC_i_; +text: .text%__1cUSafepointSynchronizebDhandle_polling_page_exception6FpnKJavaThread__pC_; +text: .text%__1cbCCompiledCodeSafepointHandlerbDhandle_polling_page_exception6M_pC_; +text: .text%__1cFframebDsender_for_raw_compiled_frame6kMpnLRegisterMap__0_; +text: .text%__1cNSafepointBlobYcaller_must_gc_arguments6kMpnKJavaThread__i_; +text: .text%__1cUThreadSafepointStateYcaller_must_gc_arguments6kM_i_; +text: .text%__1cbCCompiledCodeSafepointHandlerYcaller_must_gc_arguments6kM_i_: safepoint.o; +text: .text%__1cFframeIpatch_pc6MpnGThread_pC_v_; +text: .text%__1cNSafepointBlobbDpreserve_callee_argument_oops6MnFframe_pknLRegisterMap_pnKOopClosure__v_: codeBlob.o; +text: .text%__1cSvframeStreamCommonbFfill_in_compiled_inlined_sender6M_i_; +text: .text%__1cJFloatTypeEsize6kM_i_: c1_Canonicalizer.o; +text: .text%__1cIValueGenNrelease_roots6MpnKValueStack__v_; +text: .text%__1cSciExceptionHandlerLcatch_klass6M_pnPciInstanceKlass__; +text: .text%__1cHciKlassNis_subtype_of6Mp0_i_; +text: .text%__1cNSharedRuntimeDd2l6Fd_x_; +text: .text%__1cOObjectConstantLis_constant6kM_i_: c1_ValueType.o; +text: .text%__1cILIR_ListLstore_array6MipnLLIR_Address_nJBasicType_pnMCodeEmitInfo__v_; +text: .text%__1cNLIR_AssemblerLconst2array6MpnJLIR_Const_pnLLIR_Address_nJBasicType_pnMCodeEmitInfo__v_; +text: .text%__1cQInstanceConstantLis_constant6kM_i_: c1_ValueType.o; diff --git a/hotspot/make/solaris/makefiles/reorder_COMPILER1_i486 b/hotspot/make/solaris/makefiles/reorder_COMPILER1_i486 index bab5b288d70..caf8c0298ed 100644 --- a/hotspot/make/solaris/makefiles/reorder_COMPILER1_i486 +++ b/hotspot/make/solaris/makefiles/reorder_COMPILER1_i486 @@ -8,20 +8,20 @@ text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: arguments.o; text: .text%__1cQAgentLibraryList2t6M_v_: arguments.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_AllocTable.o; text: .text%__1cFRInfo2t6M_v_: c1_AllocTable.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_AllocTable_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_AllocTable_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_AllocTable_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_AllocTable_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CacheLocals.o; text: .text%__1cFRInfo2t6M_v_: c1_CacheLocals.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CacheLocals_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_CacheLocals_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CacheLocals_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_CacheLocals_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Canonicalizer.o; text: .text%__1cFRInfo2t6M_v_: c1_Canonicalizer.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CodeGenerator.o; text: .text%__1cFRInfo2t6M_v_: c1_CodeGenerator.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CodeGenerator_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_CodeGenerator_i486.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CodeStubs_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_CodeStubs_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CodeGenerator_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_CodeGenerator_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CodeStubs_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_CodeStubs_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Compilation.o; text: .text%__1cFRInfo2t6M_v_: c1_Compilation.o; text: .text%__1cMelapsedTimer2t6M_v_: c1_Compilation.o; @@ -29,9 +29,9 @@ text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Compiler.o; text: .text%__1cFRInfo2t6M_v_: c1_Compiler.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_FrameMap.o; text: .text%__1cFRInfo2t6M_v_: c1_FrameMap.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_FrameMap_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_FrameMap_i486.o; -text: .text%__1cKc1_RegMask2t6M_v_: c1_FrameMap_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_FrameMap_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_FrameMap_x86.o; +text: .text%__1cKc1_RegMask2t6M_v_: c1_FrameMap_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_GraphBuilder.o; text: .text%__1cFRInfo2t6M_v_: c1_GraphBuilder.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_IR.o; @@ -43,41 +43,41 @@ text: .text%__1cFRInfo2t6M_v_: c1_InstructionPrinter.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Items.o; text: .text%__1cFRInfo2t6M_v_: c1_Items.o; text: .text%__1cIHintItem2t6MpnJValueType_i_v_: c1_Items.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Items_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_Items_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Items_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_Items_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIR.o; text: .text%__1cFRInfo2t6M_v_: c1_LIR.o; text: .text%__1cLLIR_OprFactHillegal6F_pnLLIR_OprDesc__: c1_LIR.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIRAssembler.o; text: .text%__1cFRInfo2t6M_v_: c1_LIRAssembler.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIRAssembler_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_LIRAssembler_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIRAssembler_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_LIRAssembler_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIREmitter.o; text: .text%__1cFRInfo2t6M_v_: c1_LIREmitter.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIREmitter_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_LIREmitter_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIREmitter_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_LIREmitter_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIROptimizer.o; text: .text%__1cFRInfo2t6M_v_: c1_LIROptimizer.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Loops.o; text: .text%__1cFRInfo2t6M_v_: c1_Loops.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_MacroAssembler_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_MacroAssembler_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_MacroAssembler_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_MacroAssembler_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Optimizer.o; text: .text%__1cFRInfo2t6M_v_: c1_Optimizer.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_RInfo.o; text: .text%__1cFRInfo2t6M_v_: c1_RInfo.o; text: .text%__1cKc1_RegMask2t6M_v_: c1_RInfo.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_RInfo_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_RInfo_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_RInfo_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_RInfo_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_RegAlloc.o; text: .text%__1cFRInfo2t6M_v_: c1_RegAlloc.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_RegAlloc_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_RegAlloc_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_RegAlloc_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_RegAlloc_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Runtime1.o; text: .text%__1cFRInfo2t6M_v_: c1_Runtime1.o; text: .text%__1cIiEntries2t6M_v_; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Runtime1_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_Runtime1_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Runtime1_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_Runtime1_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_ScanBlocks.o; text: .text%__1cFRInfo2t6M_v_: c1_ScanBlocks.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_ValueMap.o; @@ -105,8 +105,8 @@ text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: fprofiler.o; text: .text%__1cMelapsedTimer2t6M_v_: fprofiler.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: frame.o; text: .text%__1cFRInfo2t6M_v_: frame.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: frame_i486.o; -text: .text%__1cFRInfo2t6M_v_: frame_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: frame_x86.o; +text: .text%__1cFRInfo2t6M_v_: frame_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: genCollectedHeap.o; text: .text%__1cTAssertIsPermClosure2t6M_v_: genCollectedHeap.o; text: .text%__1cRAlwaysTrueClosure2t6M_v_: genCollectedHeap.o; @@ -117,8 +117,8 @@ text: .text%__1cNCellTypeStateImake_top6F_0_: generateOopMap.o; text: .text%__1cMelapsedTimer2t6M_v_: generateOopMap.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: interpreter.o; text: .text%__1cKEntryPoint2t6M_v_; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: interpreter_i486.o; -text: .text%__1cFRInfo2t6M_v_: interpreter_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: interpreter_x86.o; +text: .text%__1cFRInfo2t6M_v_: interpreter_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: java.o; text: .text%__1cFRInfo2t6M_v_: java.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: jvmtiEnvBase.o; @@ -151,16 +151,16 @@ text: .text%__1cNGrowableArray4CpnKMemoryPool__2t6Mii_v_: memoryService.o; text: .text%__1cNGrowableArray4CpnNMemoryManager__2t6Mii_v_: memoryService.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: methodOop.o; text: .text%__1cFRInfo2t6M_v_: methodOop.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: nativeInst_i486.o; -text: .text%__1cFRInfo2t6M_v_: nativeInst_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: nativeInst_x86.o; +text: .text%__1cFRInfo2t6M_v_: nativeInst_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: nmethod.o; text: .text%__1cFRInfo2t6M_v_: nmethod.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: oopMap.o; text: .text%__1cQDoNothingClosure2t6M_v_: oopMap.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: os_solaris.o; text: .text%__1cFRInfo2t6M_v_: os_solaris.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: os_solaris_i486.o; -text: .text%__1cFRInfo2t6M_v_: os_solaris_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: os_solaris_x86.o; +text: .text%__1cFRInfo2t6M_v_: os_solaris_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: parGCAllocBuffer.o; text: .text%__1cMarrayOopDescLheader_size6FnJBasicType__i_: parGCAllocBuffer.o; text: .text%__1cRalign_object_size6Fi_i_: parGCAllocBuffer.o; @@ -181,8 +181,8 @@ text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: runtimeService.o; text: .text%__1cJTimeStamp2t6M_v_: runtimeService.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: safepoint.o; text: .text%__1cFRInfo2t6M_v_: safepoint.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: safepoint_solaris_i486.o; -text: .text%__1cFRInfo2t6M_v_: safepoint_solaris_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: safepoint_solaris_x86.o; +text: .text%__1cFRInfo2t6M_v_: safepoint_solaris_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: sharedHeap.o; text: .text%__1cTAssertIsPermClosure2t6M_v_: sharedHeap.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: sharedRuntime.o; @@ -197,10 +197,10 @@ text: .text%__1cFRInfo2t6M_v_: vmStructs.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: vm_version.o; text: .text%__1cTAbstract_VM_VersionKvm_release6F_pkc_; text: .text%__1cTAbstract_VM_VersionXinternal_vm_info_string6F_pkc_; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: vtableStubs_i486.o; -text: .text%__1cFRInfo2t6M_v_: vtableStubs_i486.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIROptimizer_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_LIROptimizer_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: vtableStubs_x86.o; +text: .text%__1cFRInfo2t6M_v_: vtableStubs_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIROptimizer_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_LIROptimizer_x86.o; text: .text%JNI_CreateJavaVM; text: .text%__1cCosVatomic_xchg_bootstrap6Fipoi_i_; text: .text%__1cHThreadsJcreate_vm6FpnOJavaVMInitArgs_pi_i_; @@ -279,7 +279,7 @@ text: .text%__1cSThreadLocalStorageEinit6F_v_; text: .text%__1cSThreadLocalStorageHpd_init6F_v_; text: .text%__1cCosbDallocate_thread_local_storage6F_i_; text: .text%__1cSThreadLocalStoragebCgenerate_code_for_get_thread6F_v_; -text: .text%__1cRAllocateTLSOffset6F_v_: threadLS_solaris_i486.o; +text: .text%__1cRAllocateTLSOffset6F_v_: threadLS_solaris_x86.o; text: .text%__1cPvm_init_globals6F_v_; text: .text%__1cScheck_ThreadShadow6F_v_; text: .text%__1cRcheck_basic_types6F_v_; @@ -463,7 +463,7 @@ text: .text%__1cKMemoryPoolImax_size6kM_I_: memoryPool.o; text: .text%__1cXresource_allocate_bytes6FI_pc_; text: .text%__1cKCodeBuffer2t6MpCi_v_; text: .text%__1cRAbstractAssembler2t6MpnKCodeBuffer__v_; -text: .text%__1cYVM_Version_StubGeneratorTgenerate_getPsrInfo6M_pC_: vm_version_i486.o; +text: .text%__1cYVM_Version_StubGeneratorTgenerate_getPsrInfo6M_pC_: vm_version_x86.o; text: .text%__1cMStubCodeMark2t6MpnRStubCodeGenerator_pkc4_v_; text: .text%__1cRStubCodeGeneratorLstub_prolog6MpnMStubCodeDesc__v_; text: .text%__1cJAssemblerFpushl6MpnMRegisterImpl__v_; @@ -497,14 +497,14 @@ text: .text%__1cFVTuneNregister_stub6FpkcpC3_v_; text: .text%__1cFForteNregister_stub6FpkcpC3_v_; text: .text%__1cKVM_VersionWget_processor_features6F_v_; text: .text%__1cCosMsupports_sse6F_i_; -text: .text%__1cVcheck_for_sse_support6F_v_: os_solaris_i486.o; +text: .text%__1cVcheck_for_sse_support6F_v_: os_solaris_x86.o; text: .text%jio_snprintf; text: .text%jio_vsnprintf; text: .text%__1cPlocal_vsnprintf6FpcIpkcpv_i_; text: .text%__1cSstubRoutines_init16F_v_; text: .text%__1cMStubRoutinesLinitialize16F_v_; text: .text%__1cWStubGenerator_generate6FpnKCodeBuffer_i_v_; -text: .text%__1cNStubGeneratorbAgenerate_forward_exception6M_pC_: stubGenerator_i486.o; +text: .text%__1cNStubGeneratorbAgenerate_forward_exception6M_pC_: stubGenerator_x86.o; text: .text%__1cOMacroAssemblerMcall_VM_leaf6MpCpnMRegisterImpl__v_; text: .text%__1cOMacroAssemblerMcall_VM_leaf6MpCi_v_; text: .text%__1cOMacroAssemblerRcall_VM_leaf_base6MpCi_v_; @@ -525,7 +525,7 @@ text: .text%__1cJAssemblerEleal6MpnMRegisterImpl_nHAddress__v_; text: .text%__1cJAssemblerEmovl6MnHAddress_i_v_; text: .text%__1cOMacroAssemblerKverify_oop6MpnMRegisterImpl_pkc_v_; text: .text%__1cJAssemblerDjmp6MpnMRegisterImpl_nJrelocInfoJrelocType__v_; -text: .text%__1cNStubGeneratorSgenerate_call_stub6MrpC_1_: stubGenerator_i486.o; +text: .text%__1cNStubGeneratorSgenerate_call_stub6MrpC_1_: stubGenerator_x86.o; text: .text%__1cOMacroAssemblerFenter6M_v_; text: .text%__1cJAssemblerEsubl6MpnMRegisterImpl_i_v_; text: .text%__1cJAssemblerFtestl6MpnMRegisterImpl_2_v_; @@ -534,14 +534,14 @@ text: .text%__1cJAssemblerEcall6MpnMRegisterImpl_nJrelocInfoJrelocType__v_; text: .text%__1cJAssemblerEcmpl6MpnMRegisterImpl_i_v_; text: .text%__1cJAssemblerGfstp_s6MnHAddress__v_; text: .text%__1cJAssemblerGfstp_d6MnHAddress__v_; -text: .text%__1cNStubGeneratorYgenerate_catch_exception6M_pC_: stubGenerator_i486.o; +text: .text%__1cNStubGeneratorYgenerate_catch_exception6M_pC_: stubGenerator_x86.o; text: .text%__1cJAssemblerDjmp6MpCnJrelocInfoJrelocType__v_; -text: .text%__1cNStubGeneratorUgenerate_atomic_xchg6M_pC_: stubGenerator_i486.o; +text: .text%__1cNStubGeneratorUgenerate_atomic_xchg6M_pC_: stubGenerator_x86.o; text: .text%__1cJAssemblerExchg6MpnMRegisterImpl_nHAddress__v_; text: .text%__1cJAssemblerGpushad6M_v_; text: .text%__1cJAssemblerFpopad6M_v_; -text: .text%__1cNStubGeneratorYgenerate_get_previous_fp6M_pC_: stubGenerator_i486.o; -text: .text%__1cNStubGeneratorUgenerate_d2i_wrapper6MpC_1_: stubGenerator_i486.o; +text: .text%__1cNStubGeneratorYgenerate_get_previous_fp6M_pC_: stubGenerator_x86.o; +text: .text%__1cNStubGeneratorUgenerate_d2i_wrapper6MpC_1_: stubGenerator_x86.o; text: .text%__1cOMacroAssemblerOpush_FPU_state6M_v_; text: .text%__1cJAssemblerGfnsave6MnHAddress__v_; text: .text%__1cJAssemblerFfwait6M_v_; @@ -552,7 +552,7 @@ text: .text%__1cJAssemblerFffree6Mi_v_; text: .text%__1cJAssemblerLemit_farith6Miii_v_; text: .text%__1cOMacroAssemblerNpop_FPU_state6M_v_; text: .text%__1cJAssemblerGfrstor6MnHAddress__v_; -text: .text%__1cNStubGeneratorUcreate_control_words6M_v_: stubGenerator_i486.o; +text: .text%__1cNStubGeneratorUcreate_control_words6M_v_: stubGenerator_x86.o; text: .text%__1cJTraceTime2T6M_v_; text: .text%__1cNcarSpace_init6F_v_; text: .text%__1cICarSpaceEinit6F_v_; @@ -773,7 +773,7 @@ text: .text%__1cUInterpreterGeneratorVgenerate_counter_incr6MpnFLabel_22_v_; text: .text%__1cJAssemblerEaddl6MpnMRegisterImpl_2_v_; text: .text%__1cJAssemblerEcmpl6MpnMRegisterImpl_nHAddress__v_; text: .text%__1cbCAbstractInterpreterGeneratorXbang_stack_shadow_pages6Mi_v_; -text: .text%__1cOMacroAssemblerWbang_stack_with_offset6Mi_v_: interp_masm_i486.o; +text: .text%__1cOMacroAssemblerWbang_stack_with_offset6Mi_v_: interp_masm_x86.o; text: .text%__1cZInterpreterMacroAssemblerTnotify_method_entry6M_v_; text: .text%__1cUInterpreterGeneratorZgenerate_counter_overflow6MpC_v_; text: .text%__1cJAssemblerEnegl6MpnMRegisterImpl__v_; @@ -785,7 +785,7 @@ text: .text%__1cJAssemblerDorl6MpnMRegisterImpl_nHAddress__v_; text: .text%__1cUInterpreterGeneratorUgenerate_empty_entry6M_pC_; text: .text%__1cUInterpreterGeneratorXgenerate_accessor_entry6M_pC_; text: .text%__1cJAssemblerEshrl6MpnMRegisterImpl_i_v_; -text: .text%__1cLlog2_intptr6Fi_i_: interpreter_i486.o; +text: .text%__1cLlog2_intptr6Fi_i_: interpreter_x86.o; text: .text%__1cOMacroAssemblerQload_signed_byte6MpnMRegisterImpl_nHAddress__i_; text: .text%__1cJAssemblerGmovsxb6MpnMRegisterImpl_nHAddress__v_; text: .text%__1cOMacroAssemblerQload_signed_word6MpnMRegisterImpl_nHAddress__i_; @@ -982,7 +982,7 @@ text: .text%__1cNTemplateTableJfloat_cmp6Fii_v_; text: .text%__1cOMacroAssemblerIfcmp2int6MpnMRegisterImpl_i_v_; text: .text%__1cNTemplateTableKdouble_cmp6Fi_v_; text: .text%__1cNTemplateTableHif_0cmp6Fn0AJCondition__v_; -text: .text%__1cFj_not6FnNTemplateTableJCondition__nJAssemblerJCondition__: templateTable_i486.o; +text: .text%__1cFj_not6FnNTemplateTableJCondition__nJAssemblerJCondition__: templateTable_x86.o; text: .text%__1cNTemplateTableGbranch6Fii_v_; text: .text%__1cZInterpreterMacroAssemblerUprofile_taken_branch6MpnMRegisterImpl_2_v_; text: .text%__1cZInterpreterMacroAssemblerNdispatch_only6MnITosState__v_; @@ -1488,7 +1488,7 @@ text: .text%__1cKSharedInfoLset_regName6F_v_; text: .text%__1cIRegAllocYinit_register_allocation6F_v_; text: .text%__1cIFrameMapEinit6F_v_; text: .text%__1cKc1_RegMaskKinit_masks6Fi_v_; -text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_FrameMap_i486.o; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_FrameMap_x86.o; text: .text%__1cNc1_AllocTableLinit_tables6F_v_; text: .text%__1cIFrameMapOfirst_register6F_pnMRegisterImpl__; text: .text%__1cIFrameMapLcpu_reg2rnr6FpnMRegisterImpl__i_; @@ -1502,7 +1502,7 @@ text: .text%__1cKCodeBuffer2t6MiiiiiipnKBufferBlob_pnJrelocInfo_pnORelocateBuffe text: .text%__1cKCodeBufferQalloc_relocation6MI_v_; text: .text%__1cJOopMapSet2t6M_v_; text: .text%__1cJAssemblerEsubl6MnHAddress_i_v_; -text: .text%__1cTsave_live_registers6FpnOMacroAssembler_i_pnGOopMap__: c1_Runtime1_i486.o; +text: .text%__1cTsave_live_registers6FpnOMacroAssembler_i_pnGOopMap__: c1_Runtime1_x86.o; text: .text%__1cJAssemblerGfldenv6MnHAddress__v_; text: .text%__1cGOopMap2t6Mii_v_; text: .text%__1cGOopMapQset_callee_saved6MnHOptoRegEName_ii2_v_; @@ -1564,10 +1564,10 @@ text: .text%__1cNStubAssemblerHcall_RT6MpnMRegisterImpl_2pCi_i_; text: .text%__1cJStubFrame2T6M_v_; text: .text%__1cIRuntime1Ygenerate_exception_throw6FpnNStubAssembler_pCpnMRegisterImpl__pnJOopMapSet__; text: .text%__1cOMacroAssemblerLtlab_refill6MrnFLabel_22_v_; -text: .text%__1cLlog2_intptr6Fi_i_: assembler_i486.o; +text: .text%__1cLlog2_intptr6Fi_i_: assembler_x86.o; text: .text%__1cOMacroAssemblerNeden_allocate6MpnMRegisterImpl_2i2rnFLabel__v_; text: .text%__1cOMacroAssemblerLverify_tlab6M_v_; -text: .text%__1cLlog2_intptr6Fi_i_: c1_Runtime1_i486.o; +text: .text%__1cLlog2_intptr6Fi_i_: c1_Runtime1_x86.o; text: .text%__1cOMacroAssemblerNtlab_allocate6MpnMRegisterImpl_2i22rnFLabel__v_; text: .text%__1cRC1_MacroAssemblerRinitialize_object6MpnMRegisterImpl_22i22_v_; text: .text%__1cRC1_MacroAssemblerRinitialize_header6MpnMRegisterImpl_22_v_; @@ -1581,7 +1581,7 @@ text: .text%__1cIiEntries2t6Miiii_v_; text: .text%__1cRNativeGeneralJumpQjump_destination6kM_pC_; text: .text%__1cJAssemblerOlocate_operand6FpCn0AMWhichOperand__1_; text: .text%__1cIRuntime1Rgenerate_patching6FpnNStubAssembler_pC_pnJOopMapSet__; -text: .text%__1cWrestore_live_registers6FpnOMacroAssembler__v_: c1_Runtime1_i486.o; +text: .text%__1cWrestore_live_registers6FpnOMacroAssembler__v_: c1_Runtime1_x86.o; text: .text%__1cNSafepointBlobGcreate6FpnKCodeBuffer_pnJOopMapSet_i_p0_; text: .text%__1cNSafepointBlob2n6FII_pv_; text: .text%__1cNSafepointBlob2t6MpnKCodeBuffer_ipnJOopMapSet_i_v_; @@ -1778,8 +1778,8 @@ text: .text%__1cYsun_reflect_ConstantPoolPcompute_offsets6F_v_; text: .text%__1cZsun_misc_AtomicLongCSImplPcompute_offsets6F_v_; text: .text%__1cSstubRoutines_init26F_v_; text: .text%__1cMStubRoutinesLinitialize26F_v_; -text: .text%__1cNStubGeneratorYgenerate_throw_exception6MpkcpCi_3_: stubGenerator_i486.o; -text: .text%__1cNStubGeneratorTgenerate_verify_oop6M_pC_: stubGenerator_i486.o; +text: .text%__1cNStubGeneratorYgenerate_throw_exception6MpkcpCi_3_: stubGenerator_x86.o; +text: .text%__1cNStubGeneratorTgenerate_verify_oop6M_pC_: stubGenerator_x86.o; text: .text%__1cJAssemblerEincl6MnHAddress__v_; text: .text%__1cHThreadsDadd6FpnKJavaThread_i_v_; text: .text%__1cNThreadServiceKadd_thread6FpnKJavaThread_i_v_; @@ -3074,11 +3074,11 @@ text: .text%__1cEItemRget_jint_constant6kM_i_; text: .text%__1cLLIR_EmitterRarithmetic_op_int6MnJBytecodesECode_pnLLIR_OprDesc_44nFRInfo__v_; text: .text%__1cLLIR_EmitterNarithmetic_op6MnJBytecodesECode_pnLLIR_OprDesc_44inFRInfo_pnMCodeEmitInfo__v_; text: .text%__1cLLIR_EmitterYstrength_reduce_multiply6MpnLLIR_OprDesc_i22_i_; -text: .text%__1cILIR_ListHreg2reg6MnFRInfo_1nJBasicType__v_: c1_LIREmitter_i486.o; -text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_LIREmitter_i486.o; -text: .text%__1cLlog2_intptr6Fi_i_: c1_LIREmitter_i486.o; +text: .text%__1cILIR_ListHreg2reg6MnFRInfo_1nJBasicType__v_: c1_LIREmitter_x86.o; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_LIREmitter_x86.o; +text: .text%__1cLlog2_intptr6Fi_i_: c1_LIREmitter_x86.o; text: .text%__1cILIR_ListKshift_left6MpnLLIR_OprDesc_222_v_; -text: .text%__1cILIR_ListDsub6MpnLLIR_OprDesc_22pnMCodeEmitInfo__v_: c1_LIREmitter_i486.o; +text: .text%__1cILIR_ListDsub6MpnLLIR_OprDesc_22pnMCodeEmitInfo__v_: c1_LIREmitter_x86.o; text: .text%__1cIValueGenWcan_inline_as_constant6MpnEItem__i_; text: .text%__1cIRegAllocPget_register_rc6kMnFRInfo__i_; text: .text%__1cLGetRefCountGdo_cpu6Mi_v_: c1_RegAlloc.o; @@ -3098,7 +3098,7 @@ text: .text%__1cMLIR_OpBranch2t6Mn0ANLIR_Condition_pnICodeStub_pnMCodeEmitInfo__ text: .text%__1cLLIR_EmitterMindexed_load6MnFRInfo_nJBasicType_pnLLIR_OprDesc_4pnMCodeEmitInfo__v_; text: .text%__1cLLIR_EmitterNarray_address6MpnLLIR_OprDesc_2inJBasicType__pnLLIR_Address__; text: .text%__1cLLIR_AddressFscale6FnJBasicType__n0AFScale__; -text: .text%__1cILIR_ListEmove6MpnLLIR_Address_pnLLIR_OprDesc_pnMCodeEmitInfo__v_: c1_LIREmitter_i486.o; +text: .text%__1cILIR_ListEmove6MpnLLIR_Address_pnLLIR_OprDesc_pnMCodeEmitInfo__v_: c1_LIREmitter_x86.o; text: .text%__1cIRegAllocNoops_in_spill6kM_pnIintStack__; text: .text%__1cIRegAllocRoops_in_registers6kM_pnPRInfoCollection__; text: .text%__1cIValueGenbDsafepoint_poll_needs_register6F_i_; @@ -3137,9 +3137,9 @@ text: .text%__1cHLIR_Op1Fvisit6MpnQLIR_OpVisitState__v_; text: .text%__1cPRegisterManagerElock6MnFRInfo__v_; text: .text%__1cHLIR_Op2Fvisit6MpnQLIR_OpVisitState__v_; text: .text%__1cMLIR_OpBranchFvisit6MpnQLIR_OpVisitState__v_; -text: .text%__1cORangeCheckStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_i486.o; -text: .text%__1cQLIR_OpVisitStateGappend6MnFRInfo__v_: c1_CodeStubs_i486.o; -text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_CodeStubs_i486.o; +text: .text%__1cORangeCheckStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; +text: .text%__1cQLIR_OpVisitStateGappend6MnFRInfo__v_: c1_CodeStubs_x86.o; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_CodeStubs_x86.o; text: .text%__1cNc1_AllocTableFmerge6Mp0_v_; text: .text%__1cGLIR_OpFvisit6MpnQLIR_OpVisitState__v_; text: .text%__1cQLIR_LocalCachingXcache_locals_for_blocks6MpnJBlockList_pnPRegisterManager_i_pnMLocalMapping__; @@ -3201,7 +3201,7 @@ text: .text%__1cJLabelListIindex_of6kMkpnFLabel__i_: c1_LIROptimizer.o; text: .text%__1cRLIR_PeepholeStateYset_disable_optimization6Mi_v_; text: .text%__1cLLIR_OpLabelJemit_code6MpnVLIR_AbstractAssembler__v_; text: .text%__1cNLIR_OptimizerMemit_opLabel6MpnLLIR_OpLabel__v_; -text: .text%__1cNLIR_OptimizerFvisit6M_v_: c1_LIROptimizer_i486.o; +text: .text%__1cNLIR_OptimizerFvisit6M_v_: c1_LIROptimizer_x86.o; text: .text%__1cHLIR_Op0Jemit_code6MpnVLIR_AbstractAssembler__v_; text: .text%__1cNLIR_OptimizerIemit_op06MpnHLIR_Op0__v_; text: .text%__1cHLIR_Op2Jemit_code6MpnVLIR_AbstractAssembler__v_; @@ -3225,7 +3225,7 @@ text: .text%__1cNLIR_OptimizerRreplace_stack_opr6MpnLLIR_OprDesc__2_; text: .text%__1cNLIR_OptimizerNoptimize_move6MpnHLIR_Op1_rpnLLIR_OprDesc_5_i_; text: .text%__1cRLIR_PeepholeStatebFequivalent_register_or_constant6MpnLLIR_OprDesc__2_; text: .text%__1cRLIR_PeepholeStateOequivalent_opr6MpnLLIR_OprDesc__2_; -text: .text%__1cNLIR_OptimizerKmaybe_opto6MpnLLIR_OprDesc_2_2_: c1_LIROptimizer_i486.o; +text: .text%__1cNLIR_OptimizerKmaybe_opto6MpnLLIR_OprDesc_2_2_: c1_LIROptimizer_x86.o; text: .text%__1cNLIR_OptimizerMis_cache_reg6MpnLLIR_OprDesc__i_; text: .text%__1cMLocalMappingMis_cache_reg6kMpnLLIR_OprDesc__i_; text: .text%__1cMLocalMappingMis_cache_reg6kMnFRInfo__i_; @@ -3294,13 +3294,13 @@ text: .text%__1cNLIR_AssemblerVsetup_locals_at_entry6M_v_; text: .text%__1cIFrameMapYsignature_type_array_for6FpknIciMethod__pnNBasicTypeList__; text: .text%__1cIFrameMapScalling_convention6FpknIciMethod_pnIintArray__pnRCallingConvention__; text: .text%__1cIFrameMapScalling_convention6FirknOBasicTypeArray_pnIintArray__pnRCallingConvention__; -text: .text%__1cIintArray2t6Mki1_v_: c1_FrameMap_i486.o; +text: .text%__1cIintArray2t6Mki1_v_: c1_FrameMap_x86.o; text: .text%__1cIFrameMapRname_for_argument6Fi_i_; text: .text%__1cIFrameMapSfp_offset_for_name6kMiii_i_; text: .text%__1cIFrameMapPnum_local_names6kM_i_; text: .text%__1cIFrameMapNlocal_to_slot6kMii_i_; text: .text%__1cIFrameMapSfp_offset_for_slot6kMi_i_; -text: .text%__1cQArgumentLocation2t6Mci_v_: c1_FrameMap_i486.o; +text: .text%__1cQArgumentLocation2t6Mci_v_: c1_FrameMap_x86.o; text: .text%__1cQArgumentLocationSset_stack_location6Mi_v_; text: .text%__1cIFrameMapQaddress_for_name6kMiii_nHAddress__; text: .text%__1cIFrameMapQmake_new_address6kMi_nHAddress__; @@ -3321,12 +3321,12 @@ text: .text%__1cNLIR_AssemblerbIadd_debug_info_for_null_check_here6MpnMCodeEmitI text: .text%__1cNLIR_AssemblerLcode_offset6kM_i_; text: .text%__1cNLIR_AssemblerbDadd_debug_info_for_null_check6MipnMCodeEmitInfo__v_; text: .text%__1cNLIR_AssemblerOemit_code_stub6MpnICodeStub__v_; -text: .text%__1cVImplicitNullCheckStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_i486.o; +text: .text%__1cVImplicitNullCheckStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; text: .text%__1cNLIR_AssemblerCpc6kM_pC_; -text: .text%__1cICodeStubLset_code_pc6MpC_v_: c1_CodeStubs_i486.o; -text: .text%__1cICodeStubMis_call_stub6kM_i_: c1_CodeStubs_i486.o; +text: .text%__1cICodeStubLset_code_pc6MpC_v_: c1_CodeStubs_x86.o; +text: .text%__1cICodeStubMis_call_stub6kM_i_: c1_CodeStubs_x86.o; text: .text%__1cNCodeStubArrayIindex_of6kMkpnICodeStub__i_: c1_LIRAssembler.o; -text: .text%__1cORangeCheckStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_i486.o; +text: .text%__1cORangeCheckStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; text: .text%__1cNLIR_AssemblerOsafepoint_poll6MnFRInfo_pnMCodeEmitInfo__v_; text: .text%__1cNLIR_AssemblerZadd_debug_info_for_branch6MpnMCodeEmitInfo__v_; text: .text%__1cPpoll_RelocationEtype6M_nJrelocInfoJrelocType__: codeBlob.o; @@ -3396,7 +3396,7 @@ text: .text%__1cNLIR_AssemblerWemit_exception_handler6M_i_; text: .text%__1cRC1_MacroAssemblerRexception_handler6Mii_v_; text: .text%__1cNLIR_AssemblerPemit_call_stubs6M_v_; text: .text%__1cNLIR_AssemblerbCmaybe_adjust_stack_alignment6MpnIciMethod__v_; -text: .text%__1cKreal_index6FpnIFrameMap_i_i_: c1_LIRAssembler_i486.o; +text: .text%__1cKreal_index6FpnIFrameMap_i_i_: c1_LIRAssembler_x86.o; text: .text%__1cLCompilationbEgenerate_exception_range_table6M_v_; text: .text%__1cOExceptionScopeGequals6kMp0_i_; text: .text%__1cLCompilationbBadd_exception_range_entries6MiipnOExceptionScope_ip2pi_v_; @@ -3582,10 +3582,10 @@ text: .text%__1cLNewInstanceOas_NewInstance6M_p0_: c1_Instruction.o; text: .text%__1cIValueGenQexceptionPcRInfo6F_nFRInfo__; text: .text%__1cILIR_ListPthrow_exception6MnFRInfo_1pnMCodeEmitInfo__v_: c1_CodeGenerator.o; text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_CodeGenerator.o; -text: .text%__1cPNewInstanceStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_i486.o; +text: .text%__1cPNewInstanceStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; text: .text%__1cOLIR_OpJavaCallFvisit6MpnQLIR_OpVisitState__v_; text: .text%__1cQLIR_OpVisitStateGappend6MnFRInfo__v_: c1_LIR.o; -text: .text%__1cOStaticCallStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_i486.o; +text: .text%__1cOStaticCallStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; text: .text%__1cIFrameMapWcaller_save_cpu_reg_at6Fi_pnLLIR_OprDesc__; text: .text%__1cLInstructionLas_NewArray6M_pnINewArray__: c1_Instruction.o; text: .text%__1cIVoidTypeDtag6kM_nIValueTag__: c1_ValueType.o; @@ -3604,12 +3604,12 @@ text: .text%__1cOoop_RelocationJpack_data6M_i_; text: .text%__1cNLIR_AssemblerPpatching_epilog6MpnMPatchingStub_nHLIR_Op1NLIR_PatchCode_pnMRegisterImpl_pnMCodeEmitInfo__v_; text: .text%__1cMPatchingStubHinstall6MpnOMacroAssembler_nHLIR_Op1NLIR_PatchCode_pnMRegisterImpl_pnMCodeEmitInfo__v_: c1_LIRAssembler.o; text: .text%__1cNLIR_AssemblerUappend_patching_stub6MpnMPatchingStub__v_; -text: .text%__1cPNewInstanceStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_i486.o; +text: .text%__1cPNewInstanceStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; text: .text%__1cNLIR_AssemblerJemit_call6MpnOLIR_OpJavaCall__v_; text: .text%__1cNLIR_AssemblerKalign_call6MnILIR_Code__v_; -text: .text%__1cICodeStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_i486.o; -text: .text%__1cOStaticCallStubLset_code_pc6MpC_v_: c1_CodeStubs_i486.o; -text: .text%__1cOStaticCallStubMis_call_stub6kM_i_: c1_CodeStubs_i486.o; +text: .text%__1cICodeStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; +text: .text%__1cOStaticCallStubLset_code_pc6MpC_v_: c1_CodeStubs_x86.o; +text: .text%__1cOStaticCallStubMis_call_stub6kM_i_: c1_CodeStubs_x86.o; text: .text%__1cNLIR_AssemblerEcall6MpCnJrelocInfoJrelocType_pnMCodeEmitInfo__v_; text: .text%__1cbBopt_virtual_call_RelocationEtype6M_nJrelocInfoJrelocType__: relocInfo.o; text: .text%__1cKRelocationJpack_data6M_i_: relocInfo.o; @@ -4010,15 +4010,15 @@ text: .text%__1cJTypeCheckPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBui text: .text%__1cQNullCheckVisitorNdo_InstanceOf6MpnKInstanceOf__v_; text: .text%__1cQNullCheckVisitorMdo_CheckCast6MpnJCheckCast__v_; text: .text%__1cIValueGenNdo_InstanceOf6MpnKInstanceOf__v_; -text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_CodeGenerator_i486.o; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_CodeGenerator_x86.o; text: .text%__1cLLIR_EmitterNinstanceof_op6MpnLLIR_OprDesc_2pnHciKlass_nFRInfo_5ipnMCodeEmitInfo__v_; text: .text%__1cILIR_ListKinstanceof6MpnLLIR_OprDesc_2pnHciKlass_22ipnMCodeEmitInfo__v_; text: .text%__1cPLIR_OpTypeCheck2t6MnILIR_Code_pnLLIR_OprDesc_3pnHciKlass_33ipnMCodeEmitInfo_7pnICodeStub__v_; text: .text%__1cIValueGenMdo_CheckCast6MpnJCheckCast__v_; text: .text%__1cILIR_ListJcheckcast6MpnLLIR_OprDesc_2pnHciKlass_22ipnMCodeEmitInfo_6pnICodeStub__v_; -text: .text%__1cILIR_ListJsafepoint6MnFRInfo_pnMCodeEmitInfo__v_: c1_CodeGenerator_i486.o; +text: .text%__1cILIR_ListJsafepoint6MnFRInfo_pnMCodeEmitInfo__v_: c1_CodeGenerator_x86.o; text: .text%__1cPLIR_OpTypeCheckFvisit6MpnQLIR_OpVisitState__v_; -text: .text%__1cTSimpleExceptionStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_i486.o; +text: .text%__1cTSimpleExceptionStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; text: .text%__1cPLIR_OpTypeCheckJemit_code6MpnVLIR_AbstractAssembler__v_; text: .text%__1cNLIR_OptimizerQemit_opTypeCheck6MpnPLIR_OpTypeCheck__v_; text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_LIROptimizer.o; @@ -4026,7 +4026,7 @@ text: .text%__1cIintArrayIindex_of6kMki_i_: c1_LIROptimizer.o; text: .text%__1cNLIR_AssemblerQemit_opTypeCheck6MpnPLIR_OpTypeCheck__v_; text: .text%__1cIciObjectIencoding6M_pnI_jobject__; text: .text%__1cJAssemblerEcmpl6MnHAddress_pnI_jobject__v_; -text: .text%__1cTSimpleExceptionStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_i486.o; +text: .text%__1cTSimpleExceptionStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; text: .text%__1cTSimpleExceptionStubJemit_code6MpnNLIR_Assembler__v_; text: .text%__1cJLoadFieldIis_equal6kMpnLInstruction__i_: c1_Instruction.o; text: .text%__1cJLoadFieldMas_LoadField6M_p0_: c1_Instruction.o; @@ -4194,7 +4194,7 @@ text: .text%__1cLLIR_EmitterOnew_type_array6MnFRInfo_nJBasicType_pnLLIR_OprDesc_ text: .text%__1cQNewTypeArrayStub2t6MnFRInfo_11pnMCodeEmitInfo__v_; text: .text%__1cQciTypeArrayKlassEmake6FnJBasicType__p0_; text: .text%__1cQciTypeArrayKlassJmake_impl6FnJBasicType__p0_; -text: .text%__1cILIR_ListHoop2reg6MpnI_jobject_nFRInfo__v_: c1_LIREmitter_i486.o; +text: .text%__1cILIR_ListHoop2reg6MpnI_jobject_nFRInfo__v_: c1_LIREmitter_x86.o; text: .text%__1cILIR_ListOallocate_array6MnFRInfo_11111nJBasicType_1pnICodeStub__v_; text: .text%__1cIValueGenMdo_Intrinsic6MpnJIntrinsic__v_; text: .text%__1cIValueGenMdo_ArrayCopy6MpnJIntrinsic__v_; @@ -4209,12 +4209,12 @@ text: .text%__1cLInstructionNdeclared_type6kM_pnGciType__: c1_Instruction.o; text: .text%__1cRpositive_constant6FpnLInstruction__i_: c1_CodeGenerator.o; text: .text%__1cLArrayLengthOas_ArrayLength6M_p0_: c1_GraphBuilder.o; text: .text%__1cQis_constant_zero6FpnLInstruction__i_: c1_CodeGenerator.o; -text: .text%__1cILIR_ListJarraycopy6MpnLLIR_OprDesc_22222pnMciArrayKlass_ipnMCodeEmitInfo__v_: c1_CodeGenerator_i486.o; +text: .text%__1cILIR_ListJarraycopy6MpnLLIR_OprDesc_22222pnMciArrayKlass_ipnMCodeEmitInfo__v_: c1_CodeGenerator_x86.o; text: .text%__1cLLIR_EmitterNwrite_barrier6MpnLLIR_OprDesc_2_v_; -text: .text%__1cILIR_ListUunsigned_shift_right6MnFRInfo_i1_v_: c1_LIREmitter_i486.o; +text: .text%__1cILIR_ListUunsigned_shift_right6MnFRInfo_i1_v_: c1_LIREmitter_x86.o; text: .text%__1cILIR_ListUunsigned_shift_right6MpnLLIR_OprDesc_222_v_; text: .text%__1cQLIR_OpAllocArrayFvisit6MpnQLIR_OpVisitState__v_; -text: .text%__1cQNewTypeArrayStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_i486.o; +text: .text%__1cQNewTypeArrayStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; text: .text%__1cPLIR_OpArrayCopyFvisit6MpnQLIR_OpVisitState__v_; text: .text%__1cQLIR_OpAllocArrayJemit_code6MpnVLIR_AbstractAssembler__v_; text: .text%__1cNLIR_OptimizerQemit_alloc_array6MpnQLIR_OpAllocArray__v_; @@ -4229,12 +4229,12 @@ text: .text%__1cNLIR_AssemblerQemit_alloc_array6MpnQLIR_OpAllocArray__v_; text: .text%__1cNLIR_AssemblerSarray_element_size6kMnJBasicType__nHAddressLScaleFactor__; text: .text%__1cRC1_MacroAssemblerOallocate_array6MpnMRegisterImpl_222inHAddressLScaleFactor_2rnFLabel__v_; text: .text%__1cRC1_MacroAssemblerMtry_allocate6MpnMRegisterImpl_2i22rnFLabel__v_; -text: .text%__1cQNewTypeArrayStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_i486.o; +text: .text%__1cQNewTypeArrayStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; text: .text%__1cNLIR_AssemblerOemit_arraycopy6MpnPLIR_OpArrayCopy__v_; text: .text%__1cMciArrayKlassMelement_type6M_pnGciType__; text: .text%__1cNArrayCopyStub2t6MpnMCodeEmitInfo_pnOStaticCallStub__v_; text: .text%__1cFRInfoMset_word_reg6MkpnMRegisterImpl__v_; -text: .text%__1cNArrayCopyStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_i486.o; +text: .text%__1cNArrayCopyStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; text: .text%__1cNLIR_AssemblerOpush_parameter6MpnMRegisterImpl_i_v_; text: .text%__1cQNewTypeArrayStubJemit_code6MpnNLIR_Assembler__v_; text: .text%__1cNArrayCopyStubJemit_code6MpnNLIR_Assembler__v_; @@ -4295,14 +4295,14 @@ text: .text%__1cLLIR_EmitterIshift_op6MnJBytecodesECode_nFRInfo_pnLLIR_OprDesc_5 text: .text%__1cILIR_ListKshift_left6MnFRInfo_i1_v_: c1_LIREmitter.o; text: .text%__1cILIR_ListKlogical_or6MnFRInfo_pnLLIR_OprDesc_1_v_: c1_LIREmitter.o; text: .text%__1cOLIR_OpAllocObjFvisit6MpnQLIR_OpVisitState__v_; -text: .text%__1cSNewObjectArrayStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_i486.o; +text: .text%__1cSNewObjectArrayStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; text: .text%__1cOLIR_OpAllocObjJemit_code6MpnVLIR_AbstractAssembler__v_; text: .text%__1cNLIR_OptimizerOemit_alloc_obj6MpnOLIR_OpAllocObj__v_; text: .text%__1cNLIR_AssemblerOemit_alloc_obj6MpnOLIR_OpAllocObj__v_; text: .text%__1cRC1_MacroAssemblerPallocate_object6MpnMRegisterImpl_22ii2rnFLabel__v_; text: .text%__1cNLIR_AssemblerOmembar_release6M_v_; text: .text%__1cNLIR_AssemblerGmembar6M_v_; -text: .text%__1cSNewObjectArrayStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_i486.o; +text: .text%__1cSNewObjectArrayStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; text: .text%__1cNLIR_AssemblerOmembar_acquire6M_v_; text: .text%__1cEBaseHas_Base6M_p0_: c1_IR.o; text: .text%__1cNLIR_AssemblerOemit_osr_entry6MpnHIRScope_ipnFLabel_i_v_; @@ -4708,11 +4708,11 @@ text: .text%__1cILIR_ListLshift_right6MpnLLIR_OprDesc_222_v_; text: .text%__1cIValueGenLdo_NegateOp6MpnINegateOp__v_; text: .text%__1cLLIR_EmitterGnegate6MnFRInfo_pnLLIR_OprDesc__v_; text: .text%__1cILIR_ListGnegate6MnFRInfo_1_v_: c1_LIREmitter.o; -text: .text%__1cXArrayStoreExceptionStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_i486.o; -text: .text%__1cXArrayStoreExceptionStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_i486.o; +text: .text%__1cXArrayStoreExceptionStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; +text: .text%__1cXArrayStoreExceptionStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; text: .text%__1cNLIR_AssemblerEleal6MpnLLIR_OprDesc_2_v_; text: .text%__1cNLIR_AssemblerGnegate6MpnLLIR_OprDesc_2_v_; -text: .text%__1cNCodeStubArrayIindex_of6kMkpnICodeStub__i_: c1_LIRAssembler_i486.o; +text: .text%__1cNCodeStubArrayIindex_of6kMkpnICodeStub__i_: c1_LIRAssembler_x86.o; text: .text%__1cXArrayStoreExceptionStubJemit_code6MpnNLIR_Assembler__v_; text: .text%__1cIRuntime1Tresolve_static_call6FpnKJavaThread_pnHoopDesc__pC_; text: .text%__1cSCompiledStaticCallNcompute_entry6FnMmethodHandle_rnOStaticCallInfo__v_; @@ -4788,7 +4788,7 @@ text: .text%__1cNLIR_AssemblerIfpu_push6MnFRInfo__v_; text: .text%__1cIFrameMapLFpuStackSimEpush6Mi_v_; text: .text%__1cNLIR_AssemblerKfpu_on_tos6MnFRInfo__v_; text: .text%__1cIFrameMapLFpuStackSimPoffset_from_tos6kMi_i_; -text: .text%__1cIintArrayIindex_of6kMki_i_: c1_FrameMap_i486.o; +text: .text%__1cIintArrayIindex_of6kMki_i_: c1_FrameMap_x86.o; text: .text%__1cNLIR_AssemblerHfpu_pop6MnFRInfo__v_; text: .text%__1cIFrameMapLFpuStackSimDpop6Mi_i_; text: .text%__1cNLIR_AssemblerKround32_op6MpnLLIR_OprDesc_2_v_; @@ -4797,7 +4797,7 @@ text: .text%__1cNLIR_AssemblerJreset_FPU6M_v_; text: .text%__1cNLIR_AssemblerIemit_op36MpnHLIR_Op3__v_; text: .text%__1cNLIR_AssemblerParithmetic_idiv6MnILIR_Code_pnLLIR_OprDesc_333pnMCodeEmitInfo__v_; text: .text%__1cNLIR_AssemblerXadd_debug_info_for_div06MipnMCodeEmitInfo__v_; -text: .text%__1cNDivByZeroStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_i486.o; +text: .text%__1cNDivByZeroStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; text: .text%__1cNDivByZeroStubJemit_code6MpnNLIR_Assembler__v_; text: .text%__1cIciObjectSis_obj_array_klass6M_i_: ciTypeArrayKlass.o; text: .text%__1cLInstructionOas_ArrayLength6M_pnLArrayLength__: c1_GraphBuilder.o; @@ -4874,12 +4874,12 @@ text: .text%__1cFKlassQup_cast_abstract6M_p0_; text: .text%__1cRComputeEntryStackHdo_byte6M_v_: generateOopMap.o; text: .text%__1cNSharedRuntimeDd2i6Fd_i_; text: .text%__1cSInterpreterRuntimeWslow_signature_handler6FpnKJavaThread_pnNmethodOopDesc_pi5_pC_; -text: .text%__1cXNativeSignatureIteratorJdo_object6Mii_v_: interpreterRT_i486.o; -text: .text%__1cUSlowSignatureHandlerLpass_object6M_v_: interpreterRT_i486.o; -text: .text%__1cXNativeSignatureIteratorIdo_array6Mii_v_: interpreterRT_i486.o; -text: .text%__1cXNativeSignatureIteratorGdo_int6M_v_: interpreterRT_i486.o; -text: .text%__1cUSlowSignatureHandlerIpass_int6M_v_: interpreterRT_i486.o; -text: .text%__1cXNativeSignatureIteratorHdo_bool6M_v_: interpreterRT_i486.o; +text: .text%__1cXNativeSignatureIteratorJdo_object6Mii_v_: interpreterRT_x86.o; +text: .text%__1cUSlowSignatureHandlerLpass_object6M_v_: interpreterRT_x86.o; +text: .text%__1cXNativeSignatureIteratorIdo_array6Mii_v_: interpreterRT_x86.o; +text: .text%__1cXNativeSignatureIteratorGdo_int6M_v_: interpreterRT_x86.o; +text: .text%__1cUSlowSignatureHandlerIpass_int6M_v_: interpreterRT_x86.o; +text: .text%__1cXNativeSignatureIteratorHdo_bool6M_v_: interpreterRT_x86.o; text: .text%jni_GetFloatArrayRegion: jni.o; text: .text%jni_GetCharArrayRegion: jni.o; text: .text%jni_SetFloatField: jni.o; @@ -4906,8 +4906,8 @@ text: .text%__1cLLIR_EmitterQreturn_op_prolog6Mi_v_; text: .text%__1cLLIR_EmitterMmonitor_exit6MnFRInfo_11i_v_; text: .text%__1cILIR_ListNunlock_object6MnFRInfo_11pnICodeStub__v_; text: .text%__1cKLIR_OpLockFvisit6MpnQLIR_OpVisitState__v_; -text: .text%__1cQMonitorEnterStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_i486.o; -text: .text%__1cRMonitorAccessStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_i486.o; +text: .text%__1cQMonitorEnterStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; +text: .text%__1cRMonitorAccessStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; text: .text%__1cKLIR_OpLockJemit_code6MpnVLIR_AbstractAssembler__v_; text: .text%__1cNLIR_OptimizerJemit_lock6MpnKLIR_OpLock__v_; text: .text%__1cNLIR_AssemblerPmonitor_address6MinFRInfo__v_; @@ -4915,7 +4915,7 @@ text: .text%__1cIFrameMapbEaddress_for_monitor_lock_index6kMi_nHAddress__; text: .text%__1cIFrameMapbAfp_offset_for_monitor_lock6kMi_i_; text: .text%__1cNLIR_AssemblerJemit_lock6MpnKLIR_OpLock__v_; text: .text%__1cRC1_MacroAssemblerLlock_object6MpnMRegisterImpl_22rnFLabel__v_; -text: .text%__1cQMonitorEnterStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_i486.o; +text: .text%__1cQMonitorEnterStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; text: .text%__1cIFrameMapWmonitor_object_regname6kMi_nHOptoRegEName__; text: .text%__1cIFrameMapbCfp_offset_for_monitor_object6kMi_i_; text: .text%__1cMCodeEmitInfobHlocation_for_monitor_object_index6Mi_nILocation__; @@ -4925,7 +4925,7 @@ text: .text%__1cIFrameMapbFlocation_for_monitor_lock_index6kMipnILocation__i_; text: .text%__1cMMonitorValue2t6MpnKScopeValue_nILocation__v_; text: .text%__1cMMonitorValueIwrite_on6MpnUDebugInfoWriteStream__v_; text: .text%__1cRC1_MacroAssemblerNunlock_object6MpnMRegisterImpl_22rnFLabel__v_; -text: .text%__1cPMonitorExitStubMis_call_stub6kM_i_: c1_CodeStubs_i486.o; +text: .text%__1cPMonitorExitStubMis_call_stub6kM_i_: c1_CodeStubs_x86.o; text: .text%__1cQMonitorEnterStubJemit_code6MpnNLIR_Assembler__v_; text: .text%__1cNLIR_AssemblerRload_receiver_reg6MpnMRegisterImpl__v_; text: .text%__1cNLIR_AssemblerLmonitorexit6MnFRInfo_1pnMRegisterImpl_i3_v_; @@ -5168,7 +5168,7 @@ text: .text%__1cFRInfoOas_register_lo6kM_pnMRegisterImpl__; text: .text%__1cCosHrealloc6FpvI_1_; text: .text%Unsafe_GetNativeFloat; text: .text%__1cIValueGenQdo_currentThread6MpnJIntrinsic__v_; -text: .text%__1cILIR_ListKget_thread6MnFRInfo__v_: c1_CodeGenerator_i486.o; +text: .text%__1cILIR_ListKget_thread6MnFRInfo__v_: c1_CodeGenerator_x86.o; text: .text%__1cNLIR_AssemblerKget_thread6MpnLLIR_OprDesc__v_; text: .text%__1cIValueGenSload_item_patching6MpnHIRScope_ipnEItem_pnKValueStack_pnOExceptionScope__v_; text: .text%__1cEItemUget_jobject_constant6kM_pnIciObject__; @@ -5246,7 +5246,7 @@ text: .text%__1cGThreadLnmethods_do6M_v_; text: .text%__1cFframeLnmethods_do6M_v_; text: .text%__1cFframeVnmethods_code_blob_do6M_v_; text: .text%__1cILIR_ListEidiv6MnFRInfo_i11pnMCodeEmitInfo__v_; -text: .text%__1cLlog2_intptr6Fi_i_: c1_LIRAssembler_i486.o; +text: .text%__1cLlog2_intptr6Fi_i_: c1_LIRAssembler_x86.o; text: .text%__1cONMethodSweeperPprocess_nmethod6FpnHnmethod__v_; text: .text%__1cHnmethodPis_locked_by_vm6kM_i_: nmethod.o; text: .text%__1cHnmethodLis_unloaded6kM_i_: nmethod.o; @@ -5423,13 +5423,13 @@ text: .text%__1cIValueGenPdo_UnsafeGetRaw6MpnMUnsafeGetRaw__v_; text: .text%__1cLLIR_EmitterOget_raw_unsafe6MnFRInfo_pnLLIR_OprDesc_3inJBasicType__v_; text: .text%__1cILIR_ListMload_mem_reg6MpnLLIR_Address_nFRInfo_nJBasicType_pnMCodeEmitInfo_nHLIR_Op1NLIR_PatchCode__v_; text: .text%__1cIValueGenPdo_LookupSwitch6MpnMLookupSwitch__v_; -text: .text%__1cUcreate_lookup_ranges6FpnMLookupSwitch__pnQLookupRangeArray__: c1_CodeGenerator_i486.o; +text: .text%__1cUcreate_lookup_ranges6FpnMLookupSwitch__pnQLookupRangeArray__: c1_CodeGenerator_x86.o; text: .text%__1cLLIR_EmitterVlookupswitch_range_op6MpnLLIR_OprDesc_iipnKBlockBegin__v_; text: .text%__1cNSharedRuntimeEldiv6Fxx_x_; text: .text%Unsafe_GetObjectVolatile; text: .text%signalHandler; text: .text%JVM_handle_solaris_signal; -text: .text%__1cKJavaThreadUin_stack_yellow_zone6MpC_i_: os_solaris_i486.o; +text: .text%__1cKJavaThreadUin_stack_yellow_zone6MpC_i_: os_solaris_x86.o; text: .text%__1cICodeBlobRis_at_poll_return6MpC_i_; text: .text%__1cUSafepointSynchronizebDhandle_polling_page_exception6FpnKJavaThread__pC_; text: .text%__1cbCCompiledCodeSafepointHandlerbDhandle_polling_page_exception6M_pC_; diff --git a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp index d5696d442f4..6d941c36866 100644 --- a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp @@ -956,7 +956,8 @@ void LIRGenerator::do_NewMultiArray(NewMultiArray* x) { size->load_item(); store_stack_parameter (size->result(), in_ByteSize(STACK_BIAS + - (i + frame::memory_parameter_word_sp_offset) * wordSize)); + frame::memory_parameter_word_sp_offset * wordSize + + i * sizeof(jint))); } // This instruction can be deoptimized in the slow path : use diff --git a/hotspot/src/cpu/sparc/vm/relocInfo_sparc.cpp b/hotspot/src/cpu/sparc/vm/relocInfo_sparc.cpp index 795e1831e52..ab365558201 100644 --- a/hotspot/src/cpu/sparc/vm/relocInfo_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/relocInfo_sparc.cpp @@ -204,3 +204,9 @@ void Relocation::pd_swap_out_breakpoint(address x, short* instrs, int instrlen) NativeInstruction* ni = nativeInstruction_at(x); ni->set_long_at(0, u.l); } + +void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { +} + +void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { +} diff --git a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp index 3812e2eaed9..6fed65b3ddc 100644 --- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp @@ -465,9 +465,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, case T_LONG: assert(sig_bt[i+1] == T_VOID, "expecting VOID in other half"); -#ifdef COMPILER2 #ifdef _LP64 - // Can't be tiered (yet) if (int_reg < int_reg_max) { Register r = is_outgoing ? as_oRegister(int_reg++) : as_iRegister(int_reg++); regs[i].set2(r->as_VMReg()); @@ -476,11 +474,12 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, stk_reg_pairs += 2; } #else +#ifdef COMPILER2 // For 32-bit build, can't pass longs in O-regs because they become // I-regs and get trashed. Use G-regs instead. G1 and G4 are almost // spare and available. This convention isn't used by the Sparc ABI or // anywhere else. If we're tiered then we don't use G-regs because c1 - // can't deal with them as a "pair". + // can't deal with them as a "pair". (Tiered makes this code think g's are filled) // G0: zero // G1: 1st Long arg // G2: global allocated to TLS @@ -500,7 +499,6 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, regs[i].set2(VMRegImpl::stack2reg(stk_reg_pairs)); stk_reg_pairs += 2; } -#endif // _LP64 #else // COMPILER2 if (int_reg_pairs + 1 < int_reg_max) { if (is_outgoing) { @@ -514,6 +512,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, stk_reg_pairs += 2; } #endif // COMPILER2 +#endif // _LP64 break; case T_FLOAT: @@ -699,17 +698,16 @@ Register AdapterGenerator::next_arg_slot(const int st_off){ // Stores long into offset pointed to by base void AdapterGenerator::store_c2i_long(Register r, Register base, const int st_off, bool is_stack) { -#ifdef COMPILER2 #ifdef _LP64 // In V9, longs are given 2 64-bit slots in the interpreter, but the // data is passed in only 1 slot. __ stx(r, base, next_arg_slot(st_off)); #else +#ifdef COMPILER2 // Misaligned store of 64-bit data __ stw(r, base, arg_slot(st_off)); // lo bits __ srlx(r, 32, r); __ stw(r, base, next_arg_slot(st_off)); // hi bits -#endif // _LP64 #else if (is_stack) { // Misaligned store of 64-bit data @@ -721,6 +719,7 @@ void AdapterGenerator::store_c2i_long(Register r, Register base, __ stw(r , base, next_arg_slot(st_off)); // hi bits } #endif // COMPILER2 +#endif // _LP64 tag_c2i_arg(frame::TagCategory2, base, st_off, r); } @@ -1637,7 +1636,7 @@ static void long_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { } } else if (dst.is_single_phys_reg()) { if (src.is_adjacent_aligned_on_stack(2)) { - __ ld_long(FP, reg2offset(src.first()) + STACK_BIAS, dst.first()->as_Register()); + __ ldx(FP, reg2offset(src.first()) + STACK_BIAS, dst.first()->as_Register()); } else { // dst is a single reg. // Remember lo is low address not msb for stack slots @@ -1811,7 +1810,6 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm, VMRegPair *in_regs, BasicType ret_type) { - // Native nmethod wrappers never take possesion of the oop arguments. // So the caller will gc the arguments. The only thing we need an // oopMap for is if the call is static diff --git a/hotspot/src/cpu/x86/vm/assembler_x86_64.cpp b/hotspot/src/cpu/x86/vm/assembler_x86.cpp similarity index 58% rename from hotspot/src/cpu/x86/vm/assembler_x86_64.cpp rename to hotspot/src/cpu/x86/vm/assembler_x86.cpp index 431c233df73..d8bc4948c92 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-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 @@ -23,7 +23,7 @@ */ #include "incls/_precompiled.incl" -#include "incls/_assembler_x86_64.cpp.incl" +#include "incls/_assembler_x86.cpp.incl" // Implementation of AddressLiteral @@ -52,6 +52,10 @@ AddressLiteral::AddressLiteral(address target, relocInfo::relocType rtype) { case relocInfo::runtime_call_type: _rspec = runtime_call_Relocation::spec(); break; + case relocInfo::poll_type: + case relocInfo::poll_return_type: + _rspec = Relocation::spec_simple(rtype); + break; case relocInfo::none: break; default: @@ -62,20 +66,13 @@ AddressLiteral::AddressLiteral(address target, relocInfo::relocType rtype) { // Implementation of Address -Address Address::make_array(ArrayAddress adr) { #ifdef _LP64 + +Address Address::make_array(ArrayAddress adr) { // Not implementable on 64bit machines // Should have been handled higher up the call chain. ShouldNotReachHere(); return Address(); -#else - AddressLiteral base = adr.base(); - Address index = adr.index(); - assert(index._disp == 0, "must not have disp"); // maybe it can? - Address array(index._base, index._index, index._scale, (intptr_t) base.target()); - array._rspec = base._rspec; - return array; -#endif // _LP64 } // exceedingly dangerous constructor @@ -95,12 +92,39 @@ Address::Address(int disp, address loc, relocInfo::relocType rtype) { // HMM _rspec = runtime_call_Relocation::spec(); break; + case relocInfo::poll_type: + case relocInfo::poll_return_type: + _rspec = Relocation::spec_simple(rtype); + break; case relocInfo::none: break; default: ShouldNotReachHere(); } } +#else // LP64 + +Address Address::make_array(ArrayAddress adr) { + AddressLiteral base = adr.base(); + Address index = adr.index(); + assert(index._disp == 0, "must not have disp"); // maybe it can? + Address array(index._base, index._index, index._scale, (intptr_t) base.target()); + array._rspec = base._rspec; + return array; +} + +// exceedingly dangerous constructor +Address::Address(address loc, RelocationHolder spec) { + _base = noreg; + _index = noreg; + _scale = no_scale; + _disp = (intptr_t) loc; + _rspec = spec; +} + +#endif // _LP64 + + // Convert the raw encoding form into the form expected by the constructor for // Address. An index of 4 (rsp) corresponds to having no index, so convert @@ -116,89 +140,21 @@ Address Address::make_raw(int base, int index, int scale, int disp) { } } - // Implementation of Assembler + int AbstractAssembler::code_fill_byte() { return (u_char)'\xF4'; // hlt } -// This should only be used by 64bit instructions that can use rip-relative -// it cannot be used by instructions that want an immediate value. - -bool Assembler::reachable(AddressLiteral adr) { - int64_t disp; - - // None will force a 64bit literal to the code stream. Likely a placeholder - // for something that will be patched later and we need to certain it will - // always be reachable. - if (adr.reloc() == relocInfo::none) { - return false; - } - if (adr.reloc() == relocInfo::internal_word_type) { - // This should be rip relative and easily reachable. - return true; - } - if (adr.reloc() != relocInfo::external_word_type && - adr.reloc() != relocInfo::runtime_call_type ) { - return false; - } - - // Stress the correction code - if (ForceUnreachable) { - // Must be runtimecall reloc, see if it is in the codecache - // Flipping stuff in the codecache to be unreachable causes issues - // with things like inline caches where the additional instructions - // are not handled. - if (CodeCache::find_blob(adr._target) == NULL) { - return false; - } - } - // For external_word_type/runtime_call_type if it is reachable from where we - // are now (possibly a temp buffer) and where we might end up - // anywhere in the codeCache then we are always reachable. - // This would have to change if we ever save/restore shared code - // to be more pessimistic. - - disp = (int64_t)adr._target - ((int64_t)CodeCache::low_bound() + sizeof(int)); - if (!is_simm32(disp)) return false; - disp = (int64_t)adr._target - ((int64_t)CodeCache::high_bound() + sizeof(int)); - if (!is_simm32(disp)) return false; - - disp = (int64_t)adr._target - ((int64_t)_code_pos + sizeof(int)); - - // Because rip relative is a disp + address_of_next_instruction and we - // don't know the value of address_of_next_instruction we apply a fudge factor - // to make sure we will be ok no matter the size of the instruction we get placed into. - // We don't have to fudge the checks above here because they are already worst case. - - // 12 == override/rex byte, opcode byte, rm byte, sib byte, a 4-byte disp , 4-byte literal - // + 4 because better safe than sorry. - const int fudge = 12 + 4; - if (disp < 0) { - disp -= fudge; - } else { - disp += fudge; - } - return is_simm32(disp); +// make this go away someday +void Assembler::emit_data(jint data, relocInfo::relocType rtype, int format) { + if (rtype == relocInfo::none) + emit_long(data); + else emit_data(data, Relocation::spec_simple(rtype), format); } - -// make this go away eventually -void Assembler::emit_data(jint data, - relocInfo::relocType rtype, - int format) { - if (rtype == relocInfo::none) { - emit_long(data); - } else { - emit_data(data, Relocation::spec_simple(rtype), format); - } -} - -void Assembler::emit_data(jint data, - RelocationHolder const& rspec, - int format) { - assert(imm64_operand == 0, "default format must be imm64 in this file"); - assert(imm64_operand != format, "must not be imm64"); +void Assembler::emit_data(jint data, RelocationHolder const& rspec, int format) { + assert(imm_operand == 0, "default format must be immediate in this file"); assert(inst_mark() != NULL, "must be inside InstructionMark"); if (rspec.type() != relocInfo::none) { #ifdef ASSERT @@ -216,67 +172,50 @@ void Assembler::emit_data(jint data, emit_long(data); } -void Assembler::emit_data64(jlong data, - relocInfo::relocType rtype, - int format) { - if (rtype == relocInfo::none) { - emit_long64(data); - } else { - emit_data64(data, Relocation::spec_simple(rtype), format); +static int encode(Register r) { + int enc = r->encoding(); + if (enc >= 8) { + enc -= 8; } + return enc; } -void Assembler::emit_data64(jlong data, - RelocationHolder const& rspec, - int format) { - assert(imm64_operand == 0, "default format must be imm64 in this file"); - assert(imm64_operand == format, "must be imm64"); - assert(inst_mark() != NULL, "must be inside InstructionMark"); - // Do not use AbstractAssembler::relocate, which is not intended for - // embedded words. Instead, relocate to the enclosing instruction. - code_section()->relocate(inst_mark(), rspec, format); -#ifdef ASSERT - check_relocation(rspec, format); -#endif - emit_long64(data); +static int encode(XMMRegister r) { + int enc = r->encoding(); + if (enc >= 8) { + enc -= 8; + } + return enc; } void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) { + assert(dst->has_byte_register(), "must have byte register"); assert(isByte(op1) && isByte(op2), "wrong opcode"); assert(isByte(imm8), "not a byte"); assert((op1 & 0x01) == 0, "should be 8bit operation"); - int dstenc = dst->encoding(); - if (dstenc >= 8) { - dstenc -= 8; - } emit_byte(op1); - emit_byte(op2 | dstenc); + emit_byte(op2 | encode(dst)); emit_byte(imm8); } -void Assembler::emit_arith(int op1, int op2, Register dst, int imm32) { + +void Assembler::emit_arith(int op1, int op2, Register dst, int32_t imm32) { assert(isByte(op1) && isByte(op2), "wrong opcode"); assert((op1 & 0x01) == 1, "should be 32bit operation"); assert((op1 & 0x02) == 0, "sign-extension bit should not be set"); - int dstenc = dst->encoding(); - if (dstenc >= 8) { - dstenc -= 8; - } if (is8bit(imm32)) { emit_byte(op1 | 0x02); // set sign bit - emit_byte(op2 | dstenc); + emit_byte(op2 | encode(dst)); emit_byte(imm32 & 0xFF); } else { emit_byte(op1); - emit_byte(op2 | dstenc); + emit_byte(op2 | encode(dst)); emit_long(imm32); } } // immediate-to-memory forms -void Assembler::emit_arith_operand(int op1, - Register rm, Address adr, - int imm32) { +void Assembler::emit_arith_operand(int op1, Register rm, Address adr, int32_t imm32) { assert((op1 & 0x01) == 1, "should be 32bit operation"); assert((op1 & 0x02) == 0, "sign-extension bit should not be set"); if (is8bit(imm32)) { @@ -290,127 +229,117 @@ void Assembler::emit_arith_operand(int op1, } } +void Assembler::emit_arith(int op1, int op2, Register dst, jobject obj) { + LP64_ONLY(ShouldNotReachHere()); + assert(isByte(op1) && isByte(op2), "wrong opcode"); + assert((op1 & 0x01) == 1, "should be 32bit operation"); + assert((op1 & 0x02) == 0, "sign-extension bit should not be set"); + InstructionMark im(this); + emit_byte(op1); + emit_byte(op2 | encode(dst)); + emit_data((intptr_t)obj, relocInfo::oop_type, 0); +} + void Assembler::emit_arith(int op1, int op2, Register dst, Register src) { assert(isByte(op1) && isByte(op2), "wrong opcode"); - int dstenc = dst->encoding(); - int srcenc = src->encoding(); - if (dstenc >= 8) { - dstenc -= 8; - } - if (srcenc >= 8) { - srcenc -= 8; - } emit_byte(op1); - emit_byte(op2 | dstenc << 3 | srcenc); + emit_byte(op2 | encode(dst) << 3 | encode(src)); } + void Assembler::emit_operand(Register reg, Register base, Register index, Address::ScaleFactor scale, int disp, RelocationHolder const& rspec, int rip_relative_correction) { relocInfo::relocType rtype = (relocInfo::relocType) rspec.type(); - int regenc = reg->encoding(); - if (regenc >= 8) { - regenc -= 8; - } + + // Encode the registers as needed in the fields they are used in + + int regenc = encode(reg) << 3; + int indexenc = index->is_valid() ? encode(index) << 3 : 0; + int baseenc = base->is_valid() ? encode(base) : 0; + if (base->is_valid()) { if (index->is_valid()) { assert(scale != Address::no_scale, "inconsistent address"); - int indexenc = index->encoding(); - if (indexenc >= 8) { - indexenc -= 8; - } - int baseenc = base->encoding(); - if (baseenc >= 8) { - baseenc -= 8; - } // [base + index*scale + disp] if (disp == 0 && rtype == relocInfo::none && - base != rbp && base != r13) { + base != rbp LP64_ONLY(&& base != r13)) { // [base + index*scale] // [00 reg 100][ss index base] assert(index != rsp, "illegal addressing mode"); - emit_byte(0x04 | regenc << 3); - emit_byte(scale << 6 | indexenc << 3 | baseenc); + emit_byte(0x04 | regenc); + emit_byte(scale << 6 | indexenc | baseenc); } else if (is8bit(disp) && rtype == relocInfo::none) { // [base + index*scale + imm8] // [01 reg 100][ss index base] imm8 assert(index != rsp, "illegal addressing mode"); - emit_byte(0x44 | regenc << 3); - emit_byte(scale << 6 | indexenc << 3 | baseenc); + emit_byte(0x44 | regenc); + emit_byte(scale << 6 | indexenc | baseenc); emit_byte(disp & 0xFF); } else { // [base + index*scale + disp32] // [10 reg 100][ss index base] disp32 assert(index != rsp, "illegal addressing mode"); - emit_byte(0x84 | regenc << 3); - emit_byte(scale << 6 | indexenc << 3 | baseenc); + emit_byte(0x84 | regenc); + emit_byte(scale << 6 | indexenc | baseenc); emit_data(disp, rspec, disp32_operand); } - } else if (base == rsp || base == r12) { + } else if (base == rsp LP64_ONLY(|| base == r12)) { // [rsp + disp] if (disp == 0 && rtype == relocInfo::none) { // [rsp] // [00 reg 100][00 100 100] - emit_byte(0x04 | regenc << 3); + emit_byte(0x04 | regenc); emit_byte(0x24); } else if (is8bit(disp) && rtype == relocInfo::none) { // [rsp + imm8] // [01 reg 100][00 100 100] disp8 - emit_byte(0x44 | regenc << 3); + emit_byte(0x44 | regenc); emit_byte(0x24); emit_byte(disp & 0xFF); } else { // [rsp + imm32] // [10 reg 100][00 100 100] disp32 - emit_byte(0x84 | regenc << 3); + emit_byte(0x84 | regenc); emit_byte(0x24); emit_data(disp, rspec, disp32_operand); } } else { // [base + disp] - assert(base != rsp && base != r12, "illegal addressing mode"); - int baseenc = base->encoding(); - if (baseenc >= 8) { - baseenc -= 8; - } + assert(base != rsp LP64_ONLY(&& base != r12), "illegal addressing mode"); if (disp == 0 && rtype == relocInfo::none && - base != rbp && base != r13) { + base != rbp LP64_ONLY(&& base != r13)) { // [base] // [00 reg base] - emit_byte(0x00 | regenc << 3 | baseenc); + emit_byte(0x00 | regenc | baseenc); } else if (is8bit(disp) && rtype == relocInfo::none) { // [base + disp8] // [01 reg base] disp8 - emit_byte(0x40 | regenc << 3 | baseenc); + emit_byte(0x40 | regenc | baseenc); emit_byte(disp & 0xFF); } else { // [base + disp32] // [10 reg base] disp32 - emit_byte(0x80 | regenc << 3 | baseenc); + emit_byte(0x80 | regenc | baseenc); emit_data(disp, rspec, disp32_operand); } } } else { if (index->is_valid()) { assert(scale != Address::no_scale, "inconsistent address"); - int indexenc = index->encoding(); - if (indexenc >= 8) { - indexenc -= 8; - } // [index*scale + disp] // [00 reg 100][ss index 101] disp32 assert(index != rsp, "illegal addressing mode"); - emit_byte(0x04 | regenc << 3); - emit_byte(scale << 6 | indexenc << 3 | 0x05); + emit_byte(0x04 | regenc); + emit_byte(scale << 6 | indexenc | 0x05); emit_data(disp, rspec, disp32_operand); -#ifdef _LP64 } else if (rtype != relocInfo::none ) { - // [disp] RIP-RELATIVE + // [disp] (64bit) RIP-RELATIVE (32bit) abs // [00 000 101] disp32 - emit_byte(0x05 | regenc << 3); + emit_byte(0x05 | regenc); // Note that the RIP-rel. correction applies to the generated // disp field, but _not_ to the target address in the rspec. @@ -419,16 +348,18 @@ void Assembler::emit_operand(Register reg, Register base, Register index, // intptr_t disp = target - next_ip; assert(inst_mark() != NULL, "must be inside InstructionMark"); address next_ip = pc() + sizeof(int32_t) + rip_relative_correction; - int64_t adjusted = (int64_t) disp - (next_ip - inst_mark()); + int64_t adjusted = disp; + // Do rip-rel adjustment for 64bit + LP64_ONLY(adjusted -= (next_ip - inst_mark())); assert(is_simm32(adjusted), "must be 32bit offset (RIP relative address)"); - emit_data((int) adjusted, rspec, disp32_operand); + emit_data((int32_t) adjusted, rspec, disp32_operand); -#endif // _LP64 } else { + // 32bit never did this, did everything as the rip-rel/disp code above // [disp] ABSOLUTE // [00 reg 100][00 100 101] disp32 - emit_byte(0x04 | regenc << 3); + emit_byte(0x04 | regenc); emit_byte(0x25); emit_data(disp, rspec, disp32_operand); } @@ -437,132 +368,8 @@ void Assembler::emit_operand(Register reg, Register base, Register index, void Assembler::emit_operand(XMMRegister reg, Register base, Register index, Address::ScaleFactor scale, int disp, - RelocationHolder const& rspec, - int rip_relative_correction) { - relocInfo::relocType rtype = (relocInfo::relocType) rspec.type(); - int regenc = reg->encoding(); - if (regenc >= 8) { - regenc -= 8; - } - if (base->is_valid()) { - if (index->is_valid()) { - assert(scale != Address::no_scale, "inconsistent address"); - int indexenc = index->encoding(); - if (indexenc >= 8) { - indexenc -= 8; - } - int baseenc = base->encoding(); - if (baseenc >= 8) { - baseenc -= 8; - } - // [base + index*scale + disp] - if (disp == 0 && rtype == relocInfo::none && - base != rbp && base != r13) { - // [base + index*scale] - // [00 reg 100][ss index base] - assert(index != rsp, "illegal addressing mode"); - emit_byte(0x04 | regenc << 3); - emit_byte(scale << 6 | indexenc << 3 | baseenc); - } else if (is8bit(disp) && rtype == relocInfo::none) { - // [base + index*scale + disp8] - // [01 reg 100][ss index base] disp8 - assert(index != rsp, "illegal addressing mode"); - emit_byte(0x44 | regenc << 3); - emit_byte(scale << 6 | indexenc << 3 | baseenc); - emit_byte(disp & 0xFF); - } else { - // [base + index*scale + disp32] - // [10 reg 100][ss index base] disp32 - assert(index != rsp, "illegal addressing mode"); - emit_byte(0x84 | regenc << 3); - emit_byte(scale << 6 | indexenc << 3 | baseenc); - emit_data(disp, rspec, disp32_operand); - } - } else if (base == rsp || base == r12) { - // [rsp + disp] - if (disp == 0 && rtype == relocInfo::none) { - // [rsp] - // [00 reg 100][00 100 100] - emit_byte(0x04 | regenc << 3); - emit_byte(0x24); - } else if (is8bit(disp) && rtype == relocInfo::none) { - // [rsp + imm8] - // [01 reg 100][00 100 100] disp8 - emit_byte(0x44 | regenc << 3); - emit_byte(0x24); - emit_byte(disp & 0xFF); - } else { - // [rsp + imm32] - // [10 reg 100][00 100 100] disp32 - emit_byte(0x84 | regenc << 3); - emit_byte(0x24); - emit_data(disp, rspec, disp32_operand); - } - } else { - // [base + disp] - assert(base != rsp && base != r12, "illegal addressing mode"); - int baseenc = base->encoding(); - if (baseenc >= 8) { - baseenc -= 8; - } - if (disp == 0 && rtype == relocInfo::none && - base != rbp && base != r13) { - // [base] - // [00 reg base] - emit_byte(0x00 | regenc << 3 | baseenc); - } else if (is8bit(disp) && rtype == relocInfo::none) { - // [base + imm8] - // [01 reg base] disp8 - emit_byte(0x40 | regenc << 3 | baseenc); - emit_byte(disp & 0xFF); - } else { - // [base + imm32] - // [10 reg base] disp32 - emit_byte(0x80 | regenc << 3 | baseenc); - emit_data(disp, rspec, disp32_operand); - } - } - } else { - if (index->is_valid()) { - assert(scale != Address::no_scale, "inconsistent address"); - int indexenc = index->encoding(); - if (indexenc >= 8) { - indexenc -= 8; - } - // [index*scale + disp] - // [00 reg 100][ss index 101] disp32 - assert(index != rsp, "illegal addressing mode"); - emit_byte(0x04 | regenc << 3); - emit_byte(scale << 6 | indexenc << 3 | 0x05); - emit_data(disp, rspec, disp32_operand); -#ifdef _LP64 - } else if ( rtype != relocInfo::none ) { - // [disp] RIP-RELATIVE - // [00 reg 101] disp32 - emit_byte(0x05 | regenc << 3); - // Note that the RIP-rel. correction applies to the generated - // disp field, but _not_ to the target address in the rspec. - - // disp was created by converting the target address minus the pc - // at the start of the instruction. That needs more correction here. - // intptr_t disp = target - next_ip; - - assert(inst_mark() != NULL, "must be inside InstructionMark"); - address next_ip = pc() + sizeof(int32_t) + rip_relative_correction; - - int64_t adjusted = (int64_t) disp - (next_ip - inst_mark()); - assert(is_simm32(adjusted), - "must be 32bit offset (RIP relative address)"); - emit_data((int) adjusted, rspec, disp32_operand); -#endif // _LP64 - } else { - // [disp] ABSOLUTE - // [00 reg 100][00 100 101] disp32 - emit_byte(0x04 | regenc << 3); - emit_byte(0x25); - emit_data(disp, rspec, disp32_operand); - } - } + RelocationHolder const& rspec) { + emit_operand((Register)reg, base, index, scale, disp, rspec); } // Secret local extension to Assembler::WhichOperand: @@ -603,8 +410,9 @@ address Assembler::locate_operand(address inst, WhichOperand which) { case ES_segment: case FS_segment: case GS_segment: - assert(0, "shouldn't have that prefix"); - assert(ip == inst + 1 || ip == inst + 2, "only two prefixes allowed"); + // Seems dubious + LP64_ONLY(assert(false, "shouldn't have that prefix")); + assert(ip == inst+1, "only one prefix allowed"); goto again_after_prefix; case 0x67: @@ -616,7 +424,7 @@ address Assembler::locate_operand(address inst, WhichOperand which) { case REX_RB: case REX_RX: case REX_RXB: -// assert(ip == inst + 1, "only one prefix allowed"); + NOT_LP64(assert(false, "64bit prefixes")); goto again_after_prefix; case REX_W: @@ -627,8 +435,8 @@ address Assembler::locate_operand(address inst, WhichOperand which) { case REX_WRB: case REX_WRX: case REX_WRXB: + NOT_LP64(assert(false, "64bit prefixes")); is_64bit = true; -// assert(ip == inst + 1, "only one prefix allowed"); goto again_after_prefix; case 0xFF: // pushq a; decl a; incl a; call a; jmp a @@ -637,15 +445,15 @@ address Assembler::locate_operand(address inst, WhichOperand which) { case 0x8A: // movb r, a case 0x8B: // movl r, a case 0x8F: // popl a - debug_only(has_disp32 = true;) + debug_only(has_disp32 = true); break; case 0x68: // pushq #32 if (which == end_pc_operand) { return ip + 4; } - assert(0, "pushq has no disp32 or imm64"); - ShouldNotReachHere(); + assert(which == imm_operand && !is_64bit, "pushl has no disp32 or 64bit immediate"); + return ip; // not produced by emit_operand case 0x66: // movw ... (size prefix) again_after_size_prefix2: @@ -666,11 +474,14 @@ address Assembler::locate_operand(address inst, WhichOperand which) { case REX_WRB: case REX_WRX: case REX_WRXB: + NOT_LP64(assert(false, "64bit prefix found")); goto again_after_size_prefix2; case 0x8B: // movw r, a case 0x89: // movw a, r + debug_only(has_disp32 = true); break; case 0xC7: // movw a, #16 + debug_only(has_disp32 = true); tail_size = 2; // the imm16 break; case 0x0F: // several SSE/SSE2 variants @@ -683,8 +494,13 @@ address Assembler::locate_operand(address inst, WhichOperand which) { case REP8(0xB8): // movl/q r, #32/#64(oop?) if (which == end_pc_operand) return ip + (is_64bit ? 8 : 4); - assert((which == call32_operand || which == imm64_operand) && is_64bit || + // these asserts are somewhat nonsensical +#ifndef _LP64 + assert(which == imm_operand || which == disp32_operand, ""); +#else + assert((which == call32_operand || which == imm_operand) && is_64bit || which == narrow_oop_operand && !is_64bit, ""); +#endif // _LP64 return ip; case 0x69: // imul r, a, #32 @@ -700,18 +516,23 @@ address Assembler::locate_operand(address inst, WhichOperand which) { case 0x2E: // ucomiss case 0x2F: // comiss case 0x54: // andps + case 0x55: // andnps + case 0x56: // orps case 0x57: // xorps case 0x6E: // movd case 0x7E: // movd case 0xAE: // ldmxcsr a - debug_only(has_disp32 = true); // has both kinds of operands! + // 64bit side says it these have both operands but that doesn't + // appear to be true + debug_only(has_disp32 = true); break; + case 0xAD: // shrd r, a, %cl case 0xAF: // imul r, a - case 0xBE: // movsbl r, a - case 0xBF: // movswl r, a - case 0xB6: // movzbl r, a - case 0xB7: // movzwl r, a + case 0xBE: // movsbl r, a (movsxb) + case 0xBF: // movswl r, a (movsxw) + case 0xB6: // movzbl r, a (movzxb) + case 0xB7: // movzwl r, a (movzxw) case REP16(0x40): // cmovl cc, r, a case 0xB0: // cmpxchgb case 0xB1: // cmpxchg @@ -721,13 +542,15 @@ address Assembler::locate_operand(address inst, WhichOperand which) { debug_only(has_disp32 = true); // fall out of the switch to decode the address break; + case 0xAC: // shrd r, a, #8 debug_only(has_disp32 = true); tail_size = 1; // the imm8 break; + case REP16(0x80): // jcc rdisp32 if (which == end_pc_operand) return ip + 4; - assert(which == call32_operand, "jcc has no disp32 or imm64"); + assert(which == call32_operand, "jcc has no disp32 or imm"); return ip; default: ShouldNotReachHere(); @@ -736,6 +559,7 @@ address Assembler::locate_operand(address inst, WhichOperand which) { case 0x81: // addl a, #32; addl r, #32 // also: orl, adcl, sbbl, andl, subl, xorl, cmpl + // on 32bit in the case of cmpl, the imm might be an oop tail_size = 4; debug_only(has_disp32 = true); // has both kinds of operands! break; @@ -764,11 +588,9 @@ address Assembler::locate_operand(address inst, WhichOperand which) { case REP4(0x18): // sbb... case REP4(0x28): // sub... case 0xF7: // mull a - case 0x87: // xchg r, a - debug_only(has_disp32 = true); - break; - case REP4(0x38): // cmp... case 0x8D: // lea r, a + case 0x87: // xchg r, a + case REP4(0x38): // cmp... case 0x85: // test r, a debug_only(has_disp32 = true); // has both kinds of operands! break; @@ -784,7 +606,7 @@ address Assembler::locate_operand(address inst, WhichOperand which) { case 0xE8: // call rdisp32 case 0xE9: // jmp rdisp32 if (which == end_pc_operand) return ip + 4; - assert(which == call32_operand, "call has no disp32 or imm32"); + assert(which == call32_operand, "call has no disp32 or imm"); return ip; case 0xD1: // sal a, 1; sar a, 1; shl a, 1; shr a, 1 @@ -818,6 +640,7 @@ address Assembler::locate_operand(address inst, WhichOperand which) { case REX_WRB: case REX_WRX: case REX_WRXB: + NOT_LP64(assert(false, "found 64bit prefix")); ip++; default: ip++; @@ -833,7 +656,12 @@ address Assembler::locate_operand(address inst, WhichOperand which) { } assert(which != call32_operand, "instruction is not a call, jmp, or jcc"); - assert(which != imm64_operand, "instruction is not a movq reg, imm64"); +#ifdef _LP64 + assert(which != imm_operand, "instruction is not a movq reg, imm64"); +#else + // assert(which != imm_operand || has_imm32, "instruction has no imm32 field"); + assert(which != imm_operand || has_disp32, "instruction has no imm32 field"); +#endif // LP64 assert(which != disp32_operand || has_disp32, "instruction has no disp32 field"); // parse the output of emit_operand @@ -888,7 +716,11 @@ address Assembler::locate_operand(address inst, WhichOperand which) { return ip + tail_size; } - assert(0, "fix locate_operand"); +#ifdef _LP64 + assert(false, "fix locate_operand"); +#else + assert(which == imm_operand, "instruction has only an imm field"); +#endif // LP64 return ip; } @@ -897,219 +729,36 @@ address Assembler::locate_next_instruction(address inst) { return locate_operand(inst, end_pc_operand); } + #ifdef ASSERT void Assembler::check_relocation(RelocationHolder const& rspec, int format) { address inst = inst_mark(); - assert(inst != NULL && inst < pc(), - "must point to beginning of instruction"); + assert(inst != NULL && inst < pc(), "must point to beginning of instruction"); address opnd; Relocation* r = rspec.reloc(); if (r->type() == relocInfo::none) { return; } else if (r->is_call() || format == call32_operand) { + // assert(format == imm32_operand, "cannot specify a nonzero format"); opnd = locate_operand(inst, call32_operand); } else if (r->is_data()) { - assert(format == imm64_operand || format == disp32_operand || - format == narrow_oop_operand, "format ok"); - opnd = locate_operand(inst, (WhichOperand) format); + assert(format == imm_operand || format == disp32_operand + LP64_ONLY(|| format == narrow_oop_operand), "format ok"); + opnd = locate_operand(inst, (WhichOperand)format); } else { - assert(format == 0, "cannot specify a format"); + assert(format == imm_operand, "cannot specify a format"); return; } assert(opnd == pc(), "must put operand where relocs can find it"); } -#endif +#endif // ASSERT -int Assembler::prefix_and_encode(int reg_enc, bool byteinst) { - if (reg_enc >= 8) { - prefix(REX_B); - reg_enc -= 8; - } else if (byteinst && reg_enc >= 4) { - prefix(REX); - } - return reg_enc; -} - -int Assembler::prefixq_and_encode(int reg_enc) { - if (reg_enc < 8) { - prefix(REX_W); - } else { - prefix(REX_WB); - reg_enc -= 8; - } - return reg_enc; -} - -int Assembler::prefix_and_encode(int dst_enc, int src_enc, bool byteinst) { - if (dst_enc < 8) { - if (src_enc >= 8) { - prefix(REX_B); - src_enc -= 8; - } else if (byteinst && src_enc >= 4) { - prefix(REX); - } - } else { - if (src_enc < 8) { - prefix(REX_R); - } else { - prefix(REX_RB); - src_enc -= 8; - } - dst_enc -= 8; - } - return dst_enc << 3 | src_enc; -} - -int Assembler::prefixq_and_encode(int dst_enc, int src_enc) { - if (dst_enc < 8) { - if (src_enc < 8) { - prefix(REX_W); - } else { - prefix(REX_WB); - src_enc -= 8; - } - } else { - if (src_enc < 8) { - prefix(REX_WR); - } else { - prefix(REX_WRB); - src_enc -= 8; - } - dst_enc -= 8; - } - return dst_enc << 3 | src_enc; -} - -void Assembler::prefix(Register reg) { - if (reg->encoding() >= 8) { - prefix(REX_B); - } -} - -void Assembler::prefix(Address adr) { - if (adr.base_needs_rex()) { - if (adr.index_needs_rex()) { - prefix(REX_XB); - } else { - prefix(REX_B); - } - } else { - if (adr.index_needs_rex()) { - prefix(REX_X); - } - } -} - -void Assembler::prefixq(Address adr) { - if (adr.base_needs_rex()) { - if (adr.index_needs_rex()) { - prefix(REX_WXB); - } else { - prefix(REX_WB); - } - } else { - if (adr.index_needs_rex()) { - prefix(REX_WX); - } else { - prefix(REX_W); - } - } -} - - -void Assembler::prefix(Address adr, Register reg, bool byteinst) { - if (reg->encoding() < 8) { - if (adr.base_needs_rex()) { - if (adr.index_needs_rex()) { - prefix(REX_XB); - } else { - prefix(REX_B); - } - } else { - if (adr.index_needs_rex()) { - prefix(REX_X); - } else if (reg->encoding() >= 4 ) { - prefix(REX); - } - } - } else { - if (adr.base_needs_rex()) { - if (adr.index_needs_rex()) { - prefix(REX_RXB); - } else { - prefix(REX_RB); - } - } else { - if (adr.index_needs_rex()) { - prefix(REX_RX); - } else { - prefix(REX_R); - } - } - } -} - -void Assembler::prefixq(Address adr, Register src) { - if (src->encoding() < 8) { - if (adr.base_needs_rex()) { - if (adr.index_needs_rex()) { - prefix(REX_WXB); - } else { - prefix(REX_WB); - } - } else { - if (adr.index_needs_rex()) { - prefix(REX_WX); - } else { - prefix(REX_W); - } - } - } else { - if (adr.base_needs_rex()) { - if (adr.index_needs_rex()) { - prefix(REX_WRXB); - } else { - prefix(REX_WRB); - } - } else { - if (adr.index_needs_rex()) { - prefix(REX_WRX); - } else { - prefix(REX_WR); - } - } - } -} - -void Assembler::prefix(Address adr, XMMRegister reg) { - if (reg->encoding() < 8) { - if (adr.base_needs_rex()) { - if (adr.index_needs_rex()) { - prefix(REX_XB); - } else { - prefix(REX_B); - } - } else { - if (adr.index_needs_rex()) { - prefix(REX_X); - } - } - } else { - if (adr.base_needs_rex()) { - if (adr.index_needs_rex()) { - prefix(REX_RXB); - } else { - prefix(REX_RB); - } - } else { - if (adr.index_needs_rex()) { - prefix(REX_RX); - } else { - prefix(REX_R); - } - } - } +void Assembler::emit_operand32(Register reg, Address adr) { + assert(reg->encoding() < 8, "no extended registers"); + assert(!adr.base_needs_rex() && !adr.index_needs_rex(), "no extended registers"); + emit_operand(reg, adr._base, adr._index, adr._scale, adr._disp, + adr._rspec); } void Assembler::emit_operand(Register reg, Address adr, @@ -1119,13 +768,24 @@ void Assembler::emit_operand(Register reg, Address adr, rip_relative_correction); } -void Assembler::emit_operand(XMMRegister reg, Address adr, - int rip_relative_correction) { +void Assembler::emit_operand(XMMRegister reg, Address adr) { emit_operand(reg, adr._base, adr._index, adr._scale, adr._disp, - adr._rspec, - rip_relative_correction); + adr._rspec); } +// MMX operations +void Assembler::emit_operand(MMXRegister reg, Address adr) { + assert(!adr.base_needs_rex() && !adr.index_needs_rex(), "no extended registers"); + emit_operand((Register)reg, adr._base, adr._index, adr._scale, adr._disp, adr._rspec); +} + +// work around gcc (3.2.1-7a) bug +void Assembler::emit_operand(Address adr, MMXRegister reg) { + assert(!adr.base_needs_rex() && !adr.index_needs_rex(), "no extended registers"); + emit_operand((Register)reg, adr._base, adr._index, adr._scale, adr._disp, adr._rspec); +} + + void Assembler::emit_farith(int b1, int b2, int i) { assert(isByte(b1) && isByte(b2), "wrong opcode"); assert(0 <= i && i < 8, "illegal stack offset"); @@ -1133,612 +793,10 @@ void Assembler::emit_farith(int b1, int b2, int i) { emit_byte(b2 + i); } -// pushad is invalid, use this instead. -// NOTE: Kills flags!! -void Assembler::pushaq() { - // we have to store original rsp. ABI says that 128 bytes - // below rsp are local scratch. - movq(Address(rsp, -5 * wordSize), rsp); - subq(rsp, 16 * wordSize); +// Now the Assembler instruction (identical for 32/64 bits) - movq(Address(rsp, 15 * wordSize), rax); - movq(Address(rsp, 14 * wordSize), rcx); - movq(Address(rsp, 13 * wordSize), rdx); - movq(Address(rsp, 12 * wordSize), rbx); - // skip rsp - movq(Address(rsp, 10 * wordSize), rbp); - movq(Address(rsp, 9 * wordSize), rsi); - movq(Address(rsp, 8 * wordSize), rdi); - movq(Address(rsp, 7 * wordSize), r8); - movq(Address(rsp, 6 * wordSize), r9); - movq(Address(rsp, 5 * wordSize), r10); - movq(Address(rsp, 4 * wordSize), r11); - movq(Address(rsp, 3 * wordSize), r12); - movq(Address(rsp, 2 * wordSize), r13); - movq(Address(rsp, wordSize), r14); - movq(Address(rsp, 0), r15); -} - -// popad is invalid, use this instead -// NOTE: Kills flags!! -void Assembler::popaq() { - movq(r15, Address(rsp, 0)); - movq(r14, Address(rsp, wordSize)); - movq(r13, Address(rsp, 2 * wordSize)); - movq(r12, Address(rsp, 3 * wordSize)); - movq(r11, Address(rsp, 4 * wordSize)); - movq(r10, Address(rsp, 5 * wordSize)); - movq(r9, Address(rsp, 6 * wordSize)); - movq(r8, Address(rsp, 7 * wordSize)); - movq(rdi, Address(rsp, 8 * wordSize)); - movq(rsi, Address(rsp, 9 * wordSize)); - movq(rbp, Address(rsp, 10 * wordSize)); - // skip rsp - movq(rbx, Address(rsp, 12 * wordSize)); - movq(rdx, Address(rsp, 13 * wordSize)); - movq(rcx, Address(rsp, 14 * wordSize)); - movq(rax, Address(rsp, 15 * wordSize)); - - addq(rsp, 16 * wordSize); -} - -void Assembler::pushfq() { - emit_byte(0x9C); -} - -void Assembler::popfq() { - emit_byte(0x9D); -} - -void Assembler::pushq(int imm32) { - emit_byte(0x68); - emit_long(imm32); -} - -void Assembler::pushq(Register src) { - int encode = prefix_and_encode(src->encoding()); - - emit_byte(0x50 | encode); -} - -void Assembler::pushq(Address src) { - InstructionMark im(this); - prefix(src); - emit_byte(0xFF); - emit_operand(rsi, src); -} - -void Assembler::popq(Register dst) { - int encode = prefix_and_encode(dst->encoding()); - emit_byte(0x58 | encode); -} - -void Assembler::popq(Address dst) { - InstructionMark im(this); - prefix(dst); - emit_byte(0x8F); - emit_operand(rax, dst); -} - -void Assembler::prefix(Prefix p) { - a_byte(p); -} - -void Assembler::movb(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst, true); - emit_byte(0x8A); - emit_operand(dst, src); -} - -void Assembler::movb(Address dst, int imm8) { - InstructionMark im(this); - prefix(dst); - emit_byte(0xC6); - emit_operand(rax, dst, 1); - emit_byte(imm8); -} - -void Assembler::movb(Address dst, Register src) { - InstructionMark im(this); - prefix(dst, src, true); - emit_byte(0x88); - emit_operand(src, dst); -} - -void Assembler::movw(Address dst, int imm16) { - InstructionMark im(this); - emit_byte(0x66); // switch to 16-bit mode - prefix(dst); - emit_byte(0xC7); - emit_operand(rax, dst, 2); - emit_word(imm16); -} - -void Assembler::movw(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x66); - prefix(src, dst); - emit_byte(0x8B); - emit_operand(dst, src); -} - -void Assembler::movw(Address dst, Register src) { - InstructionMark im(this); - emit_byte(0x66); - prefix(dst, src); - emit_byte(0x89); - emit_operand(src, dst); -} - -// Uses zero extension. -void Assembler::movl(Register dst, int imm32) { - int encode = prefix_and_encode(dst->encoding()); - emit_byte(0xB8 | encode); - emit_long(imm32); -} - -void Assembler::movl(Register dst, Register src) { - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x8B); - emit_byte(0xC0 | encode); -} - -void Assembler::movl(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x8B); - emit_operand(dst, src); -} - -void Assembler::movl(Address dst, int imm32) { - InstructionMark im(this); - prefix(dst); - emit_byte(0xC7); - emit_operand(rax, dst, 4); - emit_long(imm32); -} - -void Assembler::movl(Address dst, Register src) { - InstructionMark im(this); - prefix(dst, src); - emit_byte(0x89); - emit_operand(src, dst); -} - -void Assembler::mov64(Register dst, intptr_t imm64) { - InstructionMark im(this); - int encode = prefixq_and_encode(dst->encoding()); - emit_byte(0xB8 | encode); - emit_long64(imm64); -} - -void Assembler::mov_literal64(Register dst, intptr_t imm64, RelocationHolder const& rspec) { - InstructionMark im(this); - int encode = prefixq_and_encode(dst->encoding()); - emit_byte(0xB8 | encode); - emit_data64(imm64, rspec); -} - -void Assembler::movq(Register dst, Register src) { - int encode = prefixq_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x8B); - emit_byte(0xC0 | encode); -} - -void Assembler::movq(Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x8B); - emit_operand(dst, src); -} - -void Assembler::mov64(Address dst, intptr_t imm32) { - assert(is_simm32(imm32), "lost bits"); - InstructionMark im(this); - prefixq(dst); - emit_byte(0xC7); - emit_operand(rax, dst, 4); - emit_long(imm32); -} - -void Assembler::movq(Address dst, Register src) { - InstructionMark im(this); - prefixq(dst, src); - emit_byte(0x89); - emit_operand(src, dst); -} - -void Assembler::movsbl(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0xBE); - emit_operand(dst, src); -} - -void Assembler::movsbl(Register dst, Register src) { - int encode = prefix_and_encode(dst->encoding(), src->encoding(), true); - emit_byte(0x0F); - emit_byte(0xBE); - emit_byte(0xC0 | encode); -} - -void Assembler::movswl(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0xBF); - emit_operand(dst, src); -} - -void Assembler::movswl(Register dst, Register src) { - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0xBF); - emit_byte(0xC0 | encode); -} - -void Assembler::movslq(Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x63); - emit_operand(dst, src); -} - -void Assembler::movslq(Register dst, Register src) { - int encode = prefixq_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x63); - emit_byte(0xC0 | encode); -} - -void Assembler::movzbl(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0xB6); - emit_operand(dst, src); -} - -void Assembler::movzbl(Register dst, Register src) { - int encode = prefix_and_encode(dst->encoding(), src->encoding(), true); - emit_byte(0x0F); - emit_byte(0xB6); - emit_byte(0xC0 | encode); -} - -void Assembler::movzwl(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0xB7); - emit_operand(dst, src); -} - -void Assembler::movzwl(Register dst, Register src) { - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0xB7); - emit_byte(0xC0 | encode); -} - -void Assembler::movss(XMMRegister dst, XMMRegister src) { - emit_byte(0xF3); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x10); - emit_byte(0xC0 | encode); -} - -void Assembler::movss(XMMRegister dst, Address src) { - InstructionMark im(this); - emit_byte(0xF3); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x10); - emit_operand(dst, src); -} - -void Assembler::movss(Address dst, XMMRegister src) { - InstructionMark im(this); - emit_byte(0xF3); - prefix(dst, src); - emit_byte(0x0F); - emit_byte(0x11); - emit_operand(src, dst); -} - -void Assembler::movsd(XMMRegister dst, XMMRegister src) { - emit_byte(0xF2); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x10); - emit_byte(0xC0 | encode); -} - -void Assembler::movsd(XMMRegister dst, Address src) { - InstructionMark im(this); - emit_byte(0xF2); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x10); - emit_operand(dst, src); -} - -void Assembler::movsd(Address dst, XMMRegister src) { - InstructionMark im(this); - emit_byte(0xF2); - prefix(dst, src); - emit_byte(0x0F); - emit_byte(0x11); - emit_operand(src, dst); -} - -// New cpus require to use movsd and movss to avoid partial register stall -// when loading from memory. But for old Opteron use movlpd instead of movsd. -// The selection is done in MacroAssembler::movdbl() and movflt(). -void Assembler::movlpd(XMMRegister dst, Address src) { - InstructionMark im(this); - emit_byte(0x66); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x12); - emit_operand(dst, src); -} - -void Assembler::movapd(XMMRegister dst, XMMRegister src) { - int dstenc = dst->encoding(); - int srcenc = src->encoding(); - emit_byte(0x66); - if (dstenc < 8) { - if (srcenc >= 8) { - prefix(REX_B); - srcenc -= 8; - } - } else { - if (srcenc < 8) { - prefix(REX_R); - } else { - prefix(REX_RB); - srcenc -= 8; - } - dstenc -= 8; - } - emit_byte(0x0F); - emit_byte(0x28); - emit_byte(0xC0 | dstenc << 3 | srcenc); -} - -void Assembler::movaps(XMMRegister dst, XMMRegister src) { - int dstenc = dst->encoding(); - int srcenc = src->encoding(); - if (dstenc < 8) { - if (srcenc >= 8) { - prefix(REX_B); - srcenc -= 8; - } - } else { - if (srcenc < 8) { - prefix(REX_R); - } else { - prefix(REX_RB); - srcenc -= 8; - } - dstenc -= 8; - } - emit_byte(0x0F); - emit_byte(0x28); - emit_byte(0xC0 | dstenc << 3 | srcenc); -} - -void Assembler::movdl(XMMRegister dst, Register src) { - emit_byte(0x66); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x6E); - emit_byte(0xC0 | encode); -} - -void Assembler::movdl(Register dst, XMMRegister src) { - emit_byte(0x66); - // swap src/dst to get correct prefix - int encode = prefix_and_encode(src->encoding(), dst->encoding()); - emit_byte(0x0F); - emit_byte(0x7E); - emit_byte(0xC0 | encode); -} - -void Assembler::movdq(XMMRegister dst, Register src) { - emit_byte(0x66); - int encode = prefixq_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x6E); - emit_byte(0xC0 | encode); -} - -void Assembler::movdq(Register dst, XMMRegister src) { - emit_byte(0x66); - // swap src/dst to get correct prefix - int encode = prefixq_and_encode(src->encoding(), dst->encoding()); - emit_byte(0x0F); - emit_byte(0x7E); - emit_byte(0xC0 | encode); -} - -void Assembler::pxor(XMMRegister dst, Address src) { - InstructionMark im(this); - emit_byte(0x66); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0xEF); - emit_operand(dst, src); -} - -void Assembler::pxor(XMMRegister dst, XMMRegister src) { - InstructionMark im(this); - emit_byte(0x66); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0xEF); - emit_byte(0xC0 | encode); -} - -void Assembler::movdqa(XMMRegister dst, Address src) { - InstructionMark im(this); - emit_byte(0x66); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x6F); - emit_operand(dst, src); -} - -void Assembler::movdqa(XMMRegister dst, XMMRegister src) { - emit_byte(0x66); - int encode = prefixq_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x6F); - emit_byte(0xC0 | encode); -} - -void Assembler::movdqa(Address dst, XMMRegister src) { - InstructionMark im(this); - emit_byte(0x66); - prefix(dst, src); - emit_byte(0x0F); - emit_byte(0x7F); - emit_operand(src, dst); -} - -void Assembler::movq(XMMRegister dst, Address src) { - InstructionMark im(this); - emit_byte(0xF3); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x7E); - emit_operand(dst, src); -} - -void Assembler::movq(Address dst, XMMRegister src) { - InstructionMark im(this); - emit_byte(0x66); - prefix(dst, src); - emit_byte(0x0F); - emit_byte(0xD6); - emit_operand(src, dst); -} - -void Assembler::pshufd(XMMRegister dst, XMMRegister src, int mode) { - assert(isByte(mode), "invalid value"); - emit_byte(0x66); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x70); - emit_byte(0xC0 | encode); - emit_byte(mode & 0xFF); -} - -void Assembler::pshufd(XMMRegister dst, Address src, int mode) { - assert(isByte(mode), "invalid value"); - InstructionMark im(this); - emit_byte(0x66); - emit_byte(0x0F); - emit_byte(0x70); - emit_operand(dst, src); - emit_byte(mode & 0xFF); -} - -void Assembler::pshuflw(XMMRegister dst, XMMRegister src, int mode) { - assert(isByte(mode), "invalid value"); - emit_byte(0xF2); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x70); - emit_byte(0xC0 | encode); - emit_byte(mode & 0xFF); -} - -void Assembler::pshuflw(XMMRegister dst, Address src, int mode) { - assert(isByte(mode), "invalid value"); - InstructionMark im(this); - emit_byte(0xF2); - emit_byte(0x0F); - emit_byte(0x70); - emit_operand(dst, src); - emit_byte(mode & 0xFF); -} - -void Assembler::cmovl(Condition cc, Register dst, Register src) { - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x40 | cc); - emit_byte(0xC0 | encode); -} - -void Assembler::cmovl(Condition cc, Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x40 | cc); - emit_operand(dst, src); -} - -void Assembler::cmovq(Condition cc, Register dst, Register src) { - int encode = prefixq_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x40 | cc); - emit_byte(0xC0 | encode); -} - -void Assembler::cmovq(Condition cc, Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x0F); - emit_byte(0x40 | cc); - emit_operand(dst, src); -} - -void Assembler::prefetch_prefix(Address src) { - prefix(src); - emit_byte(0x0F); -} - -void Assembler::prefetcht0(Address src) { - InstructionMark im(this); - prefetch_prefix(src); - emit_byte(0x18); - emit_operand(rcx, src); // 1, src -} - -void Assembler::prefetcht1(Address src) { - InstructionMark im(this); - prefetch_prefix(src); - emit_byte(0x18); - emit_operand(rdx, src); // 2, src -} - -void Assembler::prefetcht2(Address src) { - InstructionMark im(this); - prefetch_prefix(src); - emit_byte(0x18); - emit_operand(rbx, src); // 3, src -} - -void Assembler::prefetchnta(Address src) { - InstructionMark im(this); - prefetch_prefix(src); - emit_byte(0x18); - emit_operand(rax, src); // 0, src -} - -void Assembler::prefetchw(Address src) { - InstructionMark im(this); - prefetch_prefix(src); - emit_byte(0x0D); - emit_operand(rcx, src); // 1, src -} - -void Assembler::adcl(Register dst, int imm32) { +void Assembler::adcl(Register dst, int32_t imm32) { prefix(dst); emit_arith(0x81, 0xD0, dst, imm32); } @@ -1755,27 +813,10 @@ void Assembler::adcl(Register dst, Register src) { emit_arith(0x13, 0xC0, dst, src); } -void Assembler::adcq(Register dst, int imm32) { - (void) prefixq_and_encode(dst->encoding()); - emit_arith(0x81, 0xD0, dst, imm32); -} - -void Assembler::adcq(Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x13); - emit_operand(dst, src); -} - -void Assembler::adcq(Register dst, Register src) { - (int) prefixq_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x13, 0xC0, dst, src); -} - -void Assembler::addl(Address dst, int imm32) { +void Assembler::addl(Address dst, int32_t imm32) { InstructionMark im(this); prefix(dst); - emit_arith_operand(0x81, rax, dst,imm32); + emit_arith_operand(0x81, rax, dst, imm32); } void Assembler::addl(Address dst, Register src) { @@ -1785,7 +826,7 @@ void Assembler::addl(Address dst, Register src) { emit_operand(src, dst); } -void Assembler::addl(Register dst, int imm32) { +void Assembler::addl(Register dst, int32_t imm32) { prefix(dst); emit_arith(0x81, 0xC0, dst, imm32); } @@ -1802,786 +843,6 @@ void Assembler::addl(Register dst, Register src) { emit_arith(0x03, 0xC0, dst, src); } -void Assembler::addq(Address dst, int imm32) { - InstructionMark im(this); - prefixq(dst); - emit_arith_operand(0x81, rax, dst,imm32); -} - -void Assembler::addq(Address dst, Register src) { - InstructionMark im(this); - prefixq(dst, src); - emit_byte(0x01); - emit_operand(src, dst); -} - -void Assembler::addq(Register dst, int imm32) { - (void) prefixq_and_encode(dst->encoding()); - emit_arith(0x81, 0xC0, dst, imm32); -} - -void Assembler::addq(Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x03); - emit_operand(dst, src); -} - -void Assembler::addq(Register dst, Register src) { - (void) prefixq_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x03, 0xC0, dst, src); -} - -void Assembler::andl(Register dst, int imm32) { - prefix(dst); - emit_arith(0x81, 0xE0, dst, imm32); -} - -void Assembler::andl(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x23); - emit_operand(dst, src); -} - -void Assembler::andl(Register dst, Register src) { - (void) prefix_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x23, 0xC0, dst, src); -} - -void Assembler::andq(Register dst, int imm32) { - (void) prefixq_and_encode(dst->encoding()); - emit_arith(0x81, 0xE0, dst, imm32); -} - -void Assembler::andq(Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x23); - emit_operand(dst, src); -} - -void Assembler::andq(Register dst, Register src) { - (int) prefixq_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x23, 0xC0, dst, src); -} - -void Assembler::cmpb(Address dst, int imm8) { - InstructionMark im(this); - prefix(dst); - emit_byte(0x80); - emit_operand(rdi, dst, 1); - emit_byte(imm8); -} - -void Assembler::cmpl(Address dst, int imm32) { - InstructionMark im(this); - prefix(dst); - emit_byte(0x81); - emit_operand(rdi, dst, 4); - emit_long(imm32); -} - -void Assembler::cmpl(Register dst, int imm32) { - prefix(dst); - emit_arith(0x81, 0xF8, dst, imm32); -} - -void Assembler::cmpl(Register dst, Register src) { - (void) prefix_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x3B, 0xC0, dst, src); -} - -void Assembler::cmpl(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x3B); - emit_operand(dst, src); -} - -void Assembler::cmpq(Address dst, int imm32) { - InstructionMark im(this); - prefixq(dst); - emit_byte(0x81); - emit_operand(rdi, dst, 4); - emit_long(imm32); -} - -void Assembler::cmpq(Register dst, int imm32) { - (void) prefixq_and_encode(dst->encoding()); - emit_arith(0x81, 0xF8, dst, imm32); -} - -void Assembler::cmpq(Address dst, Register src) { - prefixq(dst, src); - emit_byte(0x3B); - emit_operand(src, dst); -} - -void Assembler::cmpq(Register dst, Register src) { - (void) prefixq_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x3B, 0xC0, dst, src); -} - -void Assembler::cmpq(Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x3B); - emit_operand(dst, src); -} - -void Assembler::ucomiss(XMMRegister dst, XMMRegister src) { - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x2E); - emit_byte(0xC0 | encode); -} - -void Assembler::ucomisd(XMMRegister dst, XMMRegister src) { - emit_byte(0x66); - ucomiss(dst, src); -} - -void Assembler::decl(Register dst) { - // Don't use it directly. Use MacroAssembler::decrementl() instead. - // Use two-byte form (one-byte from is a REX prefix in 64-bit mode) - int encode = prefix_and_encode(dst->encoding()); - emit_byte(0xFF); - emit_byte(0xC8 | encode); -} - -void Assembler::decl(Address dst) { - // Don't use it directly. Use MacroAssembler::decrementl() instead. - InstructionMark im(this); - prefix(dst); - emit_byte(0xFF); - emit_operand(rcx, dst); -} - -void Assembler::decq(Register dst) { - // Don't use it directly. Use MacroAssembler::decrementq() instead. - // Use two-byte form (one-byte from is a REX prefix in 64-bit mode) - int encode = prefixq_and_encode(dst->encoding()); - emit_byte(0xFF); - emit_byte(0xC8 | encode); -} - -void Assembler::decq(Address dst) { - // Don't use it directly. Use MacroAssembler::decrementq() instead. - InstructionMark im(this); - prefixq(dst); - emit_byte(0xFF); - emit_operand(rcx, dst); -} - -void Assembler::idivl(Register src) { - int encode = prefix_and_encode(src->encoding()); - emit_byte(0xF7); - emit_byte(0xF8 | encode); -} - -void Assembler::idivq(Register src) { - int encode = prefixq_and_encode(src->encoding()); - emit_byte(0xF7); - emit_byte(0xF8 | encode); -} - -void Assembler::cdql() { - emit_byte(0x99); -} - -void Assembler::cdqq() { - prefix(REX_W); - emit_byte(0x99); -} - -void Assembler::imull(Register dst, Register src) { - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0xAF); - emit_byte(0xC0 | encode); -} - -void Assembler::imull(Register dst, Register src, int value) { - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - if (is8bit(value)) { - emit_byte(0x6B); - emit_byte(0xC0 | encode); - emit_byte(value); - } else { - emit_byte(0x69); - emit_byte(0xC0 | encode); - emit_long(value); - } -} - -void Assembler::imulq(Register dst, Register src) { - int encode = prefixq_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0xAF); - emit_byte(0xC0 | encode); -} - -void Assembler::imulq(Register dst, Register src, int value) { - int encode = prefixq_and_encode(dst->encoding(), src->encoding()); - if (is8bit(value)) { - emit_byte(0x6B); - emit_byte(0xC0 | encode); - emit_byte(value); - } else { - emit_byte(0x69); - emit_byte(0xC0 | encode); - emit_long(value); - } -} - -void Assembler::incl(Register dst) { - // Don't use it directly. Use MacroAssembler::incrementl() instead. - // Use two-byte form (one-byte from is a REX prefix in 64-bit mode) - int encode = prefix_and_encode(dst->encoding()); - emit_byte(0xFF); - emit_byte(0xC0 | encode); -} - -void Assembler::incl(Address dst) { - // Don't use it directly. Use MacroAssembler::incrementl() instead. - InstructionMark im(this); - prefix(dst); - emit_byte(0xFF); - emit_operand(rax, dst); -} - -void Assembler::incq(Register dst) { - // Don't use it directly. Use MacroAssembler::incrementq() instead. - // Use two-byte form (one-byte from is a REX prefix in 64-bit mode) - int encode = prefixq_and_encode(dst->encoding()); - emit_byte(0xFF); - emit_byte(0xC0 | encode); -} - -void Assembler::incq(Address dst) { - // Don't use it directly. Use MacroAssembler::incrementq() instead. - InstructionMark im(this); - prefixq(dst); - emit_byte(0xFF); - emit_operand(rax, dst); -} - -void Assembler::leal(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x67); // addr32 - prefix(src, dst); - emit_byte(0x8D); - emit_operand(dst, src); -} - -void Assembler::leaq(Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x8D); - emit_operand(dst, src); -} - -void Assembler::mull(Address src) { - InstructionMark im(this); - // was missing - prefix(src); - emit_byte(0xF7); - emit_operand(rsp, src); -} - -void Assembler::mull(Register src) { - // was missing - int encode = prefix_and_encode(src->encoding()); - emit_byte(0xF7); - emit_byte(0xE0 | encode); -} - -void Assembler::negl(Register dst) { - int encode = prefix_and_encode(dst->encoding()); - emit_byte(0xF7); - emit_byte(0xD8 | encode); -} - -void Assembler::negq(Register dst) { - int encode = prefixq_and_encode(dst->encoding()); - emit_byte(0xF7); - emit_byte(0xD8 | encode); -} - -void Assembler::notl(Register dst) { - int encode = prefix_and_encode(dst->encoding()); - emit_byte(0xF7); - emit_byte(0xD0 | encode); -} - -void Assembler::notq(Register dst) { - int encode = prefixq_and_encode(dst->encoding()); - emit_byte(0xF7); - emit_byte(0xD0 | encode); -} - -void Assembler::orl(Address dst, int imm32) { - InstructionMark im(this); - prefix(dst); - emit_byte(0x81); - emit_operand(rcx, dst, 4); - emit_long(imm32); -} - -void Assembler::orl(Register dst, int imm32) { - prefix(dst); - emit_arith(0x81, 0xC8, dst, imm32); -} - -void Assembler::orl(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x0B); - emit_operand(dst, src); -} - -void Assembler::orl(Register dst, Register src) { - (void) prefix_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x0B, 0xC0, dst, src); -} - -void Assembler::orq(Address dst, int imm32) { - InstructionMark im(this); - prefixq(dst); - emit_byte(0x81); - emit_operand(rcx, dst, 4); - emit_long(imm32); -} - -void Assembler::orq(Register dst, int imm32) { - (void) prefixq_and_encode(dst->encoding()); - emit_arith(0x81, 0xC8, dst, imm32); -} - -void Assembler::orq(Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x0B); - emit_operand(dst, src); -} - -void Assembler::orq(Register dst, Register src) { - (void) prefixq_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x0B, 0xC0, dst, src); -} - -void Assembler::rcll(Register dst, int imm8) { - assert(isShiftCount(imm8), "illegal shift count"); - int encode = prefix_and_encode(dst->encoding()); - if (imm8 == 1) { - emit_byte(0xD1); - emit_byte(0xD0 | encode); - } else { - emit_byte(0xC1); - emit_byte(0xD0 | encode); - emit_byte(imm8); - } -} - -void Assembler::rclq(Register dst, int imm8) { - assert(isShiftCount(imm8 >> 1), "illegal shift count"); - int encode = prefixq_and_encode(dst->encoding()); - if (imm8 == 1) { - emit_byte(0xD1); - emit_byte(0xD0 | encode); - } else { - emit_byte(0xC1); - emit_byte(0xD0 | encode); - emit_byte(imm8); - } -} - -void Assembler::sarl(Register dst, int imm8) { - int encode = prefix_and_encode(dst->encoding()); - assert(isShiftCount(imm8), "illegal shift count"); - if (imm8 == 1) { - emit_byte(0xD1); - emit_byte(0xF8 | encode); - } else { - emit_byte(0xC1); - emit_byte(0xF8 | encode); - emit_byte(imm8); - } -} - -void Assembler::sarl(Register dst) { - int encode = prefix_and_encode(dst->encoding()); - emit_byte(0xD3); - emit_byte(0xF8 | encode); -} - -void Assembler::sarq(Register dst, int imm8) { - assert(isShiftCount(imm8 >> 1), "illegal shift count"); - int encode = prefixq_and_encode(dst->encoding()); - if (imm8 == 1) { - emit_byte(0xD1); - emit_byte(0xF8 | encode); - } else { - emit_byte(0xC1); - emit_byte(0xF8 | encode); - emit_byte(imm8); - } -} - -void Assembler::sarq(Register dst) { - int encode = prefixq_and_encode(dst->encoding()); - emit_byte(0xD3); - emit_byte(0xF8 | encode); -} - -void Assembler::sbbl(Address dst, int imm32) { - InstructionMark im(this); - prefix(dst); - emit_arith_operand(0x81, rbx, dst, imm32); -} - -void Assembler::sbbl(Register dst, int imm32) { - prefix(dst); - emit_arith(0x81, 0xD8, dst, imm32); -} - -void Assembler::sbbl(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x1B); - emit_operand(dst, src); -} - -void Assembler::sbbl(Register dst, Register src) { - (void) prefix_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x1B, 0xC0, dst, src); -} - -void Assembler::sbbq(Address dst, int imm32) { - InstructionMark im(this); - prefixq(dst); - emit_arith_operand(0x81, rbx, dst, imm32); -} - -void Assembler::sbbq(Register dst, int imm32) { - (void) prefixq_and_encode(dst->encoding()); - emit_arith(0x81, 0xD8, dst, imm32); -} - -void Assembler::sbbq(Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x1B); - emit_operand(dst, src); -} - -void Assembler::sbbq(Register dst, Register src) { - (void) prefixq_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x1B, 0xC0, dst, src); -} - -void Assembler::shll(Register dst, int imm8) { - assert(isShiftCount(imm8), "illegal shift count"); - int encode = prefix_and_encode(dst->encoding()); - if (imm8 == 1 ) { - emit_byte(0xD1); - emit_byte(0xE0 | encode); - } else { - emit_byte(0xC1); - emit_byte(0xE0 | encode); - emit_byte(imm8); - } -} - -void Assembler::shll(Register dst) { - int encode = prefix_and_encode(dst->encoding()); - emit_byte(0xD3); - emit_byte(0xE0 | encode); -} - -void Assembler::shlq(Register dst, int imm8) { - assert(isShiftCount(imm8 >> 1), "illegal shift count"); - int encode = prefixq_and_encode(dst->encoding()); - if (imm8 == 1) { - emit_byte(0xD1); - emit_byte(0xE0 | encode); - } else { - emit_byte(0xC1); - emit_byte(0xE0 | encode); - emit_byte(imm8); - } -} - -void Assembler::shlq(Register dst) { - int encode = prefixq_and_encode(dst->encoding()); - emit_byte(0xD3); - emit_byte(0xE0 | encode); -} - -void Assembler::shrl(Register dst, int imm8) { - assert(isShiftCount(imm8), "illegal shift count"); - int encode = prefix_and_encode(dst->encoding()); - emit_byte(0xC1); - emit_byte(0xE8 | encode); - emit_byte(imm8); -} - -void Assembler::shrl(Register dst) { - int encode = prefix_and_encode(dst->encoding()); - emit_byte(0xD3); - emit_byte(0xE8 | encode); -} - -void Assembler::shrq(Register dst, int imm8) { - assert(isShiftCount(imm8 >> 1), "illegal shift count"); - int encode = prefixq_and_encode(dst->encoding()); - emit_byte(0xC1); - emit_byte(0xE8 | encode); - emit_byte(imm8); -} - -void Assembler::shrq(Register dst) { - int encode = prefixq_and_encode(dst->encoding()); - emit_byte(0xD3); - emit_byte(0xE8 | encode); -} - -void Assembler::subl(Address dst, int imm32) { - InstructionMark im(this); - prefix(dst); - if (is8bit(imm32)) { - emit_byte(0x83); - emit_operand(rbp, dst, 1); - emit_byte(imm32 & 0xFF); - } else { - emit_byte(0x81); - emit_operand(rbp, dst, 4); - emit_long(imm32); - } -} - -void Assembler::subl(Register dst, int imm32) { - prefix(dst); - emit_arith(0x81, 0xE8, dst, imm32); -} - -void Assembler::subl(Address dst, Register src) { - InstructionMark im(this); - prefix(dst, src); - emit_byte(0x29); - emit_operand(src, dst); -} - -void Assembler::subl(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x2B); - emit_operand(dst, src); -} - -void Assembler::subl(Register dst, Register src) { - (void) prefix_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x2B, 0xC0, dst, src); -} - -void Assembler::subq(Address dst, int imm32) { - InstructionMark im(this); - prefixq(dst); - if (is8bit(imm32)) { - emit_byte(0x83); - emit_operand(rbp, dst, 1); - emit_byte(imm32 & 0xFF); - } else { - emit_byte(0x81); - emit_operand(rbp, dst, 4); - emit_long(imm32); - } -} - -void Assembler::subq(Register dst, int imm32) { - (void) prefixq_and_encode(dst->encoding()); - emit_arith(0x81, 0xE8, dst, imm32); -} - -void Assembler::subq(Address dst, Register src) { - InstructionMark im(this); - prefixq(dst, src); - emit_byte(0x29); - emit_operand(src, dst); -} - -void Assembler::subq(Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x2B); - emit_operand(dst, src); -} - -void Assembler::subq(Register dst, Register src) { - (void) prefixq_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x2B, 0xC0, dst, src); -} - -void Assembler::testb(Register dst, int imm8) { - (void) prefix_and_encode(dst->encoding(), true); - emit_arith_b(0xF6, 0xC0, dst, imm8); -} - -void Assembler::testl(Register dst, int imm32) { - // not using emit_arith because test - // doesn't support sign-extension of - // 8bit operands - int encode = dst->encoding(); - if (encode == 0) { - emit_byte(0xA9); - } else { - encode = prefix_and_encode(encode); - emit_byte(0xF7); - emit_byte(0xC0 | encode); - } - emit_long(imm32); -} - -void Assembler::testl(Register dst, Register src) { - (void) prefix_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x85, 0xC0, dst, src); -} - -void Assembler::testq(Register dst, int imm32) { - // not using emit_arith because test - // doesn't support sign-extension of - // 8bit operands - int encode = dst->encoding(); - if (encode == 0) { - prefix(REX_W); - emit_byte(0xA9); - } else { - encode = prefixq_and_encode(encode); - emit_byte(0xF7); - emit_byte(0xC0 | encode); - } - emit_long(imm32); -} - -void Assembler::testq(Register dst, Register src) { - (void) prefixq_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x85, 0xC0, dst, src); -} - -void Assembler::xaddl(Address dst, Register src) { - InstructionMark im(this); - prefix(dst, src); - emit_byte(0x0F); - emit_byte(0xC1); - emit_operand(src, dst); -} - -void Assembler::xaddq(Address dst, Register src) { - InstructionMark im(this); - prefixq(dst, src); - emit_byte(0x0F); - emit_byte(0xC1); - emit_operand(src, dst); -} - -void Assembler::xorl(Register dst, int imm32) { - prefix(dst); - emit_arith(0x81, 0xF0, dst, imm32); -} - -void Assembler::xorl(Register dst, Register src) { - (void) prefix_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x33, 0xC0, dst, src); -} - -void Assembler::xorl(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x33); - emit_operand(dst, src); -} - -void Assembler::xorq(Register dst, int imm32) { - (void) prefixq_and_encode(dst->encoding()); - emit_arith(0x81, 0xF0, dst, imm32); -} - -void Assembler::xorq(Register dst, Register src) { - (void) prefixq_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x33, 0xC0, dst, src); -} - -void Assembler::xorq(Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x33); - emit_operand(dst, src); -} - -void Assembler::bswapl(Register reg) { - int encode = prefix_and_encode(reg->encoding()); - emit_byte(0x0F); - emit_byte(0xC8 | encode); -} - -void Assembler::bswapq(Register reg) { - int encode = prefixq_and_encode(reg->encoding()); - emit_byte(0x0F); - emit_byte(0xC8 | encode); -} - -void Assembler::lock() { - emit_byte(0xF0); -} - -void Assembler::xchgl(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x87); - emit_operand(dst, src); -} - -void Assembler::xchgl(Register dst, Register src) { - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x87); - emit_byte(0xc0 | encode); -} - -void Assembler::xchgq(Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x87); - emit_operand(dst, src); -} - -void Assembler::xchgq(Register dst, Register src) { - int encode = prefixq_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x87); - emit_byte(0xc0 | encode); -} - -void Assembler::cmpxchgl(Register reg, Address adr) { - InstructionMark im(this); - prefix(adr, reg); - emit_byte(0x0F); - emit_byte(0xB1); - emit_operand(reg, adr); -} - -void Assembler::cmpxchgq(Register reg, Address adr) { - InstructionMark im(this); - prefixq(adr, reg); - emit_byte(0x0F); - emit_byte(0xB1); - emit_operand(reg, adr); -} - -void Assembler::hlt() { - emit_byte(0xF4); -} - - void Assembler::addr_nop_4() { // 4 bytes: NOP DWORD PTR [EAX+0] emit_byte(0x0F); @@ -2616,8 +877,1009 @@ void Assembler::addr_nop_8() { emit_long(0); // 32-bits offset (4 bytes) } +void Assembler::addsd(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF2); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x58); + emit_byte(0xC0 | encode); +} + +void Assembler::addsd(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0xF2); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x58); + emit_operand(dst, src); +} + +void Assembler::addss(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + emit_byte(0xF3); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x58); + emit_byte(0xC0 | encode); +} + +void Assembler::addss(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + InstructionMark im(this); + emit_byte(0xF3); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x58); + emit_operand(dst, src); +} + +void Assembler::andl(Register dst, int32_t imm32) { + prefix(dst); + emit_arith(0x81, 0xE0, dst, imm32); +} + +void Assembler::andl(Register dst, Address src) { + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x23); + emit_operand(dst, src); +} + +void Assembler::andl(Register dst, Register src) { + (void) prefix_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x23, 0xC0, dst, src); +} + +void Assembler::andpd(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0x66); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x54); + emit_operand(dst, src); +} + +void Assembler::bswapl(Register reg) { // bswap + int encode = prefix_and_encode(reg->encoding()); + emit_byte(0x0F); + emit_byte(0xC8 | encode); +} + +void Assembler::call(Label& L, relocInfo::relocType rtype) { + // suspect disp32 is always good + int operand = LP64_ONLY(disp32_operand) NOT_LP64(imm_operand); + + if (L.is_bound()) { + const int long_size = 5; + int offs = (int)( target(L) - pc() ); + assert(offs <= 0, "assembler error"); + InstructionMark im(this); + // 1110 1000 #32-bit disp + emit_byte(0xE8); + emit_data(offs - long_size, rtype, operand); + } else { + InstructionMark im(this); + // 1110 1000 #32-bit disp + L.add_patch_at(code(), locator()); + + emit_byte(0xE8); + emit_data(int(0), rtype, operand); + } +} + +void Assembler::call(Register dst) { + // This was originally using a 32bit register encoding + // and surely we want 64bit! + // this is a 32bit encoding but in 64bit mode the default + // operand size is 64bit so there is no need for the + // wide prefix. So prefix only happens if we use the + // new registers. Much like push/pop. + int x = offset(); + // this may be true but dbx disassembles it as if it + // were 32bits... + // int encode = prefix_and_encode(dst->encoding()); + // if (offset() != x) assert(dst->encoding() >= 8, "what?"); + int encode = prefixq_and_encode(dst->encoding()); + + emit_byte(0xFF); + emit_byte(0xD0 | encode); +} + + +void Assembler::call(Address adr) { + InstructionMark im(this); + prefix(adr); + emit_byte(0xFF); + emit_operand(rdx, adr); +} + +void Assembler::call_literal(address entry, RelocationHolder const& rspec) { + assert(entry != NULL, "call most probably wrong"); + InstructionMark im(this); + emit_byte(0xE8); + intptr_t disp = entry - (_code_pos + sizeof(int32_t)); + assert(is_simm32(disp), "must be 32bit offset (call2)"); + // Technically, should use call32_operand, but this format is + // implied by the fact that we're emitting a call instruction. + + int operand = LP64_ONLY(disp32_operand) NOT_LP64(call32_operand); + emit_data((int) disp, rspec, operand); +} + +void Assembler::cdql() { + emit_byte(0x99); +} + +void Assembler::cmovl(Condition cc, Register dst, Register src) { + NOT_LP64(guarantee(VM_Version::supports_cmov(), "illegal instruction")); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x40 | cc); + emit_byte(0xC0 | encode); +} + + +void Assembler::cmovl(Condition cc, Register dst, Address src) { + NOT_LP64(guarantee(VM_Version::supports_cmov(), "illegal instruction")); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x40 | cc); + emit_operand(dst, src); +} + +void Assembler::cmpb(Address dst, int imm8) { + InstructionMark im(this); + prefix(dst); + emit_byte(0x80); + emit_operand(rdi, dst, 1); + emit_byte(imm8); +} + +void Assembler::cmpl(Address dst, int32_t imm32) { + InstructionMark im(this); + prefix(dst); + emit_byte(0x81); + emit_operand(rdi, dst, 4); + emit_long(imm32); +} + +void Assembler::cmpl(Register dst, int32_t imm32) { + prefix(dst); + emit_arith(0x81, 0xF8, dst, imm32); +} + +void Assembler::cmpl(Register dst, Register src) { + (void) prefix_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x3B, 0xC0, dst, src); +} + + +void Assembler::cmpl(Register dst, Address src) { + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x3B); + emit_operand(dst, src); +} + +void Assembler::cmpw(Address dst, int imm16) { + InstructionMark im(this); + assert(!dst.base_needs_rex() && !dst.index_needs_rex(), "no extended registers"); + emit_byte(0x66); + emit_byte(0x81); + emit_operand(rdi, dst, 2); + emit_word(imm16); +} + +// The 32-bit cmpxchg compares the value at adr with the contents of rax, +// and stores reg into adr if so; otherwise, the value at adr is loaded into rax,. +// The ZF is set if the compared values were equal, and cleared otherwise. +void Assembler::cmpxchgl(Register reg, Address adr) { // cmpxchg + if (Atomics & 2) { + // caveat: no instructionmark, so this isn't relocatable. + // Emit a synthetic, non-atomic, CAS equivalent. + // Beware. The synthetic form sets all ICCs, not just ZF. + // cmpxchg r,[m] is equivalent to rax, = CAS (m, rax, r) + cmpl(rax, adr); + movl(rax, adr); + if (reg != rax) { + Label L ; + jcc(Assembler::notEqual, L); + movl(adr, reg); + bind(L); + } + } else { + InstructionMark im(this); + prefix(adr, reg); + emit_byte(0x0F); + emit_byte(0xB1); + emit_operand(reg, adr); + } +} + +void Assembler::comisd(XMMRegister dst, Address src) { + // NOTE: dbx seems to decode this as comiss even though the + // 0x66 is there. Strangly ucomisd comes out correct + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0x66); + comiss(dst, src); +} + +void Assembler::comiss(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x2F); + emit_operand(dst, src); +} + +void Assembler::cvtdq2pd(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF3); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0xE6); + emit_byte(0xC0 | encode); +} + +void Assembler::cvtdq2ps(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x5B); + emit_byte(0xC0 | encode); +} + +void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF2); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x5A); + emit_byte(0xC0 | encode); +} + +void Assembler::cvtsi2sdl(XMMRegister dst, Register src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF2); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x2A); + emit_byte(0xC0 | encode); +} + +void Assembler::cvtsi2ssl(XMMRegister dst, Register src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + emit_byte(0xF3); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x2A); + emit_byte(0xC0 | encode); +} + +void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF3); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x5A); + emit_byte(0xC0 | encode); +} + +void Assembler::cvttsd2sil(Register dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF2); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x2C); + emit_byte(0xC0 | encode); +} + +void Assembler::cvttss2sil(Register dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + emit_byte(0xF3); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x2C); + emit_byte(0xC0 | encode); +} + +void Assembler::decl(Address dst) { + // Don't use it directly. Use MacroAssembler::decrement() instead. + InstructionMark im(this); + prefix(dst); + emit_byte(0xFF); + emit_operand(rcx, dst); +} + +void Assembler::divsd(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0xF2); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x5E); + emit_operand(dst, src); +} + +void Assembler::divsd(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF2); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x5E); + emit_byte(0xC0 | encode); +} + +void Assembler::divss(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + InstructionMark im(this); + emit_byte(0xF3); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x5E); + emit_operand(dst, src); +} + +void Assembler::divss(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + emit_byte(0xF3); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x5E); + emit_byte(0xC0 | encode); +} + +void Assembler::emms() { + NOT_LP64(assert(VM_Version::supports_mmx(), "")); + emit_byte(0x0F); + emit_byte(0x77); +} + +void Assembler::hlt() { + emit_byte(0xF4); +} + +void Assembler::idivl(Register src) { + int encode = prefix_and_encode(src->encoding()); + emit_byte(0xF7); + emit_byte(0xF8 | encode); +} + +void Assembler::imull(Register dst, Register src) { + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0xAF); + emit_byte(0xC0 | encode); +} + + +void Assembler::imull(Register dst, Register src, int value) { + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + if (is8bit(value)) { + emit_byte(0x6B); + emit_byte(0xC0 | encode); + emit_byte(value); + } else { + emit_byte(0x69); + emit_byte(0xC0 | encode); + emit_long(value); + } +} + +void Assembler::incl(Address dst) { + // Don't use it directly. Use MacroAssembler::increment() instead. + InstructionMark im(this); + prefix(dst); + emit_byte(0xFF); + emit_operand(rax, dst); +} + +void Assembler::jcc(Condition cc, Label& L, relocInfo::relocType rtype) { + InstructionMark im(this); + relocate(rtype); + assert((0 <= cc) && (cc < 16), "illegal cc"); + if (L.is_bound()) { + address dst = target(L); + assert(dst != NULL, "jcc most probably wrong"); + + const int short_size = 2; + const int long_size = 6; + intptr_t offs = (intptr_t)dst - (intptr_t)_code_pos; + if (rtype == relocInfo::none && is8bit(offs - short_size)) { + // 0111 tttn #8-bit disp + emit_byte(0x70 | cc); + emit_byte((offs - short_size) & 0xFF); + } else { + // 0000 1111 1000 tttn #32-bit disp + assert(is_simm32(offs - long_size), + "must be 32bit offset (call4)"); + emit_byte(0x0F); + emit_byte(0x80 | cc); + emit_long(offs - long_size); + } + } else { + // Note: could eliminate cond. jumps to this jump if condition + // is the same however, seems to be rather unlikely case. + // Note: use jccb() if label to be bound is very close to get + // an 8-bit displacement + L.add_patch_at(code(), locator()); + emit_byte(0x0F); + emit_byte(0x80 | cc); + emit_long(0); + } +} + +void Assembler::jccb(Condition cc, Label& L) { + if (L.is_bound()) { + const int short_size = 2; + address entry = target(L); + assert(is8bit((intptr_t)entry - ((intptr_t)_code_pos + short_size)), + "Dispacement too large for a short jmp"); + intptr_t offs = (intptr_t)entry - (intptr_t)_code_pos; + // 0111 tttn #8-bit disp + emit_byte(0x70 | cc); + emit_byte((offs - short_size) & 0xFF); + } else { + InstructionMark im(this); + L.add_patch_at(code(), locator()); + emit_byte(0x70 | cc); + emit_byte(0); + } +} + +void Assembler::jmp(Address adr) { + InstructionMark im(this); + prefix(adr); + emit_byte(0xFF); + emit_operand(rsp, adr); +} + +void Assembler::jmp(Label& L, relocInfo::relocType rtype) { + if (L.is_bound()) { + address entry = target(L); + assert(entry != NULL, "jmp most probably wrong"); + InstructionMark im(this); + const int short_size = 2; + const int long_size = 5; + intptr_t offs = entry - _code_pos; + if (rtype == relocInfo::none && is8bit(offs - short_size)) { + emit_byte(0xEB); + emit_byte((offs - short_size) & 0xFF); + } else { + emit_byte(0xE9); + emit_long(offs - long_size); + } + } else { + // By default, forward jumps are always 32-bit displacements, since + // we can't yet know where the label will be bound. If you're sure that + // the forward jump will not run beyond 256 bytes, use jmpb to + // force an 8-bit displacement. + InstructionMark im(this); + relocate(rtype); + L.add_patch_at(code(), locator()); + emit_byte(0xE9); + emit_long(0); + } +} + +void Assembler::jmp(Register entry) { + int encode = prefix_and_encode(entry->encoding()); + emit_byte(0xFF); + emit_byte(0xE0 | encode); +} + +void Assembler::jmp_literal(address dest, RelocationHolder const& rspec) { + InstructionMark im(this); + emit_byte(0xE9); + assert(dest != NULL, "must have a target"); + intptr_t disp = dest - (_code_pos + sizeof(int32_t)); + assert(is_simm32(disp), "must be 32bit offset (jmp)"); + emit_data(disp, rspec.reloc(), call32_operand); +} + +void Assembler::jmpb(Label& L) { + if (L.is_bound()) { + const int short_size = 2; + address entry = target(L); + assert(is8bit((entry - _code_pos) + short_size), + "Dispacement too large for a short jmp"); + assert(entry != NULL, "jmp most probably wrong"); + intptr_t offs = entry - _code_pos; + emit_byte(0xEB); + emit_byte((offs - short_size) & 0xFF); + } else { + InstructionMark im(this); + L.add_patch_at(code(), locator()); + emit_byte(0xEB); + emit_byte(0); + } +} + +void Assembler::ldmxcsr( Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + InstructionMark im(this); + prefix(src); + emit_byte(0x0F); + emit_byte(0xAE); + emit_operand(as_Register(2), src); +} + +void Assembler::leal(Register dst, Address src) { + InstructionMark im(this); +#ifdef _LP64 + emit_byte(0x67); // addr32 + prefix(src, dst); +#endif // LP64 + emit_byte(0x8D); + emit_operand(dst, src); +} + +void Assembler::lock() { + if (Atomics & 1) { + // Emit either nothing, a NOP, or a NOP: prefix + emit_byte(0x90) ; + } else { + emit_byte(0xF0); + } +} + +// Serializes memory. +void Assembler::mfence() { + // Memory barriers are only needed on multiprocessors + if (os::is_MP()) { + if( LP64_ONLY(true ||) VM_Version::supports_sse2() ) { + emit_byte( 0x0F ); // MFENCE; faster blows no regs + emit_byte( 0xAE ); + emit_byte( 0xF0 ); + } else { + // All usable chips support "locked" instructions which suffice + // as barriers, and are much faster than the alternative of + // using cpuid instruction. We use here a locked add [esp],0. + // This is conveniently otherwise a no-op except for blowing + // flags (which we save and restore.) + pushf(); // Save eflags register + lock(); + addl(Address(rsp, 0), 0);// Assert the lock# signal here + popf(); // Restore eflags register + } + } +} + +void Assembler::mov(Register dst, Register src) { + LP64_ONLY(movq(dst, src)) NOT_LP64(movl(dst, src)); +} + +void Assembler::movapd(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + int dstenc = dst->encoding(); + int srcenc = src->encoding(); + emit_byte(0x66); + if (dstenc < 8) { + if (srcenc >= 8) { + prefix(REX_B); + srcenc -= 8; + } + } else { + if (srcenc < 8) { + prefix(REX_R); + } else { + prefix(REX_RB); + srcenc -= 8; + } + dstenc -= 8; + } + emit_byte(0x0F); + emit_byte(0x28); + emit_byte(0xC0 | dstenc << 3 | srcenc); +} + +void Assembler::movaps(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + int dstenc = dst->encoding(); + int srcenc = src->encoding(); + if (dstenc < 8) { + if (srcenc >= 8) { + prefix(REX_B); + srcenc -= 8; + } + } else { + if (srcenc < 8) { + prefix(REX_R); + } else { + prefix(REX_RB); + srcenc -= 8; + } + dstenc -= 8; + } + emit_byte(0x0F); + emit_byte(0x28); + emit_byte(0xC0 | dstenc << 3 | srcenc); +} + +void Assembler::movb(Register dst, Address src) { + NOT_LP64(assert(dst->has_byte_register(), "must have byte register")); + InstructionMark im(this); + prefix(src, dst, true); + emit_byte(0x8A); + emit_operand(dst, src); +} + + +void Assembler::movb(Address dst, int imm8) { + InstructionMark im(this); + prefix(dst); + emit_byte(0xC6); + emit_operand(rax, dst, 1); + emit_byte(imm8); +} + + +void Assembler::movb(Address dst, Register src) { + assert(src->has_byte_register(), "must have byte register"); + InstructionMark im(this); + prefix(dst, src, true); + emit_byte(0x88); + emit_operand(src, dst); +} + +void Assembler::movdl(XMMRegister dst, Register src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0x66); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x6E); + emit_byte(0xC0 | encode); +} + +void Assembler::movdl(Register dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0x66); + // swap src/dst to get correct prefix + int encode = prefix_and_encode(src->encoding(), dst->encoding()); + emit_byte(0x0F); + emit_byte(0x7E); + emit_byte(0xC0 | encode); +} + +void Assembler::movdqa(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0x66); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x6F); + emit_operand(dst, src); +} + +void Assembler::movdqa(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0x66); + int encode = prefixq_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x6F); + emit_byte(0xC0 | encode); +} + +void Assembler::movdqa(Address dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0x66); + prefix(dst, src); + emit_byte(0x0F); + emit_byte(0x7F); + emit_operand(src, dst); +} + +// Uses zero extension on 64bit + +void Assembler::movl(Register dst, int32_t imm32) { + int encode = prefix_and_encode(dst->encoding()); + emit_byte(0xB8 | encode); + emit_long(imm32); +} + +void Assembler::movl(Register dst, Register src) { + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x8B); + emit_byte(0xC0 | encode); +} + +void Assembler::movl(Register dst, Address src) { + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x8B); + emit_operand(dst, src); +} + +void Assembler::movl(Address dst, int32_t imm32) { + InstructionMark im(this); + prefix(dst); + emit_byte(0xC7); + emit_operand(rax, dst, 4); + emit_long(imm32); +} + +void Assembler::movl(Address dst, Register src) { + InstructionMark im(this); + prefix(dst, src); + emit_byte(0x89); + emit_operand(src, dst); +} + +// New cpus require to use movsd and movss to avoid partial register stall +// when loading from memory. But for old Opteron use movlpd instead of movsd. +// The selection is done in MacroAssembler::movdbl() and movflt(). +void Assembler::movlpd(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0x66); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x12); + emit_operand(dst, src); +} + +void Assembler::movq( MMXRegister dst, Address src ) { + assert( VM_Version::supports_mmx(), "" ); + emit_byte(0x0F); + emit_byte(0x6F); + emit_operand(dst, src); +} + +void Assembler::movq( Address dst, MMXRegister src ) { + assert( VM_Version::supports_mmx(), "" ); + emit_byte(0x0F); + emit_byte(0x7F); + // workaround gcc (3.2.1-7a) bug + // In that version of gcc with only an emit_operand(MMX, Address) + // gcc will tail jump and try and reverse the parameters completely + // obliterating dst in the process. By having a version available + // that doesn't need to swap the args at the tail jump the bug is + // avoided. + emit_operand(dst, src); +} + +void Assembler::movq(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0xF3); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x7E); + emit_operand(dst, src); +} + +void Assembler::movq(Address dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0x66); + prefix(dst, src); + emit_byte(0x0F); + emit_byte(0xD6); + emit_operand(src, dst); +} + +void Assembler::movsbl(Register dst, Address src) { // movsxb + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0xBE); + emit_operand(dst, src); +} + +void Assembler::movsbl(Register dst, Register src) { // movsxb + NOT_LP64(assert(src->has_byte_register(), "must have byte register")); + int encode = prefix_and_encode(dst->encoding(), src->encoding(), true); + emit_byte(0x0F); + emit_byte(0xBE); + emit_byte(0xC0 | encode); +} + +void Assembler::movsd(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF2); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x10); + emit_byte(0xC0 | encode); +} + +void Assembler::movsd(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0xF2); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x10); + emit_operand(dst, src); +} + +void Assembler::movsd(Address dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0xF2); + prefix(dst, src); + emit_byte(0x0F); + emit_byte(0x11); + emit_operand(src, dst); +} + +void Assembler::movss(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + emit_byte(0xF3); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x10); + emit_byte(0xC0 | encode); +} + +void Assembler::movss(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + InstructionMark im(this); + emit_byte(0xF3); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x10); + emit_operand(dst, src); +} + +void Assembler::movss(Address dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + InstructionMark im(this); + emit_byte(0xF3); + prefix(dst, src); + emit_byte(0x0F); + emit_byte(0x11); + emit_operand(src, dst); +} + +void Assembler::movswl(Register dst, Address src) { // movsxw + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0xBF); + emit_operand(dst, src); +} + +void Assembler::movswl(Register dst, Register src) { // movsxw + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0xBF); + emit_byte(0xC0 | encode); +} + +void Assembler::movw(Address dst, int imm16) { + InstructionMark im(this); + + emit_byte(0x66); // switch to 16-bit mode + prefix(dst); + emit_byte(0xC7); + emit_operand(rax, dst, 2); + emit_word(imm16); +} + +void Assembler::movw(Register dst, Address src) { + InstructionMark im(this); + emit_byte(0x66); + prefix(src, dst); + emit_byte(0x8B); + emit_operand(dst, src); +} + +void Assembler::movw(Address dst, Register src) { + InstructionMark im(this); + emit_byte(0x66); + prefix(dst, src); + emit_byte(0x89); + emit_operand(src, dst); +} + +void Assembler::movzbl(Register dst, Address src) { // movzxb + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0xB6); + emit_operand(dst, src); +} + +void Assembler::movzbl(Register dst, Register src) { // movzxb + NOT_LP64(assert(src->has_byte_register(), "must have byte register")); + int encode = prefix_and_encode(dst->encoding(), src->encoding(), true); + emit_byte(0x0F); + emit_byte(0xB6); + emit_byte(0xC0 | encode); +} + +void Assembler::movzwl(Register dst, Address src) { // movzxw + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0xB7); + emit_operand(dst, src); +} + +void Assembler::movzwl(Register dst, Register src) { // movzxw + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0xB7); + emit_byte(0xC0 | encode); +} + +void Assembler::mull(Address src) { + InstructionMark im(this); + prefix(src); + emit_byte(0xF7); + emit_operand(rsp, src); +} + +void Assembler::mull(Register src) { + int encode = prefix_and_encode(src->encoding()); + emit_byte(0xF7); + emit_byte(0xE0 | encode); +} + +void Assembler::mulsd(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0xF2); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x59); + emit_operand(dst, src); +} + +void Assembler::mulsd(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF2); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x59); + emit_byte(0xC0 | encode); +} + +void Assembler::mulss(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + InstructionMark im(this); + emit_byte(0xF3); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x59); + emit_operand(dst, src); +} + +void Assembler::mulss(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + emit_byte(0xF3); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x59); + emit_byte(0xC0 | encode); +} + +void Assembler::negl(Register dst) { + int encode = prefix_and_encode(dst->encoding()); + emit_byte(0xF7); + emit_byte(0xD8 | encode); +} + void Assembler::nop(int i) { +#ifdef ASSERT assert(i > 0, " "); + // The fancy nops aren't currently recognized by debuggers making it a + // pain to disassemble code while debugging. If asserts are on clearly + // speed is not an issue so simply use the single byte traditional nop + // to do alignment. + + for (; i > 0 ; i--) emit_byte(0x90); + return; + +#endif // ASSERT + if (UseAddressNop && VM_Version::is_intel()) { // // Using multi-bytes nops "0x0F 0x1F [address]" for Intel @@ -2853,6 +2115,281 @@ void Assembler::nop(int i) { } } +void Assembler::notl(Register dst) { + int encode = prefix_and_encode(dst->encoding()); + emit_byte(0xF7); + emit_byte(0xD0 | encode ); +} + +void Assembler::orl(Address dst, int32_t imm32) { + InstructionMark im(this); + prefix(dst); + emit_byte(0x81); + emit_operand(rcx, dst, 4); + emit_long(imm32); +} + +void Assembler::orl(Register dst, int32_t imm32) { + prefix(dst); + emit_arith(0x81, 0xC8, dst, imm32); +} + + +void Assembler::orl(Register dst, Address src) { + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x0B); + emit_operand(dst, src); +} + + +void Assembler::orl(Register dst, Register src) { + (void) prefix_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x0B, 0xC0, dst, src); +} + +// generic +void Assembler::pop(Register dst) { + int encode = prefix_and_encode(dst->encoding()); + emit_byte(0x58 | encode); +} + +void Assembler::popf() { + emit_byte(0x9D); +} + +void Assembler::popl(Address dst) { + // NOTE: this will adjust stack by 8byte on 64bits + InstructionMark im(this); + prefix(dst); + emit_byte(0x8F); + emit_operand(rax, dst); +} + +void Assembler::prefetch_prefix(Address src) { + prefix(src); + emit_byte(0x0F); +} + +void Assembler::prefetchnta(Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "must support")); + InstructionMark im(this); + prefetch_prefix(src); + emit_byte(0x18); + emit_operand(rax, src); // 0, src +} + +void Assembler::prefetchr(Address src) { + NOT_LP64(assert(VM_Version::supports_3dnow(), "must support")); + InstructionMark im(this); + prefetch_prefix(src); + emit_byte(0x0D); + emit_operand(rax, src); // 0, src +} + +void Assembler::prefetcht0(Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "must support")); + InstructionMark im(this); + prefetch_prefix(src); + emit_byte(0x18); + emit_operand(rcx, src); // 1, src +} + +void Assembler::prefetcht1(Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "must support")); + InstructionMark im(this); + prefetch_prefix(src); + emit_byte(0x18); + emit_operand(rdx, src); // 2, src +} + +void Assembler::prefetcht2(Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "must support")); + InstructionMark im(this); + prefetch_prefix(src); + emit_byte(0x18); + emit_operand(rbx, src); // 3, src +} + +void Assembler::prefetchw(Address src) { + NOT_LP64(assert(VM_Version::supports_3dnow(), "must support")); + InstructionMark im(this); + prefetch_prefix(src); + emit_byte(0x0D); + emit_operand(rcx, src); // 1, src +} + +void Assembler::prefix(Prefix p) { + a_byte(p); +} + +void Assembler::pshufd(XMMRegister dst, XMMRegister src, int mode) { + assert(isByte(mode), "invalid value"); + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + + emit_byte(0x66); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x70); + emit_byte(0xC0 | encode); + emit_byte(mode & 0xFF); + +} + +void Assembler::pshufd(XMMRegister dst, Address src, int mode) { + assert(isByte(mode), "invalid value"); + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + + InstructionMark im(this); + emit_byte(0x66); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x70); + emit_operand(dst, src); + emit_byte(mode & 0xFF); +} + +void Assembler::pshuflw(XMMRegister dst, XMMRegister src, int mode) { + assert(isByte(mode), "invalid value"); + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + + emit_byte(0xF2); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x70); + emit_byte(0xC0 | encode); + emit_byte(mode & 0xFF); +} + +void Assembler::pshuflw(XMMRegister dst, Address src, int mode) { + assert(isByte(mode), "invalid value"); + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + + InstructionMark im(this); + emit_byte(0xF2); + prefix(src, dst); // QQ new + emit_byte(0x0F); + emit_byte(0x70); + emit_operand(dst, src); + emit_byte(mode & 0xFF); +} + +void Assembler::psrlq(XMMRegister dst, int shift) { + // HMM Table D-1 says sse2 or mmx + NOT_LP64(assert(VM_Version::supports_sse(), "")); + + int encode = prefixq_and_encode(xmm2->encoding(), dst->encoding()); + emit_byte(0x66); + emit_byte(0x0F); + emit_byte(0x73); + emit_byte(0xC0 | encode); + emit_byte(shift); +} + +void Assembler::punpcklbw(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0x66); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x60); + emit_byte(0xC0 | encode); +} + +void Assembler::push(int32_t imm32) { + // in 64bits we push 64bits onto the stack but only + // take a 32bit immediate + emit_byte(0x68); + emit_long(imm32); +} + +void Assembler::push(Register src) { + int encode = prefix_and_encode(src->encoding()); + + emit_byte(0x50 | encode); +} + +void Assembler::pushf() { + emit_byte(0x9C); +} + +void Assembler::pushl(Address src) { + // Note this will push 64bit on 64bit + InstructionMark im(this); + prefix(src); + emit_byte(0xFF); + emit_operand(rsi, src); +} + +void Assembler::pxor(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0x66); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0xEF); + emit_operand(dst, src); +} + +void Assembler::pxor(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0x66); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0xEF); + emit_byte(0xC0 | encode); +} + +void Assembler::rcll(Register dst, int imm8) { + assert(isShiftCount(imm8), "illegal shift count"); + int encode = prefix_and_encode(dst->encoding()); + if (imm8 == 1) { + emit_byte(0xD1); + emit_byte(0xD0 | encode); + } else { + emit_byte(0xC1); + emit_byte(0xD0 | encode); + emit_byte(imm8); + } +} + +// copies data from [esi] to [edi] using rcx pointer sized words +// generic +void Assembler::rep_mov() { + emit_byte(0xF3); + // MOVSQ + LP64_ONLY(prefix(REX_W)); + emit_byte(0xA5); +} + +// sets rcx pointer sized words with rax, value at [edi] +// generic +void Assembler::rep_set() { // rep_set + emit_byte(0xF3); + // STOSQ + LP64_ONLY(prefix(REX_W)); + emit_byte(0xAB); +} + +// scans rcx pointer sized words at [edi] for occurance of rax, +// generic +void Assembler::repne_scan() { // repne_scan + emit_byte(0xF2); + // SCASQ + LP64_ONLY(prefix(REX_W)); + emit_byte(0xAF); +} + +#ifdef _LP64 +// scans rcx 4 byte words at [edi] for occurance of rax, +// generic +void Assembler::repne_scanl() { // repne_scan + emit_byte(0xF2); + // SCASL + emit_byte(0xAF); +} +#endif + void Assembler::ret(int imm16) { if (imm16 == 0) { emit_byte(0xC3); @@ -2862,53 +2399,56 @@ void Assembler::ret(int imm16) { } } -// copies a single word from [esi] to [edi] -void Assembler::smovl() { - emit_byte(0xA5); +void Assembler::sahf() { +#ifdef _LP64 + // Not supported in 64bit mode + ShouldNotReachHere(); +#endif + emit_byte(0x9E); } -// copies data from [rsi] to [rdi] using rcx words (m32) -void Assembler::rep_movl() { - // REP - emit_byte(0xF3); - // MOVSL - emit_byte(0xA5); +void Assembler::sarl(Register dst, int imm8) { + int encode = prefix_and_encode(dst->encoding()); + assert(isShiftCount(imm8), "illegal shift count"); + if (imm8 == 1) { + emit_byte(0xD1); + emit_byte(0xF8 | encode); + } else { + emit_byte(0xC1); + emit_byte(0xF8 | encode); + emit_byte(imm8); + } } -// copies data from [rsi] to [rdi] using rcx double words (m64) -void Assembler::rep_movq() { - // REP - emit_byte(0xF3); - // MOVSQ - prefix(REX_W); - emit_byte(0xA5); +void Assembler::sarl(Register dst) { + int encode = prefix_and_encode(dst->encoding()); + emit_byte(0xD3); + emit_byte(0xF8 | encode); } -// sets rcx double words (m64) with rax value at [rdi] -void Assembler::rep_set() { - // REP - emit_byte(0xF3); - // STOSQ - prefix(REX_W); - emit_byte(0xAB); +void Assembler::sbbl(Address dst, int32_t imm32) { + InstructionMark im(this); + prefix(dst); + emit_arith_operand(0x81, rbx, dst, imm32); } -// scans rcx double words (m64) at [rdi] for occurance of rax -void Assembler::repne_scanq() { - // REPNE/REPNZ - emit_byte(0xF2); - // SCASQ - prefix(REX_W); - emit_byte(0xAF); +void Assembler::sbbl(Register dst, int32_t imm32) { + prefix(dst); + emit_arith(0x81, 0xD8, dst, imm32); } -void Assembler::repne_scanl() { - // REPNE/REPNZ - emit_byte(0xF2); - // SCASL - emit_byte(0xAF); + +void Assembler::sbbl(Register dst, Address src) { + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x1B); + emit_operand(dst, src); } +void Assembler::sbbl(Register dst, Register src) { + (void) prefix_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x1B, 0xC0, dst, src); +} void Assembler::setb(Condition cc, Register dst) { assert(0 <= cc && cc < 16, "illegal cc"); @@ -2918,6 +2458,1155 @@ void Assembler::setb(Condition cc, Register dst) { emit_byte(0xC0 | encode); } +void Assembler::shll(Register dst, int imm8) { + assert(isShiftCount(imm8), "illegal shift count"); + int encode = prefix_and_encode(dst->encoding()); + if (imm8 == 1 ) { + emit_byte(0xD1); + emit_byte(0xE0 | encode); + } else { + emit_byte(0xC1); + emit_byte(0xE0 | encode); + emit_byte(imm8); + } +} + +void Assembler::shll(Register dst) { + int encode = prefix_and_encode(dst->encoding()); + emit_byte(0xD3); + emit_byte(0xE0 | encode); +} + +void Assembler::shrl(Register dst, int imm8) { + assert(isShiftCount(imm8), "illegal shift count"); + int encode = prefix_and_encode(dst->encoding()); + emit_byte(0xC1); + emit_byte(0xE8 | encode); + emit_byte(imm8); +} + +void Assembler::shrl(Register dst) { + int encode = prefix_and_encode(dst->encoding()); + emit_byte(0xD3); + emit_byte(0xE8 | encode); +} + +// copies a single word from [esi] to [edi] +void Assembler::smovl() { + emit_byte(0xA5); +} + +void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) { + // HMM Table D-1 says sse2 + // NOT_LP64(assert(VM_Version::supports_sse(), "")); + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF2); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x51); + emit_byte(0xC0 | encode); +} + +void Assembler::stmxcsr( Address dst) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + InstructionMark im(this); + prefix(dst); + emit_byte(0x0F); + emit_byte(0xAE); + emit_operand(as_Register(3), dst); +} + +void Assembler::subl(Address dst, int32_t imm32) { + InstructionMark im(this); + prefix(dst); + if (is8bit(imm32)) { + emit_byte(0x83); + emit_operand(rbp, dst, 1); + emit_byte(imm32 & 0xFF); + } else { + emit_byte(0x81); + emit_operand(rbp, dst, 4); + emit_long(imm32); + } +} + +void Assembler::subl(Register dst, int32_t imm32) { + prefix(dst); + emit_arith(0x81, 0xE8, dst, imm32); +} + +void Assembler::subl(Address dst, Register src) { + InstructionMark im(this); + prefix(dst, src); + emit_byte(0x29); + emit_operand(src, dst); +} + +void Assembler::subl(Register dst, Address src) { + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x2B); + emit_operand(dst, src); +} + +void Assembler::subl(Register dst, Register src) { + (void) prefix_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x2B, 0xC0, dst, src); +} + +void Assembler::subsd(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF2); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x5C); + emit_byte(0xC0 | encode); +} + +void Assembler::subsd(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0xF2); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x5C); + emit_operand(dst, src); +} + +void Assembler::subss(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + emit_byte(0xF3); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x5C); + emit_byte(0xC0 | encode); +} + +void Assembler::subss(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + InstructionMark im(this); + emit_byte(0xF3); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x5C); + emit_operand(dst, src); +} + +void Assembler::testb(Register dst, int imm8) { + NOT_LP64(assert(dst->has_byte_register(), "must have byte register")); + (void) prefix_and_encode(dst->encoding(), true); + emit_arith_b(0xF6, 0xC0, dst, imm8); +} + +void Assembler::testl(Register dst, int32_t imm32) { + // not using emit_arith because test + // doesn't support sign-extension of + // 8bit operands + int encode = dst->encoding(); + if (encode == 0) { + emit_byte(0xA9); + } else { + encode = prefix_and_encode(encode); + emit_byte(0xF7); + emit_byte(0xC0 | encode); + } + emit_long(imm32); +} + +void Assembler::testl(Register dst, Register src) { + (void) prefix_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x85, 0xC0, dst, src); +} + +void Assembler::testl(Register dst, Address src) { + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x85); + emit_operand(dst, src); +} + +void Assembler::ucomisd(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0x66); + ucomiss(dst, src); +} + +void Assembler::ucomisd(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0x66); + ucomiss(dst, src); +} + +void Assembler::ucomiss(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x2E); + emit_operand(dst, src); +} + +void Assembler::ucomiss(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x2E); + emit_byte(0xC0 | encode); +} + + +void Assembler::xaddl(Address dst, Register src) { + InstructionMark im(this); + prefix(dst, src); + emit_byte(0x0F); + emit_byte(0xC1); + emit_operand(src, dst); +} + +void Assembler::xchgl(Register dst, Address src) { // xchg + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x87); + emit_operand(dst, src); +} + +void Assembler::xchgl(Register dst, Register src) { + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x87); + emit_byte(0xc0 | encode); +} + +void Assembler::xorl(Register dst, int32_t imm32) { + prefix(dst); + emit_arith(0x81, 0xF0, dst, imm32); +} + +void Assembler::xorl(Register dst, Address src) { + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x33); + emit_operand(dst, src); +} + +void Assembler::xorl(Register dst, Register src) { + (void) prefix_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x33, 0xC0, dst, src); +} + +void Assembler::xorpd(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0x66); + xorps(dst, src); +} + +void Assembler::xorpd(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0x66); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x57); + emit_operand(dst, src); +} + + +void Assembler::xorps(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x57); + emit_byte(0xC0 | encode); +} + +void Assembler::xorps(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x57); + emit_operand(dst, src); +} + +#ifndef _LP64 +// 32bit only pieces of the assembler + +void Assembler::cmp_literal32(Register src1, int32_t imm32, RelocationHolder const& rspec) { + // NO PREFIX AS NEVER 64BIT + InstructionMark im(this); + emit_byte(0x81); + emit_byte(0xF8 | src1->encoding()); + emit_data(imm32, rspec, 0); +} + +void Assembler::cmp_literal32(Address src1, int32_t imm32, RelocationHolder const& rspec) { + // NO PREFIX AS NEVER 64BIT (not even 32bit versions of 64bit regs + InstructionMark im(this); + emit_byte(0x81); + emit_operand(rdi, src1); + emit_data(imm32, rspec, 0); +} + +// The 64-bit (32bit platform) cmpxchg compares the value at adr with the contents of rdx:rax, +// and stores rcx:rbx into adr if so; otherwise, the value at adr is loaded +// into rdx:rax. The ZF is set if the compared values were equal, and cleared otherwise. +void Assembler::cmpxchg8(Address adr) { + InstructionMark im(this); + emit_byte(0x0F); + emit_byte(0xc7); + emit_operand(rcx, adr); +} + +void Assembler::decl(Register dst) { + // Don't use it directly. Use MacroAssembler::decrementl() instead. + emit_byte(0x48 | dst->encoding()); +} + +#endif // _LP64 + +// 64bit typically doesn't use the x87 but needs to for the trig funcs + +void Assembler::fabs() { + emit_byte(0xD9); + emit_byte(0xE1); +} + +void Assembler::fadd(int i) { + emit_farith(0xD8, 0xC0, i); +} + +void Assembler::fadd_d(Address src) { + InstructionMark im(this); + emit_byte(0xDC); + emit_operand32(rax, src); +} + +void Assembler::fadd_s(Address src) { + InstructionMark im(this); + emit_byte(0xD8); + emit_operand32(rax, src); +} + +void Assembler::fadda(int i) { + emit_farith(0xDC, 0xC0, i); +} + +void Assembler::faddp(int i) { + emit_farith(0xDE, 0xC0, i); +} + +void Assembler::fchs() { + emit_byte(0xD9); + emit_byte(0xE0); +} + +void Assembler::fcom(int i) { + emit_farith(0xD8, 0xD0, i); +} + +void Assembler::fcomp(int i) { + emit_farith(0xD8, 0xD8, i); +} + +void Assembler::fcomp_d(Address src) { + InstructionMark im(this); + emit_byte(0xDC); + emit_operand32(rbx, src); +} + +void Assembler::fcomp_s(Address src) { + InstructionMark im(this); + emit_byte(0xD8); + emit_operand32(rbx, src); +} + +void Assembler::fcompp() { + emit_byte(0xDE); + emit_byte(0xD9); +} + +void Assembler::fcos() { + emit_byte(0xD9); + emit_byte(0xFF); +} + +void Assembler::fdecstp() { + emit_byte(0xD9); + emit_byte(0xF6); +} + +void Assembler::fdiv(int i) { + emit_farith(0xD8, 0xF0, i); +} + +void Assembler::fdiv_d(Address src) { + InstructionMark im(this); + emit_byte(0xDC); + emit_operand32(rsi, src); +} + +void Assembler::fdiv_s(Address src) { + InstructionMark im(this); + emit_byte(0xD8); + emit_operand32(rsi, src); +} + +void Assembler::fdiva(int i) { + emit_farith(0xDC, 0xF8, i); +} + +// Note: The Intel manual (Pentium Processor User's Manual, Vol.3, 1994) +// is erroneous for some of the floating-point instructions below. + +void Assembler::fdivp(int i) { + emit_farith(0xDE, 0xF8, i); // ST(0) <- ST(0) / ST(1) and pop (Intel manual wrong) +} + +void Assembler::fdivr(int i) { + emit_farith(0xD8, 0xF8, i); +} + +void Assembler::fdivr_d(Address src) { + InstructionMark im(this); + emit_byte(0xDC); + emit_operand32(rdi, src); +} + +void Assembler::fdivr_s(Address src) { + InstructionMark im(this); + emit_byte(0xD8); + emit_operand32(rdi, src); +} + +void Assembler::fdivra(int i) { + emit_farith(0xDC, 0xF0, i); +} + +void Assembler::fdivrp(int i) { + emit_farith(0xDE, 0xF0, i); // ST(0) <- ST(1) / ST(0) and pop (Intel manual wrong) +} + +void Assembler::ffree(int i) { + emit_farith(0xDD, 0xC0, i); +} + +void Assembler::fild_d(Address adr) { + InstructionMark im(this); + emit_byte(0xDF); + emit_operand32(rbp, adr); +} + +void Assembler::fild_s(Address adr) { + InstructionMark im(this); + emit_byte(0xDB); + emit_operand32(rax, adr); +} + +void Assembler::fincstp() { + emit_byte(0xD9); + emit_byte(0xF7); +} + +void Assembler::finit() { + emit_byte(0x9B); + emit_byte(0xDB); + emit_byte(0xE3); +} + +void Assembler::fist_s(Address adr) { + InstructionMark im(this); + emit_byte(0xDB); + emit_operand32(rdx, adr); +} + +void Assembler::fistp_d(Address adr) { + InstructionMark im(this); + emit_byte(0xDF); + emit_operand32(rdi, adr); +} + +void Assembler::fistp_s(Address adr) { + InstructionMark im(this); + emit_byte(0xDB); + emit_operand32(rbx, adr); +} + +void Assembler::fld1() { + emit_byte(0xD9); + emit_byte(0xE8); +} + +void Assembler::fld_d(Address adr) { + InstructionMark im(this); + emit_byte(0xDD); + emit_operand32(rax, adr); +} + +void Assembler::fld_s(Address adr) { + InstructionMark im(this); + emit_byte(0xD9); + emit_operand32(rax, adr); +} + + +void Assembler::fld_s(int index) { + emit_farith(0xD9, 0xC0, index); +} + +void Assembler::fld_x(Address adr) { + InstructionMark im(this); + emit_byte(0xDB); + emit_operand32(rbp, adr); +} + +void Assembler::fldcw(Address src) { + InstructionMark im(this); + emit_byte(0xd9); + emit_operand32(rbp, src); +} + +void Assembler::fldenv(Address src) { + InstructionMark im(this); + emit_byte(0xD9); + emit_operand32(rsp, src); +} + +void Assembler::fldlg2() { + emit_byte(0xD9); + emit_byte(0xEC); +} + +void Assembler::fldln2() { + emit_byte(0xD9); + emit_byte(0xED); +} + +void Assembler::fldz() { + emit_byte(0xD9); + emit_byte(0xEE); +} + +void Assembler::flog() { + fldln2(); + fxch(); + fyl2x(); +} + +void Assembler::flog10() { + fldlg2(); + fxch(); + fyl2x(); +} + +void Assembler::fmul(int i) { + emit_farith(0xD8, 0xC8, i); +} + +void Assembler::fmul_d(Address src) { + InstructionMark im(this); + emit_byte(0xDC); + emit_operand32(rcx, src); +} + +void Assembler::fmul_s(Address src) { + InstructionMark im(this); + emit_byte(0xD8); + emit_operand32(rcx, src); +} + +void Assembler::fmula(int i) { + emit_farith(0xDC, 0xC8, i); +} + +void Assembler::fmulp(int i) { + emit_farith(0xDE, 0xC8, i); +} + +void Assembler::fnsave(Address dst) { + InstructionMark im(this); + emit_byte(0xDD); + emit_operand32(rsi, dst); +} + +void Assembler::fnstcw(Address src) { + InstructionMark im(this); + emit_byte(0x9B); + emit_byte(0xD9); + emit_operand32(rdi, src); +} + +void Assembler::fnstsw_ax() { + emit_byte(0xdF); + emit_byte(0xE0); +} + +void Assembler::fprem() { + emit_byte(0xD9); + emit_byte(0xF8); +} + +void Assembler::fprem1() { + emit_byte(0xD9); + emit_byte(0xF5); +} + +void Assembler::frstor(Address src) { + InstructionMark im(this); + emit_byte(0xDD); + emit_operand32(rsp, src); +} + +void Assembler::fsin() { + emit_byte(0xD9); + emit_byte(0xFE); +} + +void Assembler::fsqrt() { + emit_byte(0xD9); + emit_byte(0xFA); +} + +void Assembler::fst_d(Address adr) { + InstructionMark im(this); + emit_byte(0xDD); + emit_operand32(rdx, adr); +} + +void Assembler::fst_s(Address adr) { + InstructionMark im(this); + emit_byte(0xD9); + emit_operand32(rdx, adr); +} + +void Assembler::fstp_d(Address adr) { + InstructionMark im(this); + emit_byte(0xDD); + emit_operand32(rbx, adr); +} + +void Assembler::fstp_d(int index) { + emit_farith(0xDD, 0xD8, index); +} + +void Assembler::fstp_s(Address adr) { + InstructionMark im(this); + emit_byte(0xD9); + emit_operand32(rbx, adr); +} + +void Assembler::fstp_x(Address adr) { + InstructionMark im(this); + emit_byte(0xDB); + emit_operand32(rdi, adr); +} + +void Assembler::fsub(int i) { + emit_farith(0xD8, 0xE0, i); +} + +void Assembler::fsub_d(Address src) { + InstructionMark im(this); + emit_byte(0xDC); + emit_operand32(rsp, src); +} + +void Assembler::fsub_s(Address src) { + InstructionMark im(this); + emit_byte(0xD8); + emit_operand32(rsp, src); +} + +void Assembler::fsuba(int i) { + emit_farith(0xDC, 0xE8, i); +} + +void Assembler::fsubp(int i) { + emit_farith(0xDE, 0xE8, i); // ST(0) <- ST(0) - ST(1) and pop (Intel manual wrong) +} + +void Assembler::fsubr(int i) { + emit_farith(0xD8, 0xE8, i); +} + +void Assembler::fsubr_d(Address src) { + InstructionMark im(this); + emit_byte(0xDC); + emit_operand32(rbp, src); +} + +void Assembler::fsubr_s(Address src) { + InstructionMark im(this); + emit_byte(0xD8); + emit_operand32(rbp, src); +} + +void Assembler::fsubra(int i) { + emit_farith(0xDC, 0xE0, i); +} + +void Assembler::fsubrp(int i) { + emit_farith(0xDE, 0xE0, i); // ST(0) <- ST(1) - ST(0) and pop (Intel manual wrong) +} + +void Assembler::ftan() { + emit_byte(0xD9); + emit_byte(0xF2); + emit_byte(0xDD); + emit_byte(0xD8); +} + +void Assembler::ftst() { + emit_byte(0xD9); + emit_byte(0xE4); +} + +void Assembler::fucomi(int i) { + // make sure the instruction is supported (introduced for P6, together with cmov) + guarantee(VM_Version::supports_cmov(), "illegal instruction"); + emit_farith(0xDB, 0xE8, i); +} + +void Assembler::fucomip(int i) { + // make sure the instruction is supported (introduced for P6, together with cmov) + guarantee(VM_Version::supports_cmov(), "illegal instruction"); + emit_farith(0xDF, 0xE8, i); +} + +void Assembler::fwait() { + emit_byte(0x9B); +} + +void Assembler::fxch(int i) { + emit_farith(0xD9, 0xC8, i); +} + +void Assembler::fyl2x() { + emit_byte(0xD9); + emit_byte(0xF1); +} + +void Assembler::mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec, int format) { + InstructionMark im(this); + int encode = prefix_and_encode(dst->encoding()); + emit_byte(0xB8 | encode); + emit_data((int)imm32, rspec, format); +} + +#ifndef _LP64 + +void Assembler::incl(Register dst) { + // Don't use it directly. Use MacroAssembler::incrementl() instead. + emit_byte(0x40 | dst->encoding()); +} + +void Assembler::lea(Register dst, Address src) { + leal(dst, src); +} + +void Assembler::mov_literal32(Address dst, int32_t imm32, RelocationHolder const& rspec) { + InstructionMark im(this); + emit_byte(0xC7); + emit_operand(rax, dst); + emit_data((int)imm32, rspec, 0); +} + + +void Assembler::popa() { // 32bit + emit_byte(0x61); +} + +void Assembler::push_literal32(int32_t imm32, RelocationHolder const& rspec) { + InstructionMark im(this); + emit_byte(0x68); + emit_data(imm32, rspec, 0); +} + +void Assembler::pusha() { // 32bit + emit_byte(0x60); +} + +void Assembler::set_byte_if_not_zero(Register dst) { + emit_byte(0x0F); + emit_byte(0x95); + emit_byte(0xE0 | dst->encoding()); +} + +void Assembler::shldl(Register dst, Register src) { + emit_byte(0x0F); + emit_byte(0xA5); + emit_byte(0xC0 | src->encoding() << 3 | dst->encoding()); +} + +void Assembler::shrdl(Register dst, Register src) { + emit_byte(0x0F); + emit_byte(0xAD); + emit_byte(0xC0 | src->encoding() << 3 | dst->encoding()); +} + +#else // LP64 + +// 64bit only pieces of the assembler +// This should only be used by 64bit instructions that can use rip-relative +// it cannot be used by instructions that want an immediate value. + +bool Assembler::reachable(AddressLiteral adr) { + int64_t disp; + // None will force a 64bit literal to the code stream. Likely a placeholder + // for something that will be patched later and we need to certain it will + // always be reachable. + if (adr.reloc() == relocInfo::none) { + return false; + } + if (adr.reloc() == relocInfo::internal_word_type) { + // This should be rip relative and easily reachable. + return true; + } + if (adr.reloc() == relocInfo::virtual_call_type || + adr.reloc() == relocInfo::opt_virtual_call_type || + adr.reloc() == relocInfo::static_call_type || + adr.reloc() == relocInfo::static_stub_type ) { + // This should be rip relative within the code cache and easily + // reachable until we get huge code caches. (At which point + // ic code is going to have issues). + return true; + } + if (adr.reloc() != relocInfo::external_word_type && + adr.reloc() != relocInfo::poll_return_type && // these are really external_word but need special + adr.reloc() != relocInfo::poll_type && // relocs to identify them + adr.reloc() != relocInfo::runtime_call_type ) { + return false; + } + + // Stress the correction code + if (ForceUnreachable) { + // Must be runtimecall reloc, see if it is in the codecache + // Flipping stuff in the codecache to be unreachable causes issues + // with things like inline caches where the additional instructions + // are not handled. + if (CodeCache::find_blob(adr._target) == NULL) { + return false; + } + } + // For external_word_type/runtime_call_type if it is reachable from where we + // are now (possibly a temp buffer) and where we might end up + // anywhere in the codeCache then we are always reachable. + // This would have to change if we ever save/restore shared code + // to be more pessimistic. + + disp = (int64_t)adr._target - ((int64_t)CodeCache::low_bound() + sizeof(int)); + if (!is_simm32(disp)) return false; + disp = (int64_t)adr._target - ((int64_t)CodeCache::high_bound() + sizeof(int)); + if (!is_simm32(disp)) return false; + + disp = (int64_t)adr._target - ((int64_t)_code_pos + sizeof(int)); + + // Because rip relative is a disp + address_of_next_instruction and we + // don't know the value of address_of_next_instruction we apply a fudge factor + // to make sure we will be ok no matter the size of the instruction we get placed into. + // We don't have to fudge the checks above here because they are already worst case. + + // 12 == override/rex byte, opcode byte, rm byte, sib byte, a 4-byte disp , 4-byte literal + // + 4 because better safe than sorry. + const int fudge = 12 + 4; + if (disp < 0) { + disp -= fudge; + } else { + disp += fudge; + } + return is_simm32(disp); +} + +void Assembler::emit_data64(jlong data, + relocInfo::relocType rtype, + int format) { + if (rtype == relocInfo::none) { + emit_long64(data); + } else { + emit_data64(data, Relocation::spec_simple(rtype), format); + } +} + +void Assembler::emit_data64(jlong data, + RelocationHolder const& rspec, + int format) { + assert(imm_operand == 0, "default format must be immediate in this file"); + assert(imm_operand == format, "must be immediate"); + assert(inst_mark() != NULL, "must be inside InstructionMark"); + // Do not use AbstractAssembler::relocate, which is not intended for + // embedded words. Instead, relocate to the enclosing instruction. + code_section()->relocate(inst_mark(), rspec, format); +#ifdef ASSERT + check_relocation(rspec, format); +#endif + emit_long64(data); +} + +int Assembler::prefix_and_encode(int reg_enc, bool byteinst) { + if (reg_enc >= 8) { + prefix(REX_B); + reg_enc -= 8; + } else if (byteinst && reg_enc >= 4) { + prefix(REX); + } + return reg_enc; +} + +int Assembler::prefixq_and_encode(int reg_enc) { + if (reg_enc < 8) { + prefix(REX_W); + } else { + prefix(REX_WB); + reg_enc -= 8; + } + return reg_enc; +} + +int Assembler::prefix_and_encode(int dst_enc, int src_enc, bool byteinst) { + if (dst_enc < 8) { + if (src_enc >= 8) { + prefix(REX_B); + src_enc -= 8; + } else if (byteinst && src_enc >= 4) { + prefix(REX); + } + } else { + if (src_enc < 8) { + prefix(REX_R); + } else { + prefix(REX_RB); + src_enc -= 8; + } + dst_enc -= 8; + } + return dst_enc << 3 | src_enc; +} + +int Assembler::prefixq_and_encode(int dst_enc, int src_enc) { + if (dst_enc < 8) { + if (src_enc < 8) { + prefix(REX_W); + } else { + prefix(REX_WB); + src_enc -= 8; + } + } else { + if (src_enc < 8) { + prefix(REX_WR); + } else { + prefix(REX_WRB); + src_enc -= 8; + } + dst_enc -= 8; + } + return dst_enc << 3 | src_enc; +} + +void Assembler::prefix(Register reg) { + if (reg->encoding() >= 8) { + prefix(REX_B); + } +} + +void Assembler::prefix(Address adr) { + if (adr.base_needs_rex()) { + if (adr.index_needs_rex()) { + prefix(REX_XB); + } else { + prefix(REX_B); + } + } else { + if (adr.index_needs_rex()) { + prefix(REX_X); + } + } +} + +void Assembler::prefixq(Address adr) { + if (adr.base_needs_rex()) { + if (adr.index_needs_rex()) { + prefix(REX_WXB); + } else { + prefix(REX_WB); + } + } else { + if (adr.index_needs_rex()) { + prefix(REX_WX); + } else { + prefix(REX_W); + } + } +} + + +void Assembler::prefix(Address adr, Register reg, bool byteinst) { + if (reg->encoding() < 8) { + if (adr.base_needs_rex()) { + if (adr.index_needs_rex()) { + prefix(REX_XB); + } else { + prefix(REX_B); + } + } else { + if (adr.index_needs_rex()) { + prefix(REX_X); + } else if (reg->encoding() >= 4 ) { + prefix(REX); + } + } + } else { + if (adr.base_needs_rex()) { + if (adr.index_needs_rex()) { + prefix(REX_RXB); + } else { + prefix(REX_RB); + } + } else { + if (adr.index_needs_rex()) { + prefix(REX_RX); + } else { + prefix(REX_R); + } + } + } +} + +void Assembler::prefixq(Address adr, Register src) { + if (src->encoding() < 8) { + if (adr.base_needs_rex()) { + if (adr.index_needs_rex()) { + prefix(REX_WXB); + } else { + prefix(REX_WB); + } + } else { + if (adr.index_needs_rex()) { + prefix(REX_WX); + } else { + prefix(REX_W); + } + } + } else { + if (adr.base_needs_rex()) { + if (adr.index_needs_rex()) { + prefix(REX_WRXB); + } else { + prefix(REX_WRB); + } + } else { + if (adr.index_needs_rex()) { + prefix(REX_WRX); + } else { + prefix(REX_WR); + } + } + } +} + +void Assembler::prefix(Address adr, XMMRegister reg) { + if (reg->encoding() < 8) { + if (adr.base_needs_rex()) { + if (adr.index_needs_rex()) { + prefix(REX_XB); + } else { + prefix(REX_B); + } + } else { + if (adr.index_needs_rex()) { + prefix(REX_X); + } + } + } else { + if (adr.base_needs_rex()) { + if (adr.index_needs_rex()) { + prefix(REX_RXB); + } else { + prefix(REX_RB); + } + } else { + if (adr.index_needs_rex()) { + prefix(REX_RX); + } else { + prefix(REX_R); + } + } + } +} + +void Assembler::adcq(Register dst, int32_t imm32) { + (void) prefixq_and_encode(dst->encoding()); + emit_arith(0x81, 0xD0, dst, imm32); +} + +void Assembler::adcq(Register dst, Address src) { + InstructionMark im(this); + prefixq(src, dst); + emit_byte(0x13); + emit_operand(dst, src); +} + +void Assembler::adcq(Register dst, Register src) { + (int) prefixq_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x13, 0xC0, dst, src); +} + +void Assembler::addq(Address dst, int32_t imm32) { + InstructionMark im(this); + prefixq(dst); + emit_arith_operand(0x81, rax, dst,imm32); +} + +void Assembler::addq(Address dst, Register src) { + InstructionMark im(this); + prefixq(dst, src); + emit_byte(0x01); + emit_operand(src, dst); +} + +void Assembler::addq(Register dst, int32_t imm32) { + (void) prefixq_and_encode(dst->encoding()); + emit_arith(0x81, 0xC0, dst, imm32); +} + +void Assembler::addq(Register dst, Address src) { + InstructionMark im(this); + prefixq(src, dst); + emit_byte(0x03); + emit_operand(dst, src); +} + +void Assembler::addq(Register dst, Register src) { + (void) prefixq_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x03, 0xC0, dst, src); +} + +void Assembler::andq(Register dst, int32_t imm32) { + (void) prefixq_and_encode(dst->encoding()); + emit_arith(0x81, 0xE0, dst, imm32); +} + +void Assembler::andq(Register dst, Address src) { + InstructionMark im(this); + prefixq(src, dst); + emit_byte(0x23); + emit_operand(dst, src); +} + +void Assembler::andq(Register dst, Register src) { + (int) prefixq_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x23, 0xC0, dst, src); +} + +void Assembler::bswapq(Register reg) { + int encode = prefixq_and_encode(reg->encoding()); + emit_byte(0x0F); + emit_byte(0xC8 | encode); +} + +void Assembler::cdqq() { + prefix(REX_W); + emit_byte(0x99); +} + void Assembler::clflush(Address adr) { prefix(adr); emit_byte(0x0F); @@ -2925,185 +3614,119 @@ void Assembler::clflush(Address adr) { emit_operand(rdi, adr); } -void Assembler::call(Label& L, relocInfo::relocType rtype) { - if (L.is_bound()) { - const int long_size = 5; - int offs = (int)( target(L) - pc() ); - assert(offs <= 0, "assembler error"); - InstructionMark im(this); - // 1110 1000 #32-bit disp - emit_byte(0xE8); - emit_data(offs - long_size, rtype, disp32_operand); - } else { - InstructionMark im(this); - // 1110 1000 #32-bit disp - L.add_patch_at(code(), locator()); - - emit_byte(0xE8); - emit_data(int(0), rtype, disp32_operand); - } +void Assembler::cmovq(Condition cc, Register dst, Register src) { + int encode = prefixq_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x40 | cc); + emit_byte(0xC0 | encode); } -void Assembler::call_literal(address entry, RelocationHolder const& rspec) { - assert(entry != NULL, "call most probably wrong"); +void Assembler::cmovq(Condition cc, Register dst, Address src) { InstructionMark im(this); - emit_byte(0xE8); - intptr_t disp = entry - (_code_pos + sizeof(int32_t)); - assert(is_simm32(disp), "must be 32bit offset (call2)"); - // Technically, should use call32_operand, but this format is - // implied by the fact that we're emitting a call instruction. - emit_data((int) disp, rspec, disp32_operand); + prefixq(src, dst); + emit_byte(0x0F); + emit_byte(0x40 | cc); + emit_operand(dst, src); } +void Assembler::cmpq(Address dst, int32_t imm32) { + InstructionMark im(this); + prefixq(dst); + emit_byte(0x81); + emit_operand(rdi, dst, 4); + emit_long(imm32); +} -void Assembler::call(Register dst) { - // This was originally using a 32bit register encoding - // and surely we want 64bit! - // this is a 32bit encoding but in 64bit mode the default - // operand size is 64bit so there is no need for the - // wide prefix. So prefix only happens if we use the - // new registers. Much like push/pop. +void Assembler::cmpq(Register dst, int32_t imm32) { + (void) prefixq_and_encode(dst->encoding()); + emit_arith(0x81, 0xF8, dst, imm32); +} + +void Assembler::cmpq(Address dst, Register src) { + InstructionMark im(this); + prefixq(dst, src); + emit_byte(0x3B); + emit_operand(src, dst); +} + +void Assembler::cmpq(Register dst, Register src) { + (void) prefixq_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x3B, 0xC0, dst, src); +} + +void Assembler::cmpq(Register dst, Address src) { + InstructionMark im(this); + prefixq(src, dst); + emit_byte(0x3B); + emit_operand(dst, src); +} + +void Assembler::cmpxchgq(Register reg, Address adr) { + InstructionMark im(this); + prefixq(adr, reg); + emit_byte(0x0F); + emit_byte(0xB1); + emit_operand(reg, adr); +} + +void Assembler::cvtsi2sdq(XMMRegister dst, Register src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF2); + int encode = prefixq_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x2A); + emit_byte(0xC0 | encode); +} + +void Assembler::cvtsi2ssq(XMMRegister dst, Register src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + emit_byte(0xF3); + int encode = prefixq_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x2A); + emit_byte(0xC0 | encode); +} + +void Assembler::cvttsd2siq(Register dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF2); + int encode = prefixq_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x2C); + emit_byte(0xC0 | encode); +} + +void Assembler::cvttss2siq(Register dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + emit_byte(0xF3); + int encode = prefixq_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x2C); + emit_byte(0xC0 | encode); +} + +void Assembler::decl(Register dst) { + // Don't use it directly. Use MacroAssembler::decrementl() instead. + // Use two-byte form (one-byte form is a REX prefix in 64-bit mode) + int encode = prefix_and_encode(dst->encoding()); + emit_byte(0xFF); + emit_byte(0xC8 | encode); +} + +void Assembler::decq(Register dst) { + // Don't use it directly. Use MacroAssembler::decrementq() instead. + // Use two-byte form (one-byte from is a REX prefix in 64-bit mode) int encode = prefixq_and_encode(dst->encoding()); emit_byte(0xFF); - emit_byte(0xD0 | encode); + emit_byte(0xC8 | encode); } -void Assembler::call(Address adr) { +void Assembler::decq(Address dst) { + // Don't use it directly. Use MacroAssembler::decrementq() instead. InstructionMark im(this); - prefix(adr); - emit_byte(0xFF); - emit_operand(rdx, adr); -} - -void Assembler::jmp(Register reg) { - int encode = prefix_and_encode(reg->encoding()); - emit_byte(0xFF); - emit_byte(0xE0 | encode); -} - -void Assembler::jmp(Address adr) { - InstructionMark im(this); - prefix(adr); - emit_byte(0xFF); - emit_operand(rsp, adr); -} - -void Assembler::jmp_literal(address dest, RelocationHolder const& rspec) { - InstructionMark im(this); - emit_byte(0xE9); - assert(dest != NULL, "must have a target"); - intptr_t disp = dest - (_code_pos + sizeof(int32_t)); - assert(is_simm32(disp), "must be 32bit offset (jmp)"); - emit_data(disp, rspec.reloc(), call32_operand); -} - -void Assembler::jmp(Label& L, relocInfo::relocType rtype) { - if (L.is_bound()) { - address entry = target(L); - assert(entry != NULL, "jmp most probably wrong"); - InstructionMark im(this); - const int short_size = 2; - const int long_size = 5; - intptr_t offs = entry - _code_pos; - if (rtype == relocInfo::none && is8bit(offs - short_size)) { - emit_byte(0xEB); - emit_byte((offs - short_size) & 0xFF); - } else { - emit_byte(0xE9); - emit_long(offs - long_size); - } - } else { - // By default, forward jumps are always 32-bit displacements, since - // we can't yet know where the label will be bound. If you're sure that - // the forward jump will not run beyond 256 bytes, use jmpb to - // force an 8-bit displacement. - InstructionMark im(this); - relocate(rtype); - L.add_patch_at(code(), locator()); - emit_byte(0xE9); - emit_long(0); - } -} - -void Assembler::jmpb(Label& L) { - if (L.is_bound()) { - const int short_size = 2; - address entry = target(L); - assert(is8bit((entry - _code_pos) + short_size), - "Dispacement too large for a short jmp"); - assert(entry != NULL, "jmp most probably wrong"); - intptr_t offs = entry - _code_pos; - emit_byte(0xEB); - emit_byte((offs - short_size) & 0xFF); - } else { - InstructionMark im(this); - L.add_patch_at(code(), locator()); - emit_byte(0xEB); - emit_byte(0); - } -} - -void Assembler::jcc(Condition cc, Label& L, relocInfo::relocType rtype) { - InstructionMark im(this); - relocate(rtype); - assert((0 <= cc) && (cc < 16), "illegal cc"); - if (L.is_bound()) { - address dst = target(L); - assert(dst != NULL, "jcc most probably wrong"); - - const int short_size = 2; - const int long_size = 6; - intptr_t offs = (intptr_t)dst - (intptr_t)_code_pos; - if (rtype == relocInfo::none && is8bit(offs - short_size)) { - // 0111 tttn #8-bit disp - emit_byte(0x70 | cc); - emit_byte((offs - short_size) & 0xFF); - } else { - // 0000 1111 1000 tttn #32-bit disp - assert(is_simm32(offs - long_size), - "must be 32bit offset (call4)"); - emit_byte(0x0F); - emit_byte(0x80 | cc); - emit_long(offs - long_size); - } - } else { - // Note: could eliminate cond. jumps to this jump if condition - // is the same however, seems to be rather unlikely case. - // Note: use jccb() if label to be bound is very close to get - // an 8-bit displacement - L.add_patch_at(code(), locator()); - emit_byte(0x0F); - emit_byte(0x80 | cc); - emit_long(0); - } -} - -void Assembler::jccb(Condition cc, Label& L) { - if (L.is_bound()) { - const int short_size = 2; - const int long_size = 6; - address entry = target(L); - assert(is8bit((intptr_t)entry - ((intptr_t)_code_pos + short_size)), - "Dispacement too large for a short jmp"); - intptr_t offs = (intptr_t)entry - (intptr_t)_code_pos; - // 0111 tttn #8-bit disp - emit_byte(0x70 | cc); - emit_byte((offs - short_size) & 0xFF); - } else { - InstructionMark im(this); - L.add_patch_at(code(), locator()); - emit_byte(0x70 | cc); - emit_byte(0); - } -} - -// FP instructions - -void Assembler::fxsave(Address dst) { prefixq(dst); - emit_byte(0x0F); - emit_byte(0xAE); - emit_operand(as_Register(0), dst); + emit_byte(0xFF); + emit_operand(rcx, dst); } void Assembler::fxrstor(Address src) { @@ -3113,167 +3736,347 @@ void Assembler::fxrstor(Address src) { emit_operand(as_Register(1), src); } -void Assembler::ldmxcsr(Address src) { - InstructionMark im(this); - prefix(src); +void Assembler::fxsave(Address dst) { + prefixq(dst); emit_byte(0x0F); emit_byte(0xAE); - emit_operand(as_Register(2), src); + emit_operand(as_Register(0), dst); } -void Assembler::stmxcsr(Address dst) { - InstructionMark im(this); - prefix(dst); - emit_byte(0x0F); - emit_byte(0xAE); - emit_operand(as_Register(3), dst); +void Assembler::idivq(Register src) { + int encode = prefixq_and_encode(src->encoding()); + emit_byte(0xF7); + emit_byte(0xF8 | encode); } -void Assembler::addss(XMMRegister dst, XMMRegister src) { - emit_byte(0xF3); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); +void Assembler::imulq(Register dst, Register src) { + int encode = prefixq_and_encode(dst->encoding(), src->encoding()); emit_byte(0x0F); - emit_byte(0x58); + emit_byte(0xAF); emit_byte(0xC0 | encode); } -void Assembler::addss(XMMRegister dst, Address src) { +void Assembler::imulq(Register dst, Register src, int value) { + int encode = prefixq_and_encode(dst->encoding(), src->encoding()); + if (is8bit(value)) { + emit_byte(0x6B); + emit_byte(0xC0 | encode); + emit_byte(value); + } else { + emit_byte(0x69); + emit_byte(0xC0 | encode); + emit_long(value); + } +} + +void Assembler::incl(Register dst) { + // Don't use it directly. Use MacroAssembler::incrementl() instead. + // Use two-byte form (one-byte from is a REX prefix in 64-bit mode) + int encode = prefix_and_encode(dst->encoding()); + emit_byte(0xFF); + emit_byte(0xC0 | encode); +} + +void Assembler::incq(Register dst) { + // Don't use it directly. Use MacroAssembler::incrementq() instead. + // Use two-byte form (one-byte from is a REX prefix in 64-bit mode) + int encode = prefixq_and_encode(dst->encoding()); + emit_byte(0xFF); + emit_byte(0xC0 | encode); +} + +void Assembler::incq(Address dst) { + // Don't use it directly. Use MacroAssembler::incrementq() instead. InstructionMark im(this); - emit_byte(0xF3); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x58); + prefixq(dst); + emit_byte(0xFF); + emit_operand(rax, dst); +} + +void Assembler::lea(Register dst, Address src) { + leaq(dst, src); +} + +void Assembler::leaq(Register dst, Address src) { + InstructionMark im(this); + prefixq(src, dst); + emit_byte(0x8D); emit_operand(dst, src); } -void Assembler::subss(XMMRegister dst, XMMRegister src) { - emit_byte(0xF3); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); +void Assembler::mov64(Register dst, int64_t imm64) { + InstructionMark im(this); + int encode = prefixq_and_encode(dst->encoding()); + emit_byte(0xB8 | encode); + emit_long64(imm64); +} + +void Assembler::mov_literal64(Register dst, intptr_t imm64, RelocationHolder const& rspec) { + InstructionMark im(this); + int encode = prefixq_and_encode(dst->encoding()); + emit_byte(0xB8 | encode); + emit_data64(imm64, rspec); +} + +void Assembler::movdq(XMMRegister dst, Register src) { + // table D-1 says MMX/SSE2 + NOT_LP64(assert(VM_Version::supports_sse2() || VM_Version::supports_mmx(), "")); + emit_byte(0x66); + int encode = prefixq_and_encode(dst->encoding(), src->encoding()); emit_byte(0x0F); - emit_byte(0x5C); + emit_byte(0x6E); emit_byte(0xC0 | encode); } -void Assembler::subss(XMMRegister dst, Address src) { - InstructionMark im(this); - emit_byte(0xF3); - prefix(src, dst); +void Assembler::movdq(Register dst, XMMRegister src) { + // table D-1 says MMX/SSE2 + NOT_LP64(assert(VM_Version::supports_sse2() || VM_Version::supports_mmx(), "")); + emit_byte(0x66); + // swap src/dst to get correct prefix + int encode = prefixq_and_encode(src->encoding(), dst->encoding()); emit_byte(0x0F); - emit_byte(0x5C); + emit_byte(0x7E); + emit_byte(0xC0 | encode); +} + +void Assembler::movq(Register dst, Register src) { + int encode = prefixq_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x8B); + emit_byte(0xC0 | encode); +} + +void Assembler::movq(Register dst, Address src) { + InstructionMark im(this); + prefixq(src, dst); + emit_byte(0x8B); emit_operand(dst, src); } -void Assembler::mulss(XMMRegister dst, XMMRegister src) { - emit_byte(0xF3); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x59); - emit_byte(0xC0 | encode); +void Assembler::movq(Address dst, Register src) { + InstructionMark im(this); + prefixq(dst, src); + emit_byte(0x89); + emit_operand(src, dst); } -void Assembler::mulss(XMMRegister dst, Address src) { +void Assembler::movslq(Register dst, int32_t imm32) { + // dbx shows movslq(rcx, 3) as movq $0x0000000049000000,(%rbx) + // and movslq(r8, 3); as movl $0x0000000048000000,(%rbx) + // as a result we shouldn't use until tested at runtime... + ShouldNotReachHere(); InstructionMark im(this); - emit_byte(0xF3); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x59); + int encode = prefixq_and_encode(dst->encoding()); + emit_byte(0xC7 | encode); + emit_long(imm32); +} + +void Assembler::movslq(Address dst, int32_t imm32) { + assert(is_simm32(imm32), "lost bits"); + InstructionMark im(this); + prefixq(dst); + emit_byte(0xC7); + emit_operand(rax, dst, 4); + emit_long(imm32); +} + +void Assembler::movslq(Register dst, Address src) { + InstructionMark im(this); + prefixq(src, dst); + emit_byte(0x63); emit_operand(dst, src); } -void Assembler::divss(XMMRegister dst, XMMRegister src) { - emit_byte(0xF3); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x5E); +void Assembler::movslq(Register dst, Register src) { + int encode = prefixq_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x63); emit_byte(0xC0 | encode); } -void Assembler::divss(XMMRegister dst, Address src) { +void Assembler::negq(Register dst) { + int encode = prefixq_and_encode(dst->encoding()); + emit_byte(0xF7); + emit_byte(0xD8 | encode); +} + +void Assembler::notq(Register dst) { + int encode = prefixq_and_encode(dst->encoding()); + emit_byte(0xF7); + emit_byte(0xD0 | encode); +} + +void Assembler::orq(Address dst, int32_t imm32) { InstructionMark im(this); - emit_byte(0xF3); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x5E); + prefixq(dst); + emit_byte(0x81); + emit_operand(rcx, dst, 4); + emit_long(imm32); +} + +void Assembler::orq(Register dst, int32_t imm32) { + (void) prefixq_and_encode(dst->encoding()); + emit_arith(0x81, 0xC8, dst, imm32); +} + +void Assembler::orq(Register dst, Address src) { + InstructionMark im(this); + prefixq(src, dst); + emit_byte(0x0B); emit_operand(dst, src); } -void Assembler::addsd(XMMRegister dst, XMMRegister src) { - emit_byte(0xF2); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x58); - emit_byte(0xC0 | encode); +void Assembler::orq(Register dst, Register src) { + (void) prefixq_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x0B, 0xC0, dst, src); } -void Assembler::addsd(XMMRegister dst, Address src) { +void Assembler::popa() { // 64bit + movq(r15, Address(rsp, 0)); + movq(r14, Address(rsp, wordSize)); + movq(r13, Address(rsp, 2 * wordSize)); + movq(r12, Address(rsp, 3 * wordSize)); + movq(r11, Address(rsp, 4 * wordSize)); + movq(r10, Address(rsp, 5 * wordSize)); + movq(r9, Address(rsp, 6 * wordSize)); + movq(r8, Address(rsp, 7 * wordSize)); + movq(rdi, Address(rsp, 8 * wordSize)); + movq(rsi, Address(rsp, 9 * wordSize)); + movq(rbp, Address(rsp, 10 * wordSize)); + // skip rsp + movq(rbx, Address(rsp, 12 * wordSize)); + movq(rdx, Address(rsp, 13 * wordSize)); + movq(rcx, Address(rsp, 14 * wordSize)); + movq(rax, Address(rsp, 15 * wordSize)); + + addq(rsp, 16 * wordSize); +} + +void Assembler::popq(Address dst) { InstructionMark im(this); - emit_byte(0xF2); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x58); + prefixq(dst); + emit_byte(0x8F); + emit_operand(rax, dst); +} + +void Assembler::pusha() { // 64bit + // we have to store original rsp. ABI says that 128 bytes + // below rsp are local scratch. + movq(Address(rsp, -5 * wordSize), rsp); + + subq(rsp, 16 * wordSize); + + movq(Address(rsp, 15 * wordSize), rax); + movq(Address(rsp, 14 * wordSize), rcx); + movq(Address(rsp, 13 * wordSize), rdx); + movq(Address(rsp, 12 * wordSize), rbx); + // skip rsp + movq(Address(rsp, 10 * wordSize), rbp); + movq(Address(rsp, 9 * wordSize), rsi); + movq(Address(rsp, 8 * wordSize), rdi); + movq(Address(rsp, 7 * wordSize), r8); + movq(Address(rsp, 6 * wordSize), r9); + movq(Address(rsp, 5 * wordSize), r10); + movq(Address(rsp, 4 * wordSize), r11); + movq(Address(rsp, 3 * wordSize), r12); + movq(Address(rsp, 2 * wordSize), r13); + movq(Address(rsp, wordSize), r14); + movq(Address(rsp, 0), r15); +} + +void Assembler::pushq(Address src) { + InstructionMark im(this); + prefixq(src); + emit_byte(0xFF); + emit_operand(rsi, src); +} + +void Assembler::rclq(Register dst, int imm8) { + assert(isShiftCount(imm8 >> 1), "illegal shift count"); + int encode = prefixq_and_encode(dst->encoding()); + if (imm8 == 1) { + emit_byte(0xD1); + emit_byte(0xD0 | encode); + } else { + emit_byte(0xC1); + emit_byte(0xD0 | encode); + emit_byte(imm8); + } +} +void Assembler::sarq(Register dst, int imm8) { + assert(isShiftCount(imm8 >> 1), "illegal shift count"); + int encode = prefixq_and_encode(dst->encoding()); + if (imm8 == 1) { + emit_byte(0xD1); + emit_byte(0xF8 | encode); + } else { + emit_byte(0xC1); + emit_byte(0xF8 | encode); + emit_byte(imm8); + } +} + +void Assembler::sarq(Register dst) { + int encode = prefixq_and_encode(dst->encoding()); + emit_byte(0xD3); + emit_byte(0xF8 | encode); +} +void Assembler::sbbq(Address dst, int32_t imm32) { + InstructionMark im(this); + prefixq(dst); + emit_arith_operand(0x81, rbx, dst, imm32); +} + +void Assembler::sbbq(Register dst, int32_t imm32) { + (void) prefixq_and_encode(dst->encoding()); + emit_arith(0x81, 0xD8, dst, imm32); +} + +void Assembler::sbbq(Register dst, Address src) { + InstructionMark im(this); + prefixq(src, dst); + emit_byte(0x1B); emit_operand(dst, src); } -void Assembler::subsd(XMMRegister dst, XMMRegister src) { - emit_byte(0xF2); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x5C); - emit_byte(0xC0 | encode); +void Assembler::sbbq(Register dst, Register src) { + (void) prefixq_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x1B, 0xC0, dst, src); } -void Assembler::subsd(XMMRegister dst, Address src) { - InstructionMark im(this); - emit_byte(0xF2); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x5C); - emit_operand(dst, src); +void Assembler::shlq(Register dst, int imm8) { + assert(isShiftCount(imm8 >> 1), "illegal shift count"); + int encode = prefixq_and_encode(dst->encoding()); + if (imm8 == 1) { + emit_byte(0xD1); + emit_byte(0xE0 | encode); + } else { + emit_byte(0xC1); + emit_byte(0xE0 | encode); + emit_byte(imm8); + } } -void Assembler::mulsd(XMMRegister dst, XMMRegister src) { - emit_byte(0xF2); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x59); - emit_byte(0xC0 | encode); +void Assembler::shlq(Register dst) { + int encode = prefixq_and_encode(dst->encoding()); + emit_byte(0xD3); + emit_byte(0xE0 | encode); } -void Assembler::mulsd(XMMRegister dst, Address src) { - InstructionMark im(this); - emit_byte(0xF2); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x59); - emit_operand(dst, src); +void Assembler::shrq(Register dst, int imm8) { + assert(isShiftCount(imm8 >> 1), "illegal shift count"); + int encode = prefixq_and_encode(dst->encoding()); + emit_byte(0xC1); + emit_byte(0xE8 | encode); + emit_byte(imm8); } -void Assembler::divsd(XMMRegister dst, XMMRegister src) { - emit_byte(0xF2); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x5E); - emit_byte(0xC0 | encode); -} - -void Assembler::divsd(XMMRegister dst, Address src) { - InstructionMark im(this); - emit_byte(0xF2); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x5E); - emit_operand(dst, src); -} - -void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) { - emit_byte(0xF2); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x51); - emit_byte(0xC0 | encode); +void Assembler::shrq(Register dst) { + int encode = prefixq_and_encode(dst->encoding()); + emit_byte(0xD3); + emit_byte(0xE8 | encode); } void Assembler::sqrtsd(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); InstructionMark im(this); emit_byte(0xF2); prefix(src, dst); @@ -3282,171 +4085,99 @@ void Assembler::sqrtsd(XMMRegister dst, Address src) { emit_operand(dst, src); } -void Assembler::xorps(XMMRegister dst, XMMRegister src) { - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x57); - emit_byte(0xC0 | encode); +void Assembler::subq(Address dst, int32_t imm32) { + InstructionMark im(this); + prefixq(dst); + if (is8bit(imm32)) { + emit_byte(0x83); + emit_operand(rbp, dst, 1); + emit_byte(imm32 & 0xFF); + } else { + emit_byte(0x81); + emit_operand(rbp, dst, 4); + emit_long(imm32); + } } -void Assembler::xorps(XMMRegister dst, Address src) { +void Assembler::subq(Register dst, int32_t imm32) { + (void) prefixq_and_encode(dst->encoding()); + emit_arith(0x81, 0xE8, dst, imm32); +} + +void Assembler::subq(Address dst, Register src) { InstructionMark im(this); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x57); + prefixq(dst, src); + emit_byte(0x29); + emit_operand(src, dst); +} + +void Assembler::subq(Register dst, Address src) { + InstructionMark im(this); + prefixq(src, dst); + emit_byte(0x2B); emit_operand(dst, src); } -void Assembler::xorpd(XMMRegister dst, XMMRegister src) { - emit_byte(0x66); - xorps(dst, src); +void Assembler::subq(Register dst, Register src) { + (void) prefixq_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x2B, 0xC0, dst, src); } -void Assembler::xorpd(XMMRegister dst, Address src) { +void Assembler::testq(Register dst, int32_t imm32) { + // not using emit_arith because test + // doesn't support sign-extension of + // 8bit operands + int encode = dst->encoding(); + if (encode == 0) { + prefix(REX_W); + emit_byte(0xA9); + } else { + encode = prefixq_and_encode(encode); + emit_byte(0xF7); + emit_byte(0xC0 | encode); + } + emit_long(imm32); +} + +void Assembler::testq(Register dst, Register src) { + (void) prefixq_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x85, 0xC0, dst, src); +} + +void Assembler::xaddq(Address dst, Register src) { InstructionMark im(this); - emit_byte(0x66); - prefix(src, dst); + prefixq(dst, src); emit_byte(0x0F); - emit_byte(0x57); + emit_byte(0xC1); + emit_operand(src, dst); +} + +void Assembler::xchgq(Register dst, Address src) { + InstructionMark im(this); + prefixq(src, dst); + emit_byte(0x87); emit_operand(dst, src); } -void Assembler::cvtsi2ssl(XMMRegister dst, Register src) { - emit_byte(0xF3); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x2A); - emit_byte(0xC0 | encode); -} - -void Assembler::cvtsi2ssq(XMMRegister dst, Register src) { - emit_byte(0xF3); +void Assembler::xchgq(Register dst, Register src) { int encode = prefixq_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x2A); - emit_byte(0xC0 | encode); + emit_byte(0x87); + emit_byte(0xc0 | encode); } -void Assembler::cvtsi2sdl(XMMRegister dst, Register src) { - emit_byte(0xF2); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x2A); - emit_byte(0xC0 | encode); +void Assembler::xorq(Register dst, Register src) { + (void) prefixq_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x33, 0xC0, dst, src); } -void Assembler::cvtsi2sdq(XMMRegister dst, Register src) { - emit_byte(0xF2); - int encode = prefixq_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x2A); - emit_byte(0xC0 | encode); +void Assembler::xorq(Register dst, Address src) { + InstructionMark im(this); + prefixq(src, dst); + emit_byte(0x33); + emit_operand(dst, src); } -void Assembler::cvttss2sil(Register dst, XMMRegister src) { - emit_byte(0xF3); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x2C); - emit_byte(0xC0 | encode); -} - -void Assembler::cvttss2siq(Register dst, XMMRegister src) { - emit_byte(0xF3); - int encode = prefixq_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x2C); - emit_byte(0xC0 | encode); -} - -void Assembler::cvttsd2sil(Register dst, XMMRegister src) { - emit_byte(0xF2); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x2C); - emit_byte(0xC0 | encode); -} - -void Assembler::cvttsd2siq(Register dst, XMMRegister src) { - emit_byte(0xF2); - int encode = prefixq_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x2C); - emit_byte(0xC0 | encode); -} - -void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) { - emit_byte(0xF3); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x5A); - emit_byte(0xC0 | encode); -} - -void Assembler::cvtdq2pd(XMMRegister dst, XMMRegister src) { - emit_byte(0xF3); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0xE6); - emit_byte(0xC0 | encode); -} - -void Assembler::cvtdq2ps(XMMRegister dst, XMMRegister src) { - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x5B); - emit_byte(0xC0 | encode); -} - -void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) { - emit_byte(0xF2); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x5A); - emit_byte(0xC0 | encode); -} - -void Assembler::punpcklbw(XMMRegister dst, XMMRegister src) { - emit_byte(0x66); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x60); - emit_byte(0xC0 | encode); -} - -// Implementation of MacroAssembler - -// On 32 bit it returns a vanilla displacement on 64 bit is a rip relative displacement -Address MacroAssembler::as_Address(AddressLiteral adr) { - assert(!adr.is_lval(), "must be rval"); - assert(reachable(adr), "must be"); - return Address((int)(intptr_t)(adr.target() - pc()), adr.target(), adr.reloc()); -} - -Address MacroAssembler::as_Address(ArrayAddress adr) { -#ifdef _LP64 - AddressLiteral base = adr.base(); - lea(rscratch1, base); - Address index = adr.index(); - assert(index._disp == 0, "must not have disp"); // maybe it can? - Address array(rscratch1, index._index, index._scale, index._disp); - return array; -#else - return Address::make_array(adr); -#endif // _LP64 - -} - -void MacroAssembler::fat_nop() { - // A 5 byte nop that is safe for patching (see patch_verified_entry) - // Recommened sequence from 'Software Optimization Guide for the AMD - // Hammer Processor' - emit_byte(0x66); - emit_byte(0x66); - emit_byte(0x90); - emit_byte(0x66); - emit_byte(0x90); -} +#endif // !LP64 static Assembler::Condition reverse[] = { Assembler::noOverflow /* overflow = 0x0 */ , @@ -3468,1515 +4199,613 @@ static Assembler::Condition reverse[] = { }; + +// Implementation of MacroAssembler + +// First all the versions that have distinct versions depending on 32/64 bit +// Unless the difference is trivial (1 line or so). + +#ifndef _LP64 + +// 32bit versions + +Address MacroAssembler::as_Address(AddressLiteral adr) { + return Address(adr.target(), adr.rspec()); +} + +Address MacroAssembler::as_Address(ArrayAddress adr) { + return Address::make_array(adr); +} + +int MacroAssembler::biased_locking_enter(Register lock_reg, + Register obj_reg, + Register swap_reg, + Register tmp_reg, + bool swap_reg_contains_mark, + Label& done, + Label* slow_case, + BiasedLockingCounters* counters) { + assert(UseBiasedLocking, "why call this otherwise?"); + assert(swap_reg == rax, "swap_reg must be rax, for cmpxchg"); + assert_different_registers(lock_reg, obj_reg, swap_reg); + + if (PrintBiasedLockingStatistics && counters == NULL) + counters = BiasedLocking::counters(); + + bool need_tmp_reg = false; + if (tmp_reg == noreg) { + need_tmp_reg = true; + tmp_reg = lock_reg; + } else { + assert_different_registers(lock_reg, obj_reg, swap_reg, tmp_reg); + } + assert(markOopDesc::age_shift == markOopDesc::lock_bits + markOopDesc::biased_lock_bits, "biased locking makes assumptions about bit layout"); + Address mark_addr (obj_reg, oopDesc::mark_offset_in_bytes()); + Address klass_addr (obj_reg, oopDesc::klass_offset_in_bytes()); + Address saved_mark_addr(lock_reg, 0); + + // Biased locking + // See whether the lock is currently biased toward our thread and + // whether the epoch is still valid + // Note that the runtime guarantees sufficient alignment of JavaThread + // pointers to allow age to be placed into low bits + // First check to see whether biasing is even enabled for this object + Label cas_label; + int null_check_offset = -1; + if (!swap_reg_contains_mark) { + null_check_offset = offset(); + movl(swap_reg, mark_addr); + } + if (need_tmp_reg) { + push(tmp_reg); + } + movl(tmp_reg, swap_reg); + andl(tmp_reg, markOopDesc::biased_lock_mask_in_place); + cmpl(tmp_reg, markOopDesc::biased_lock_pattern); + if (need_tmp_reg) { + pop(tmp_reg); + } + jcc(Assembler::notEqual, cas_label); + // The bias pattern is present in the object's header. Need to check + // whether the bias owner and the epoch are both still current. + // Note that because there is no current thread register on x86 we + // need to store off the mark word we read out of the object to + // avoid reloading it and needing to recheck invariants below. This + // store is unfortunate but it makes the overall code shorter and + // simpler. + movl(saved_mark_addr, swap_reg); + if (need_tmp_reg) { + push(tmp_reg); + } + get_thread(tmp_reg); + xorl(swap_reg, tmp_reg); + if (swap_reg_contains_mark) { + null_check_offset = offset(); + } + movl(tmp_reg, klass_addr); + xorl(swap_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + andl(swap_reg, ~((int) markOopDesc::age_mask_in_place)); + if (need_tmp_reg) { + pop(tmp_reg); + } + if (counters != NULL) { + cond_inc32(Assembler::zero, + ExternalAddress((address)counters->biased_lock_entry_count_addr())); + } + jcc(Assembler::equal, done); + + Label try_revoke_bias; + Label try_rebias; + + // At this point we know that the header has the bias pattern and + // that we are not the bias owner in the current epoch. We need to + // figure out more details about the state of the header in order to + // know what operations can be legally performed on the object's + // header. + + // If the low three bits in the xor result aren't clear, that means + // the prototype header is no longer biased and we have to revoke + // the bias on this object. + testl(swap_reg, markOopDesc::biased_lock_mask_in_place); + jcc(Assembler::notZero, try_revoke_bias); + + // Biasing is still enabled for this data type. See whether the + // epoch of the current bias is still valid, meaning that the epoch + // bits of the mark word are equal to the epoch bits of the + // prototype header. (Note that the prototype header's epoch bits + // only change at a safepoint.) If not, attempt to rebias the object + // toward the current thread. Note that we must be absolutely sure + // that the current epoch is invalid in order to do this because + // otherwise the manipulations it performs on the mark word are + // illegal. + testl(swap_reg, markOopDesc::epoch_mask_in_place); + jcc(Assembler::notZero, try_rebias); + + // The epoch of the current bias is still valid but we know nothing + // about the owner; it might be set or it might be clear. Try to + // acquire the bias of the object using an atomic operation. If this + // fails we will go in to the runtime to revoke the object's bias. + // Note that we first construct the presumed unbiased header so we + // don't accidentally blow away another thread's valid bias. + movl(swap_reg, saved_mark_addr); + andl(swap_reg, + markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place); + if (need_tmp_reg) { + push(tmp_reg); + } + get_thread(tmp_reg); + orl(tmp_reg, swap_reg); + if (os::is_MP()) { + lock(); + } + cmpxchgptr(tmp_reg, Address(obj_reg, 0)); + if (need_tmp_reg) { + pop(tmp_reg); + } + // If the biasing toward our thread failed, this means that + // another thread succeeded in biasing it toward itself and we + // need to revoke that bias. The revocation will occur in the + // interpreter runtime in the slow case. + if (counters != NULL) { + cond_inc32(Assembler::zero, + ExternalAddress((address)counters->anonymously_biased_lock_entry_count_addr())); + } + if (slow_case != NULL) { + jcc(Assembler::notZero, *slow_case); + } + jmp(done); + + bind(try_rebias); + // At this point we know the epoch has expired, meaning that the + // current "bias owner", if any, is actually invalid. Under these + // circumstances _only_, we are allowed to use the current header's + // value as the comparison value when doing the cas to acquire the + // bias in the current epoch. In other words, we allow transfer of + // the bias from one thread to another directly in this situation. + // + // FIXME: due to a lack of registers we currently blow away the age + // bits in this situation. Should attempt to preserve them. + if (need_tmp_reg) { + push(tmp_reg); + } + get_thread(tmp_reg); + movl(swap_reg, klass_addr); + orl(tmp_reg, Address(swap_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + movl(swap_reg, saved_mark_addr); + if (os::is_MP()) { + lock(); + } + cmpxchgptr(tmp_reg, Address(obj_reg, 0)); + if (need_tmp_reg) { + pop(tmp_reg); + } + // If the biasing toward our thread failed, then another thread + // succeeded in biasing it toward itself and we need to revoke that + // bias. The revocation will occur in the runtime in the slow case. + if (counters != NULL) { + cond_inc32(Assembler::zero, + ExternalAddress((address)counters->rebiased_lock_entry_count_addr())); + } + if (slow_case != NULL) { + jcc(Assembler::notZero, *slow_case); + } + jmp(done); + + bind(try_revoke_bias); + // The prototype mark in the klass doesn't have the bias bit set any + // more, indicating that objects of this data type are not supposed + // to be biased any more. We are going to try to reset the mark of + // this object to the prototype value and fall through to the + // CAS-based locking scheme. Note that if our CAS fails, it means + // that another thread raced us for the privilege of revoking the + // bias of this particular object, so it's okay to continue in the + // normal locking code. + // + // FIXME: due to a lack of registers we currently blow away the age + // bits in this situation. Should attempt to preserve them. + movl(swap_reg, saved_mark_addr); + if (need_tmp_reg) { + push(tmp_reg); + } + movl(tmp_reg, klass_addr); + movl(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + if (os::is_MP()) { + lock(); + } + cmpxchgptr(tmp_reg, Address(obj_reg, 0)); + if (need_tmp_reg) { + pop(tmp_reg); + } + // Fall through to the normal CAS-based lock, because no matter what + // the result of the above CAS, some thread must have succeeded in + // removing the bias bit from the object's header. + if (counters != NULL) { + cond_inc32(Assembler::zero, + ExternalAddress((address)counters->revoked_lock_entry_count_addr())); + } + + bind(cas_label); + + return null_check_offset; +} +void MacroAssembler::call_VM_leaf_base(address entry_point, + int number_of_arguments) { + call(RuntimeAddress(entry_point)); + increment(rsp, number_of_arguments * wordSize); +} + +void MacroAssembler::cmpoop(Address src1, jobject obj) { + cmp_literal32(src1, (int32_t)obj, oop_Relocation::spec_for_immediate()); +} + +void MacroAssembler::cmpoop(Register src1, jobject obj) { + cmp_literal32(src1, (int32_t)obj, oop_Relocation::spec_for_immediate()); +} + +void MacroAssembler::extend_sign(Register hi, Register lo) { + // According to Intel Doc. AP-526, "Integer Divide", p.18. + if (VM_Version::is_P6() && hi == rdx && lo == rax) { + cdql(); + } else { + movl(hi, lo); + sarl(hi, 31); + } +} + +void MacroAssembler::fat_nop() { + // A 5 byte nop that is safe for patching (see patch_verified_entry) + emit_byte(0x26); // es: + emit_byte(0x2e); // cs: + emit_byte(0x64); // fs: + emit_byte(0x65); // gs: + emit_byte(0x90); +} + +void MacroAssembler::jC2(Register tmp, Label& L) { + // set parity bit if FPU flag C2 is set (via rax) + save_rax(tmp); + fwait(); fnstsw_ax(); + sahf(); + restore_rax(tmp); + // branch + jcc(Assembler::parity, L); +} + +void MacroAssembler::jnC2(Register tmp, Label& L) { + // set parity bit if FPU flag C2 is set (via rax) + save_rax(tmp); + fwait(); fnstsw_ax(); + sahf(); + restore_rax(tmp); + // branch + jcc(Assembler::noParity, L); +} + // 32bit can do a case table jump in one instruction but we no longer allow the base // to be installed in the Address class void MacroAssembler::jump(ArrayAddress entry) { -#ifdef _LP64 - lea(rscratch1, entry.base()); - Address dispatch = entry.index(); - assert(dispatch._base == noreg, "must be"); - dispatch._base = rscratch1; - jmp(dispatch); -#else jmp(as_Address(entry)); -#endif // _LP64 } -void MacroAssembler::jump(AddressLiteral dst) { - if (reachable(dst)) { - jmp_literal(dst.target(), dst.rspec()); - } else { - lea(rscratch1, dst); - jmp(rscratch1); - } -} +// Note: y_lo will be destroyed +void MacroAssembler::lcmp2int(Register x_hi, Register x_lo, Register y_hi, Register y_lo) { + // Long compare for Java (semantics as described in JVM spec.) + Label high, low, done; -void MacroAssembler::jump_cc(Condition cc, AddressLiteral dst) { - if (reachable(dst)) { - InstructionMark im(this); - relocate(dst.reloc()); - const int short_size = 2; - const int long_size = 6; - int offs = (intptr_t)dst.target() - ((intptr_t)_code_pos); - if (dst.reloc() == relocInfo::none && is8bit(offs - short_size)) { - // 0111 tttn #8-bit disp - emit_byte(0x70 | cc); - emit_byte((offs - short_size) & 0xFF); - } else { - // 0000 1111 1000 tttn #32-bit disp - emit_byte(0x0F); - emit_byte(0x80 | cc); - emit_long(offs - long_size); - } - } else { -#ifdef ASSERT - warning("reversing conditional branch"); -#endif /* ASSERT */ - Label skip; - jccb(reverse[cc], skip); - lea(rscratch1, dst); - Assembler::jmp(rscratch1); - bind(skip); - } -} + cmpl(x_hi, y_hi); + jcc(Assembler::less, low); + jcc(Assembler::greater, high); + // x_hi is the return register + xorl(x_hi, x_hi); + cmpl(x_lo, y_lo); + jcc(Assembler::below, low); + jcc(Assembler::equal, done); -// Wouldn't need if AddressLiteral version had new name -void MacroAssembler::call(Label& L, relocInfo::relocType rtype) { - Assembler::call(L, rtype); -} + bind(high); + xorl(x_hi, x_hi); + increment(x_hi); + jmp(done); -// Wouldn't need if AddressLiteral version had new name -void MacroAssembler::call(Register entry) { - Assembler::call(entry); -} + bind(low); + xorl(x_hi, x_hi); + decrementl(x_hi); -void MacroAssembler::call(AddressLiteral entry) { - if (reachable(entry)) { - Assembler::call_literal(entry.target(), entry.rspec()); - } else { - lea(rscratch1, entry); - Assembler::call(rscratch1); - } -} - -void MacroAssembler::cmp8(AddressLiteral src1, int8_t src2) { - if (reachable(src1)) { - cmpb(as_Address(src1), src2); - } else { - lea(rscratch1, src1); - cmpb(Address(rscratch1, 0), src2); - } -} - -void MacroAssembler::cmp32(AddressLiteral src1, int32_t src2) { - if (reachable(src1)) { - cmpl(as_Address(src1), src2); - } else { - lea(rscratch1, src1); - cmpl(Address(rscratch1, 0), src2); - } -} - -void MacroAssembler::cmp32(Register src1, AddressLiteral src2) { - if (reachable(src2)) { - cmpl(src1, as_Address(src2)); - } else { - lea(rscratch1, src2); - cmpl(src1, Address(rscratch1, 0)); - } -} - -void MacroAssembler::cmpptr(Register src1, AddressLiteral src2) { -#ifdef _LP64 - if (src2.is_lval()) { - movptr(rscratch1, src2); - Assembler::cmpq(src1, rscratch1); - } else if (reachable(src2)) { - cmpq(src1, as_Address(src2)); - } else { - lea(rscratch1, src2); - Assembler::cmpq(src1, Address(rscratch1, 0)); - } -#else - if (src2.is_lval()) { - cmp_literal32(src1, (int32_t) src2.target(), src2.rspec()); - } else { - cmpl(src1, as_Address(src2)); - } -#endif // _LP64 -} - -void MacroAssembler::cmpptr(Address src1, AddressLiteral src2) { - assert(src2.is_lval(), "not a mem-mem compare"); -#ifdef _LP64 - // moves src2's literal address - movptr(rscratch1, src2); - Assembler::cmpq(src1, rscratch1); -#else - cmp_literal32(src1, (int32_t) src2.target(), src2.rspec()); -#endif // _LP64 -} - -void MacroAssembler::cmp64(Register src1, AddressLiteral src2) { - assert(!src2.is_lval(), "should use cmpptr"); - - if (reachable(src2)) { -#ifdef _LP64 - cmpq(src1, as_Address(src2)); -#else - ShouldNotReachHere(); -#endif // _LP64 - } else { - lea(rscratch1, src2); - Assembler::cmpq(src1, Address(rscratch1, 0)); - } -} - -void MacroAssembler::cmpxchgptr(Register reg, AddressLiteral adr) { - if (reachable(adr)) { -#ifdef _LP64 - cmpxchgq(reg, as_Address(adr)); -#else - cmpxchgl(reg, as_Address(adr)); -#endif // _LP64 - } else { - lea(rscratch1, adr); - cmpxchgq(reg, Address(rscratch1, 0)); - } -} - -void MacroAssembler::incrementl(AddressLiteral dst) { - if (reachable(dst)) { - incrementl(as_Address(dst)); - } else { - lea(rscratch1, dst); - incrementl(Address(rscratch1, 0)); - } -} - -void MacroAssembler::incrementl(ArrayAddress dst) { - incrementl(as_Address(dst)); -} - -void MacroAssembler::lea(Register dst, Address src) { -#ifdef _LP64 - leaq(dst, src); -#else - leal(dst, src); -#endif // _LP64 + bind(done); } void MacroAssembler::lea(Register dst, AddressLiteral src) { -#ifdef _LP64 - mov_literal64(dst, (intptr_t)src.target(), src.rspec()); -#else - mov_literal32(dst, (intptr_t)src.target(), src.rspec()); -#endif // _LP64 + mov_literal32(dst, (int32_t)src.target(), src.rspec()); } -void MacroAssembler::mov32(AddressLiteral dst, Register src) { - if (reachable(dst)) { - movl(as_Address(dst), src); - } else { - lea(rscratch1, dst); - movl(Address(rscratch1, 0), src); - } -} - -void MacroAssembler::mov32(Register dst, AddressLiteral src) { - if (reachable(src)) { - movl(dst, as_Address(src)); - } else { - lea(rscratch1, src); - movl(dst, Address(rscratch1, 0)); - } -} - -void MacroAssembler::movdbl(XMMRegister dst, AddressLiteral src) { - if (reachable(src)) { - if (UseXmmLoadAndClearUpper) { - movsd (dst, as_Address(src)); - } else { - movlpd(dst, as_Address(src)); - } - } else { - lea(rscratch1, src); - if (UseXmmLoadAndClearUpper) { - movsd (dst, Address(rscratch1, 0)); - } else { - movlpd(dst, Address(rscratch1, 0)); - } - } -} - -void MacroAssembler::movflt(XMMRegister dst, AddressLiteral src) { - if (reachable(src)) { - movss(dst, as_Address(src)); - } else { - lea(rscratch1, src); - movss(dst, Address(rscratch1, 0)); - } -} - -void MacroAssembler::movoop(Register dst, jobject obj) { - mov_literal64(dst, (intptr_t)obj, oop_Relocation::spec_for_immediate()); -} - -void MacroAssembler::movoop(Address dst, jobject obj) { - mov_literal64(rscratch1, (intptr_t)obj, oop_Relocation::spec_for_immediate()); - movq(dst, rscratch1); -} - -void MacroAssembler::movptr(Register dst, AddressLiteral src) { -#ifdef _LP64 - if (src.is_lval()) { - mov_literal64(dst, (intptr_t)src.target(), src.rspec()); - } else { - if (reachable(src)) { - movq(dst, as_Address(src)); - } else { - lea(rscratch1, src); - movq(dst, Address(rscratch1,0)); - } - } -#else - if (src.is_lval()) { - mov_literal32(dst, (intptr_t)src.target(), src.rspec()); - } else { - movl(dst, as_Address(src)); - } -#endif // LP64 -} - -void MacroAssembler::movptr(ArrayAddress dst, Register src) { -#ifdef _LP64 - movq(as_Address(dst), src); -#else - movl(as_Address(dst), src); -#endif // _LP64 -} - -void MacroAssembler::pushoop(jobject obj) { -#ifdef _LP64 - movoop(rscratch1, obj); - pushq(rscratch1); -#else - push_literal32((int32_t)obj, oop_Relocation::spec_for_immediate()); -#endif // _LP64 -} - -void MacroAssembler::pushptr(AddressLiteral src) { -#ifdef _LP64 - lea(rscratch1, src); - if (src.is_lval()) { - pushq(rscratch1); - } else { - pushq(Address(rscratch1, 0)); - } -#else - if (src.is_lval()) { - push_literal((int32_t)src.target(), src.rspec()); - else { - pushl(as_Address(src)); - } -#endif // _LP64 -} - -void MacroAssembler::ldmxcsr(AddressLiteral src) { - if (reachable(src)) { - Assembler::ldmxcsr(as_Address(src)); - } else { - lea(rscratch1, src); - Assembler::ldmxcsr(Address(rscratch1, 0)); - } -} - -void MacroAssembler::movlpd(XMMRegister dst, AddressLiteral src) { - if (reachable(src)) { - movlpd(dst, as_Address(src)); - } else { - lea(rscratch1, src); - movlpd(dst, Address(rscratch1, 0)); - } -} - -void MacroAssembler::movss(XMMRegister dst, AddressLiteral src) { - if (reachable(src)) { - movss(dst, as_Address(src)); - } else { - lea(rscratch1, src); - movss(dst, Address(rscratch1, 0)); - } -} -void MacroAssembler::xorpd(XMMRegister dst, AddressLiteral src) { - if (reachable(src)) { - xorpd(dst, as_Address(src)); - } else { - lea(rscratch1, src); - xorpd(dst, Address(rscratch1, 0)); - } -} - -void MacroAssembler::xorps(XMMRegister dst, AddressLiteral src) { - if (reachable(src)) { - xorps(dst, as_Address(src)); - } else { - lea(rscratch1, src); - xorps(dst, Address(rscratch1, 0)); - } -} - -void MacroAssembler::null_check(Register reg, int offset) { - if (needs_explicit_null_check(offset)) { - // provoke OS NULL exception if reg = NULL by - // accessing M[reg] w/o changing any (non-CC) registers - cmpq(rax, Address(reg, 0)); - // Note: should probably use testl(rax, Address(reg, 0)); - // may be shorter code (however, this version of - // testl needs to be implemented first) - } else { - // nothing to do, (later) access of M[reg + offset] - // will provoke OS NULL exception if reg = NULL - } -} - -int MacroAssembler::load_unsigned_byte(Register dst, Address src) { - int off = offset(); - movzbl(dst, src); - return off; -} - -int MacroAssembler::load_unsigned_word(Register dst, Address src) { - int off = offset(); - movzwl(dst, src); - return off; -} - -int MacroAssembler::load_signed_byte(Register dst, Address src) { - int off = offset(); - movsbl(dst, src); - return off; -} - -int MacroAssembler::load_signed_word(Register dst, Address src) { - int off = offset(); - movswl(dst, src); - return off; -} - -void MacroAssembler::incrementl(Register reg, int value) { - if (value == min_jint) { addl(reg, value); return; } - if (value < 0) { decrementl(reg, -value); return; } - if (value == 0) { ; return; } - if (value == 1 && UseIncDec) { incl(reg) ; return; } - /* else */ { addl(reg, value) ; return; } -} - -void MacroAssembler::decrementl(Register reg, int value) { - if (value == min_jint) { subl(reg, value); return; } - if (value < 0) { incrementl(reg, -value); return; } - if (value == 0) { ; return; } - if (value == 1 && UseIncDec) { decl(reg) ; return; } - /* else */ { subl(reg, value) ; return; } -} - -void MacroAssembler::incrementq(Register reg, int value) { - if (value == min_jint) { addq(reg, value); return; } - if (value < 0) { decrementq(reg, -value); return; } - if (value == 0) { ; return; } - if (value == 1 && UseIncDec) { incq(reg) ; return; } - /* else */ { addq(reg, value) ; return; } -} - -void MacroAssembler::decrementq(Register reg, int value) { - if (value == min_jint) { subq(reg, value); return; } - if (value < 0) { incrementq(reg, -value); return; } - if (value == 0) { ; return; } - if (value == 1 && UseIncDec) { decq(reg) ; return; } - /* else */ { subq(reg, value) ; return; } -} - -void MacroAssembler::incrementl(Address dst, int value) { - if (value == min_jint) { addl(dst, value); return; } - if (value < 0) { decrementl(dst, -value); return; } - if (value == 0) { ; return; } - if (value == 1 && UseIncDec) { incl(dst) ; return; } - /* else */ { addl(dst, value) ; return; } -} - -void MacroAssembler::decrementl(Address dst, int value) { - if (value == min_jint) { subl(dst, value); return; } - if (value < 0) { incrementl(dst, -value); return; } - if (value == 0) { ; return; } - if (value == 1 && UseIncDec) { decl(dst) ; return; } - /* else */ { subl(dst, value) ; return; } -} - -void MacroAssembler::incrementq(Address dst, int value) { - if (value == min_jint) { addq(dst, value); return; } - if (value < 0) { decrementq(dst, -value); return; } - if (value == 0) { ; return; } - if (value == 1 && UseIncDec) { incq(dst) ; return; } - /* else */ { addq(dst, value) ; return; } -} - -void MacroAssembler::decrementq(Address dst, int value) { - if (value == min_jint) { subq(dst, value); return; } - if (value < 0) { incrementq(dst, -value); return; } - if (value == 0) { ; return; } - if (value == 1 && UseIncDec) { decq(dst) ; return; } - /* else */ { subq(dst, value) ; return; } -} - -void MacroAssembler::align(int modulus) { - if (offset() % modulus != 0) { - nop(modulus - (offset() % modulus)); - } -} - -void MacroAssembler::enter() { - pushq(rbp); - movq(rbp, rsp); +void MacroAssembler::lea(Address dst, AddressLiteral adr) { + // leal(dst, as_Address(adr)); + // see note in movl as to why we must use a move + mov_literal32(dst, (int32_t) adr.target(), adr.rspec()); } void MacroAssembler::leave() { - emit_byte(0xC9); // LEAVE + mov(rsp, rbp); + pop(rbp); } -// C++ bool manipulation - -void MacroAssembler::movbool(Register dst, Address src) { - if(sizeof(bool) == 1) - movb(dst, src); - else if(sizeof(bool) == 2) - movw(dst, src); - else if(sizeof(bool) == 4) - movl(dst, src); - else { - // unsupported - ShouldNotReachHere(); - } +void MacroAssembler::lmul(int x_rsp_offset, int y_rsp_offset) { + // Multiplication of two Java long values stored on the stack + // as illustrated below. Result is in rdx:rax. + // + // rsp ---> [ ?? ] \ \ + // .... | y_rsp_offset | + // [ y_lo ] / (in bytes) | x_rsp_offset + // [ y_hi ] | (in bytes) + // .... | + // [ x_lo ] / + // [ x_hi ] + // .... + // + // Basic idea: lo(result) = lo(x_lo * y_lo) + // hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) + lo(x_lo * y_hi) + Address x_hi(rsp, x_rsp_offset + wordSize); Address x_lo(rsp, x_rsp_offset); + Address y_hi(rsp, y_rsp_offset + wordSize); Address y_lo(rsp, y_rsp_offset); + Label quick; + // load x_hi, y_hi and check if quick + // multiplication is possible + movl(rbx, x_hi); + movl(rcx, y_hi); + movl(rax, rbx); + orl(rbx, rcx); // rbx, = 0 <=> x_hi = 0 and y_hi = 0 + jcc(Assembler::zero, quick); // if rbx, = 0 do quick multiply + // do full multiplication + // 1st step + mull(y_lo); // x_hi * y_lo + movl(rbx, rax); // save lo(x_hi * y_lo) in rbx, + // 2nd step + movl(rax, x_lo); + mull(rcx); // x_lo * y_hi + addl(rbx, rax); // add lo(x_lo * y_hi) to rbx, + // 3rd step + bind(quick); // note: rbx, = 0 if quick multiply! + movl(rax, x_lo); + mull(y_lo); // x_lo * y_lo + addl(rdx, rbx); // correct hi(x_lo * y_lo) } -void MacroAssembler::movbool(Address dst, bool boolconst) { - if(sizeof(bool) == 1) - movb(dst, (int) boolconst); - else if(sizeof(bool) == 2) - movw(dst, (int) boolconst); - else if(sizeof(bool) == 4) - movl(dst, (int) boolconst); - else { - // unsupported - ShouldNotReachHere(); - } +void MacroAssembler::lneg(Register hi, Register lo) { + negl(lo); + adcl(hi, 0); + negl(hi); } -void MacroAssembler::movbool(Address dst, Register src) { - if(sizeof(bool) == 1) - movb(dst, src); - else if(sizeof(bool) == 2) - movw(dst, src); - else if(sizeof(bool) == 4) - movl(dst, src); - else { - // unsupported - ShouldNotReachHere(); - } -} - -void MacroAssembler::testbool(Register dst) { - if(sizeof(bool) == 1) - testb(dst, (int) 0xff); - else if(sizeof(bool) == 2) { - // need testw impl - ShouldNotReachHere(); - } else if(sizeof(bool) == 4) - testl(dst, dst); - else { - // unsupported - ShouldNotReachHere(); - } -} - -void MacroAssembler::set_last_Java_frame(Register last_java_sp, - Register last_java_fp, - address last_java_pc) { - // determine last_java_sp register - if (!last_java_sp->is_valid()) { - last_java_sp = rsp; - } - - // last_java_fp is optional - if (last_java_fp->is_valid()) { - movq(Address(r15_thread, JavaThread::last_Java_fp_offset()), - last_java_fp); - } - - // last_java_pc is optional - if (last_java_pc != NULL) { - Address java_pc(r15_thread, - JavaThread::frame_anchor_offset() + JavaFrameAnchor::last_Java_pc_offset()); - lea(rscratch1, InternalAddress(last_java_pc)); - movq(java_pc, rscratch1); - } - - movq(Address(r15_thread, JavaThread::last_Java_sp_offset()), last_java_sp); -} - -void MacroAssembler::reset_last_Java_frame(bool clear_fp, - bool clear_pc) { - // we must set sp to zero to clear frame - movptr(Address(r15_thread, JavaThread::last_Java_sp_offset()), NULL_WORD); - // must clear fp, so that compiled frames are not confused; it is - // possible that we need it only for debugging - if (clear_fp) { - movptr(Address(r15_thread, JavaThread::last_Java_fp_offset()), NULL_WORD); - } - - if (clear_pc) { - movptr(Address(r15_thread, JavaThread::last_Java_pc_offset()), NULL_WORD); - } +void MacroAssembler::lshl(Register hi, Register lo) { + // Java shift left long support (semantics as described in JVM spec., p.305) + // (basic idea for shift counts s >= n: x << s == (x << n) << (s - n)) + // shift value is in rcx ! + assert(hi != rcx, "must not use rcx"); + assert(lo != rcx, "must not use rcx"); + const Register s = rcx; // shift count + const int n = BitsPerWord; + Label L; + andl(s, 0x3f); // s := s & 0x3f (s < 0x40) + cmpl(s, n); // if (s < n) + jcc(Assembler::less, L); // else (s >= n) + movl(hi, lo); // x := x << n + xorl(lo, lo); + // Note: subl(s, n) is not needed since the Intel shift instructions work rcx mod n! + bind(L); // s (mod n) < n + shldl(hi, lo); // x := x << s + shll(lo); } -// Implementation of call_VM versions - -void MacroAssembler::call_VM_leaf_base(address entry_point, int num_args) { - Label L, E; - -#ifdef _WIN64 - // Windows always allocates space for it's register args - assert(num_args <= 4, "only register arguments supported"); - subq(rsp, frame::arg_reg_save_area_bytes); -#endif - - // Align stack if necessary - testl(rsp, 15); - jcc(Assembler::zero, L); - - subq(rsp, 8); - { - call(RuntimeAddress(entry_point)); - } - addq(rsp, 8); - jmp(E); - - bind(L); - { - call(RuntimeAddress(entry_point)); - } - - bind(E); - -#ifdef _WIN64 - // restore stack pointer - addq(rsp, frame::arg_reg_save_area_bytes); -#endif - +void MacroAssembler::lshr(Register hi, Register lo, bool sign_extension) { + // Java shift right long support (semantics as described in JVM spec., p.306 & p.310) + // (basic idea for shift counts s >= n: x >> s == (x >> n) >> (s - n)) + assert(hi != rcx, "must not use rcx"); + assert(lo != rcx, "must not use rcx"); + const Register s = rcx; // shift count + const int n = BitsPerWord; + Label L; + andl(s, 0x3f); // s := s & 0x3f (s < 0x40) + cmpl(s, n); // if (s < n) + jcc(Assembler::less, L); // else (s >= n) + movl(lo, hi); // x := x >> n + if (sign_extension) sarl(hi, 31); + else xorl(hi, hi); + // Note: subl(s, n) is not needed since the Intel shift instructions work rcx mod n! + bind(L); // s (mod n) < n + shrdl(lo, hi); // x := x >> s + if (sign_extension) sarl(hi); + else shrl(hi); } - -void MacroAssembler::call_VM_base(Register oop_result, - Register java_thread, - Register last_java_sp, - address entry_point, - int num_args, - bool check_exceptions) { - // determine last_java_sp register - if (!last_java_sp->is_valid()) { - last_java_sp = rsp; - } - - // debugging support - assert(num_args >= 0, "cannot have negative number of arguments"); - assert(r15_thread != oop_result, - "cannot use the same register for java_thread & oop_result"); - assert(r15_thread != last_java_sp, - "cannot use the same register for java_thread & last_java_sp"); - - // set last Java frame before call - - // This sets last_Java_fp which is only needed from interpreted frames - // and should really be done only from the interp_masm version before - // calling the underlying call_VM. That doesn't happen yet so we set - // last_Java_fp here even though some callers don't need it and - // also clear it below. - set_last_Java_frame(last_java_sp, rbp, NULL); - - { - Label L, E; - - // Align stack if necessary -#ifdef _WIN64 - assert(num_args <= 4, "only register arguments supported"); - // Windows always allocates space for it's register args - subq(rsp, frame::arg_reg_save_area_bytes); -#endif - testl(rsp, 15); - jcc(Assembler::zero, L); - - subq(rsp, 8); - { - call(RuntimeAddress(entry_point)); - } - addq(rsp, 8); - jmp(E); - - - bind(L); - { - call(RuntimeAddress(entry_point)); - } - - bind(E); - -#ifdef _WIN64 - // restore stack pointer - addq(rsp, frame::arg_reg_save_area_bytes); -#endif - } - -#ifdef ASSERT - pushq(rax); - { - Label L; - get_thread(rax); - cmpq(r15_thread, rax); - jcc(Assembler::equal, L); - stop("MacroAssembler::call_VM_base: register not callee saved?"); - bind(L); - } - popq(rax); -#endif - - // reset last Java frame - // This really shouldn't have to clear fp set note above at the - // call to set_last_Java_frame - reset_last_Java_frame(true, false); - - check_and_handle_popframe(noreg); - check_and_handle_earlyret(noreg); - - if (check_exceptions) { - cmpq(Address(r15_thread, Thread::pending_exception_offset()), (int) NULL); - // This used to conditionally jump to forward_exception however it is - // possible if we relocate that the branch will not reach. So we must jump - // around so we can always reach - Label ok; - jcc(Assembler::equal, ok); - jump(RuntimeAddress(StubRoutines::forward_exception_entry())); - bind(ok); - } - - // get oop result if there is one and reset the value in the thread - if (oop_result->is_valid()) { - movq(oop_result, Address(r15_thread, JavaThread::vm_result_offset())); - movptr(Address(r15_thread, JavaThread::vm_result_offset()), NULL_WORD); - verify_oop(oop_result, "broken oop in call_VM_base"); - } +void MacroAssembler::movoop(Register dst, jobject obj) { + mov_literal32(dst, (int32_t)obj, oop_Relocation::spec_for_immediate()); } -void MacroAssembler::check_and_handle_popframe(Register java_thread) {} -void MacroAssembler::check_and_handle_earlyret(Register java_thread) {} - -void MacroAssembler::call_VM_helper(Register oop_result, - address entry_point, - int num_args, - bool check_exceptions) { - // Java thread becomes first argument of C function - movq(c_rarg0, r15_thread); - - // We've pushed one address, correct last_Java_sp - leaq(rax, Address(rsp, wordSize)); - - call_VM_base(oop_result, noreg, rax, entry_point, num_args, - check_exceptions); +void MacroAssembler::movoop(Address dst, jobject obj) { + mov_literal32(dst, (int32_t)obj, oop_Relocation::spec_for_immediate()); } - -void MacroAssembler::call_VM(Register oop_result, - address entry_point, - bool check_exceptions) { - Label C, E; - Assembler::call(C, relocInfo::none); - jmp(E); - - bind(C); - call_VM_helper(oop_result, entry_point, 0, check_exceptions); - ret(0); - - bind(E); -} - - -void MacroAssembler::call_VM(Register oop_result, - address entry_point, - Register arg_1, - bool check_exceptions) { - assert(rax != arg_1, "smashed argument"); - assert(c_rarg0 != arg_1, "smashed argument"); - - Label C, E; - Assembler::call(C, relocInfo::none); - jmp(E); - - bind(C); - // c_rarg0 is reserved for thread - if (c_rarg1 != arg_1) { - movq(c_rarg1, arg_1); - } - call_VM_helper(oop_result, entry_point, 1, check_exceptions); - ret(0); - - bind(E); -} - -void MacroAssembler::call_VM(Register oop_result, - address entry_point, - Register arg_1, - Register arg_2, - bool check_exceptions) { - assert(rax != arg_1, "smashed argument"); - assert(rax != arg_2, "smashed argument"); - assert(c_rarg0 != arg_1, "smashed argument"); - assert(c_rarg0 != arg_2, "smashed argument"); - assert(c_rarg1 != arg_2, "smashed argument"); - assert(c_rarg2 != arg_1, "smashed argument"); - - Label C, E; - Assembler::call(C, relocInfo::none); - jmp(E); - - bind(C); - // c_rarg0 is reserved for thread - if (c_rarg1 != arg_1) { - movq(c_rarg1, arg_1); - } - if (c_rarg2 != arg_2) { - movq(c_rarg2, arg_2); - } - call_VM_helper(oop_result, entry_point, 2, check_exceptions); - ret(0); - - bind(E); -} - - -void MacroAssembler::call_VM(Register oop_result, - address entry_point, - Register arg_1, - Register arg_2, - Register arg_3, - bool check_exceptions) { - assert(rax != arg_1, "smashed argument"); - assert(rax != arg_2, "smashed argument"); - assert(rax != arg_3, "smashed argument"); - assert(c_rarg0 != arg_1, "smashed argument"); - assert(c_rarg0 != arg_2, "smashed argument"); - assert(c_rarg0 != arg_3, "smashed argument"); - assert(c_rarg1 != arg_2, "smashed argument"); - assert(c_rarg1 != arg_3, "smashed argument"); - assert(c_rarg2 != arg_1, "smashed argument"); - assert(c_rarg2 != arg_3, "smashed argument"); - assert(c_rarg3 != arg_1, "smashed argument"); - assert(c_rarg3 != arg_2, "smashed argument"); - - Label C, E; - Assembler::call(C, relocInfo::none); - jmp(E); - - bind(C); - // c_rarg0 is reserved for thread - if (c_rarg1 != arg_1) { - movq(c_rarg1, arg_1); - } - if (c_rarg2 != arg_2) { - movq(c_rarg2, arg_2); - } - if (c_rarg3 != arg_3) { - movq(c_rarg3, arg_3); - } - call_VM_helper(oop_result, entry_point, 3, check_exceptions); - ret(0); - - bind(E); -} - -void MacroAssembler::call_VM(Register oop_result, - Register last_java_sp, - address entry_point, - int num_args, - bool check_exceptions) { - call_VM_base(oop_result, noreg, last_java_sp, entry_point, num_args, - check_exceptions); -} - -void MacroAssembler::call_VM(Register oop_result, - Register last_java_sp, - address entry_point, - Register arg_1, - bool check_exceptions) { - assert(c_rarg0 != arg_1, "smashed argument"); - assert(c_rarg1 != last_java_sp, "smashed argument"); - // c_rarg0 is reserved for thread - if (c_rarg1 != arg_1) { - movq(c_rarg1, arg_1); - } - call_VM(oop_result, last_java_sp, entry_point, 1, check_exceptions); -} - -void MacroAssembler::call_VM(Register oop_result, - Register last_java_sp, - address entry_point, - Register arg_1, - Register arg_2, - bool check_exceptions) { - assert(c_rarg0 != arg_1, "smashed argument"); - assert(c_rarg0 != arg_2, "smashed argument"); - assert(c_rarg1 != arg_2, "smashed argument"); - assert(c_rarg1 != last_java_sp, "smashed argument"); - assert(c_rarg2 != arg_1, "smashed argument"); - assert(c_rarg2 != last_java_sp, "smashed argument"); - // c_rarg0 is reserved for thread - if (c_rarg1 != arg_1) { - movq(c_rarg1, arg_1); - } - if (c_rarg2 != arg_2) { - movq(c_rarg2, arg_2); - } - call_VM(oop_result, last_java_sp, entry_point, 2, check_exceptions); -} - - -void MacroAssembler::call_VM(Register oop_result, - Register last_java_sp, - address entry_point, - Register arg_1, - Register arg_2, - Register arg_3, - bool check_exceptions) { - assert(c_rarg0 != arg_1, "smashed argument"); - assert(c_rarg0 != arg_2, "smashed argument"); - assert(c_rarg0 != arg_3, "smashed argument"); - assert(c_rarg1 != arg_2, "smashed argument"); - assert(c_rarg1 != arg_3, "smashed argument"); - assert(c_rarg1 != last_java_sp, "smashed argument"); - assert(c_rarg2 != arg_1, "smashed argument"); - assert(c_rarg2 != arg_3, "smashed argument"); - assert(c_rarg2 != last_java_sp, "smashed argument"); - assert(c_rarg3 != arg_1, "smashed argument"); - assert(c_rarg3 != arg_2, "smashed argument"); - assert(c_rarg3 != last_java_sp, "smashed argument"); - // c_rarg0 is reserved for thread - if (c_rarg1 != arg_1) { - movq(c_rarg1, arg_1); - } - if (c_rarg2 != arg_2) { - movq(c_rarg2, arg_2); - } - if (c_rarg3 != arg_3) { - movq(c_rarg2, arg_3); - } - call_VM(oop_result, last_java_sp, entry_point, 3, check_exceptions); -} - -void MacroAssembler::call_VM_leaf(address entry_point, int num_args) { - call_VM_leaf_base(entry_point, num_args); -} - -void MacroAssembler::call_VM_leaf(address entry_point, Register arg_1) { - if (c_rarg0 != arg_1) { - movq(c_rarg0, arg_1); - } - call_VM_leaf(entry_point, 1); -} - -void MacroAssembler::call_VM_leaf(address entry_point, - Register arg_1, - Register arg_2) { - assert(c_rarg0 != arg_2, "smashed argument"); - assert(c_rarg1 != arg_1, "smashed argument"); - if (c_rarg0 != arg_1) { - movq(c_rarg0, arg_1); - } - if (c_rarg1 != arg_2) { - movq(c_rarg1, arg_2); - } - call_VM_leaf(entry_point, 2); -} - -void MacroAssembler::call_VM_leaf(address entry_point, - Register arg_1, - Register arg_2, - Register arg_3) { - assert(c_rarg0 != arg_2, "smashed argument"); - assert(c_rarg0 != arg_3, "smashed argument"); - assert(c_rarg1 != arg_1, "smashed argument"); - assert(c_rarg1 != arg_3, "smashed argument"); - assert(c_rarg2 != arg_1, "smashed argument"); - assert(c_rarg2 != arg_2, "smashed argument"); - if (c_rarg0 != arg_1) { - movq(c_rarg0, arg_1); - } - if (c_rarg1 != arg_2) { - movq(c_rarg1, arg_2); - } - if (c_rarg2 != arg_3) { - movq(c_rarg2, arg_3); - } - call_VM_leaf(entry_point, 3); -} - - -// Calls to C land -// -// When entering C land, the rbp & rsp of the last Java frame have to -// be recorded in the (thread-local) JavaThread object. When leaving C -// land, the last Java fp has to be reset to 0. This is required to -// allow proper stack traversal. -void MacroAssembler::store_check(Register obj) { - // Does a store check for the oop in register obj. The content of - // register obj is destroyed afterwards. - store_check_part_1(obj); - store_check_part_2(obj); -} - -void MacroAssembler::store_check(Register obj, Address dst) { - store_check(obj); -} - -// split the store check operation so that other instructions can be -// scheduled inbetween -void MacroAssembler::store_check_part_1(Register obj) { - BarrierSet* bs = Universe::heap()->barrier_set(); - assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind"); - shrq(obj, CardTableModRefBS::card_shift); -} - -void MacroAssembler::store_check_part_2(Register obj) { - BarrierSet* bs = Universe::heap()->barrier_set(); - assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind"); - CardTableModRefBS* ct = (CardTableModRefBS*)bs; - assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); - - // The calculation for byte_map_base is as follows: - // byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift); - // So this essentially converts an address to a displacement and - // it will never need to be relocated. On 64bit however the value may be too - // large for a 32bit displacement - - intptr_t disp = (intptr_t) ct->byte_map_base; - if (is_simm32(disp)) { - Address cardtable(noreg, obj, Address::times_1, disp); - movb(cardtable, 0); +void MacroAssembler::movptr(Register dst, AddressLiteral src) { + if (src.is_lval()) { + mov_literal32(dst, (intptr_t)src.target(), src.rspec()); } else { - // By doing it as an ExternalAddress disp could be converted to a rip-relative - // displacement and done in a single instruction given favorable mapping and - // a smarter version of as_Address. Worst case it is two instructions which - // is no worse off then loading disp into a register and doing as a simple - // Address() as above. - // We can't do as ExternalAddress as the only style since if disp == 0 we'll - // assert since NULL isn't acceptable in a reloci (see 6644928). In any case - // in some cases we'll get a single instruction version. - - ExternalAddress cardtable((address)disp); - Address index(noreg, obj, Address::times_1); - movb(as_Address(ArrayAddress(cardtable, index)), 0); + movl(dst, as_Address(src)); } - } -void MacroAssembler::c2bool(Register x) { - // implements x == 0 ? 0 : 1 - // note: must only look at least-significant byte of x - // since C-style booleans are stored in one byte - // only! (was bug) - andl(x, 0xFF); - setb(Assembler::notZero, x); +void MacroAssembler::movptr(ArrayAddress dst, Register src) { + movl(as_Address(dst), src); } -int MacroAssembler::corrected_idivl(Register reg) { - // Full implementation of Java idiv and irem; checks for special - // case as described in JVM spec., p.243 & p.271. The function - // returns the (pc) offset of the idivl instruction - may be needed - // for implicit exceptions. - // - // normal case special case - // - // input : eax: dividend min_int - // reg: divisor (may not be eax/edx) -1 - // - // output: eax: quotient (= eax idiv reg) min_int - // edx: remainder (= eax irem reg) 0 - assert(reg != rax && reg != rdx, "reg cannot be rax or rdx register"); - const int min_int = 0x80000000; - Label normal_case, special_case; - - // check for special case - cmpl(rax, min_int); - jcc(Assembler::notEqual, normal_case); - xorl(rdx, rdx); // prepare edx for possible special case (where - // remainder = 0) - cmpl(reg, -1); - jcc(Assembler::equal, special_case); - - // handle normal case - bind(normal_case); - cdql(); - int idivl_offset = offset(); - idivl(reg); - - // normal and special case exit - bind(special_case); - - return idivl_offset; +void MacroAssembler::movptr(Register dst, ArrayAddress src) { + movl(dst, as_Address(src)); } -int MacroAssembler::corrected_idivq(Register reg) { - // Full implementation of Java ldiv and lrem; checks for special - // case as described in JVM spec., p.243 & p.271. The function - // returns the (pc) offset of the idivl instruction - may be needed - // for implicit exceptions. - // - // normal case special case - // - // input : rax: dividend min_long - // reg: divisor (may not be eax/edx) -1 - // - // output: rax: quotient (= rax idiv reg) min_long - // rdx: remainder (= rax irem reg) 0 - assert(reg != rax && reg != rdx, "reg cannot be rax or rdx register"); - static const int64_t min_long = 0x8000000000000000; - Label normal_case, special_case; - - // check for special case - cmp64(rax, ExternalAddress((address) &min_long)); - jcc(Assembler::notEqual, normal_case); - xorl(rdx, rdx); // prepare rdx for possible special case (where - // remainder = 0) - cmpq(reg, -1); - jcc(Assembler::equal, special_case); - - // handle normal case - bind(normal_case); - cdqq(); - int idivq_offset = offset(); - idivq(reg); - - // normal and special case exit - bind(special_case); - - return idivq_offset; +// src should NEVER be a real pointer. Use AddressLiteral for true pointers +void MacroAssembler::movptr(Address dst, intptr_t src) { + movl(dst, src); } -void MacroAssembler::push_IU_state() { - pushfq(); // Push flags first because pushaq kills them - subq(rsp, 8); // Make sure rsp stays 16-byte aligned - pushaq(); + +void MacroAssembler::movsd(XMMRegister dst, AddressLiteral src) { + movsd(dst, as_Address(src)); } -void MacroAssembler::pop_IU_state() { - popaq(); - addq(rsp, 8); - popfq(); +void MacroAssembler::pop_callee_saved_registers() { + pop(rcx); + pop(rdx); + pop(rdi); + pop(rsi); } -void MacroAssembler::push_FPU_state() { - subq(rsp, FPUStateSizeInWords * wordSize); - fxsave(Address(rsp, 0)); +void MacroAssembler::pop_fTOS() { + fld_d(Address(rsp, 0)); + addl(rsp, 2 * wordSize); } -void MacroAssembler::pop_FPU_state() { - fxrstor(Address(rsp, 0)); - addq(rsp, FPUStateSizeInWords * wordSize); +void MacroAssembler::push_callee_saved_registers() { + push(rsi); + push(rdi); + push(rdx); + push(rcx); } -// Save Integer and Float state -// Warning: Stack must be 16 byte aligned -void MacroAssembler::push_CPU_state() { - push_IU_state(); - push_FPU_state(); +void MacroAssembler::push_fTOS() { + subl(rsp, 2 * wordSize); + fstp_d(Address(rsp, 0)); } -void MacroAssembler::pop_CPU_state() { - pop_FPU_state(); - pop_IU_state(); + +void MacroAssembler::pushoop(jobject obj) { + push_literal32((int32_t)obj, oop_Relocation::spec_for_immediate()); } -void MacroAssembler::sign_extend_short(Register reg) { - movswl(reg, reg); -} -void MacroAssembler::sign_extend_byte(Register reg) { - movsbl(reg, reg); -} - -void MacroAssembler::division_with_shift(Register reg, int shift_value) { - assert (shift_value > 0, "illegal shift value"); - Label _is_positive; - testl (reg, reg); - jcc (Assembler::positive, _is_positive); - int offset = (1 << shift_value) - 1 ; - - if (offset == 1) { - incrementl(reg); +void MacroAssembler::pushptr(AddressLiteral src) { + if (src.is_lval()) { + push_literal32((int32_t)src.target(), src.rspec()); } else { - addl(reg, offset); + pushl(as_Address(src)); } - - bind (_is_positive); - sarl(reg, shift_value); } -void MacroAssembler::round_to_l(Register reg, int modulus) { - addl(reg, modulus - 1); - andl(reg, -modulus); +void MacroAssembler::set_word_if_not_zero(Register dst) { + xorl(dst, dst); + set_byte_if_not_zero(dst); } -void MacroAssembler::round_to_q(Register reg, int modulus) { - addq(reg, modulus - 1); - andq(reg, -modulus); +static void pass_arg0(MacroAssembler* masm, Register arg) { + masm->push(arg); } -void MacroAssembler::verify_oop(Register reg, const char* s) { - if (!VerifyOops) { - return; - } - - // Pass register number to verify_oop_subroutine - char* b = new char[strlen(s) + 50]; - sprintf(b, "verify_oop: %s: %s", reg->name(), s); - - pushq(rax); // save rax, restored by receiver - - // pass args on stack, only touch rax - pushq(reg); - // avoid using pushptr, as it modifies scratch registers - // and our contract is not to modify anything - ExternalAddress buffer((address)b); - movptr(rax, buffer.addr()); - pushq(rax); - - // call indirectly to solve generation ordering problem - movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address())); - call(rax); // no alignment requirement - // everything popped by receiver +static void pass_arg1(MacroAssembler* masm, Register arg) { + masm->push(arg); } -void MacroAssembler::verify_oop_addr(Address addr, const char* s) { - if (!VerifyOops) return; - // Pass register number to verify_oop_subroutine - char* b = new char[strlen(s) + 50]; - sprintf(b, "verify_oop_addr: %s", s); - pushq(rax); // save rax - movq(addr, rax); - pushq(rax); // pass register argument - - - // avoid using pushptr, as it modifies scratch registers - // and our contract is not to modify anything - ExternalAddress buffer((address)b); - movptr(rax, buffer.addr()); - pushq(rax); - - // call indirectly to solve generation ordering problem - movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address())); - call(rax); // no alignment requirement - // everything popped by receiver +static void pass_arg2(MacroAssembler* masm, Register arg) { + masm->push(arg); } - -void MacroAssembler::stop(const char* msg) { - address rip = pc(); - pushaq(); // get regs on stack - lea(c_rarg0, ExternalAddress((address) msg)); - lea(c_rarg1, InternalAddress(rip)); - movq(c_rarg2, rsp); // pass pointer to regs array - andq(rsp, -16); // align stack as required by ABI - call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug))); - hlt(); -} - -void MacroAssembler::warn(const char* msg) { - pushq(r12); - movq(r12, rsp); - andq(rsp, -16); // align stack as required by push_CPU_state and call - - push_CPU_state(); // keeps alignment at 16 bytes - lea(c_rarg0, ExternalAddress((address) msg)); - call_VM_leaf(CAST_FROM_FN_PTR(address, warning), c_rarg0); - pop_CPU_state(); - - movq(rsp, r12); - popq(r12); +static void pass_arg3(MacroAssembler* masm, Register arg) { + masm->push(arg); } #ifndef PRODUCT extern "C" void findpc(intptr_t x); #endif -void MacroAssembler::debug(char* msg, int64_t pc, int64_t regs[]) { +void MacroAssembler::debug32(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip, char* msg) { // In order to get locks to work, we need to fake a in_VM state - if (ShowMessageBoxOnError ) { + JavaThread* thread = JavaThread::current(); + JavaThreadState saved_state = thread->thread_state(); + thread->set_thread_state(_thread_in_vm); + if (ShowMessageBoxOnError) { JavaThread* thread = JavaThread::current(); JavaThreadState saved_state = thread->thread_state(); thread->set_thread_state(_thread_in_vm); -#ifndef PRODUCT if (CountBytecodes || TraceBytecodes || StopInterpreterAt) { ttyLocker ttyl; BytecodeCounter::print(); } -#endif // To see where a verify_oop failed, get $ebx+40/X for this frame. - // XXX correct this offset for amd64 // This is the value of eip which points to where verify_oop will return. if (os::message_box(msg, "Execution stopped, print registers?")) { ttyLocker ttyl; - tty->print_cr("rip = 0x%016lx", pc); + tty->print_cr("eip = 0x%08x", eip); #ifndef PRODUCT tty->cr(); - findpc(pc); + findpc(eip); tty->cr(); #endif - tty->print_cr("rax = 0x%016lx", regs[15]); - tty->print_cr("rbx = 0x%016lx", regs[12]); - tty->print_cr("rcx = 0x%016lx", regs[14]); - tty->print_cr("rdx = 0x%016lx", regs[13]); - tty->print_cr("rdi = 0x%016lx", regs[8]); - tty->print_cr("rsi = 0x%016lx", regs[9]); - tty->print_cr("rbp = 0x%016lx", regs[10]); - tty->print_cr("rsp = 0x%016lx", regs[11]); - tty->print_cr("r8 = 0x%016lx", regs[7]); - tty->print_cr("r9 = 0x%016lx", regs[6]); - tty->print_cr("r10 = 0x%016lx", regs[5]); - tty->print_cr("r11 = 0x%016lx", regs[4]); - tty->print_cr("r12 = 0x%016lx", regs[3]); - tty->print_cr("r13 = 0x%016lx", regs[2]); - tty->print_cr("r14 = 0x%016lx", regs[1]); - tty->print_cr("r15 = 0x%016lx", regs[0]); + tty->print_cr("rax, = 0x%08x", rax); + tty->print_cr("rbx, = 0x%08x", rbx); + tty->print_cr("rcx = 0x%08x", rcx); + tty->print_cr("rdx = 0x%08x", rdx); + tty->print_cr("rdi = 0x%08x", rdi); + tty->print_cr("rsi = 0x%08x", rsi); + tty->print_cr("rbp, = 0x%08x", rbp); + tty->print_cr("rsp = 0x%08x", rsp); BREAKPOINT; } - ThreadStateTransition::transition(thread, _thread_in_vm, saved_state); } else { ttyLocker ttyl; - ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n", - msg); + ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n", msg); + assert(false, "DEBUG MESSAGE"); } + ThreadStateTransition::transition(thread, _thread_in_vm, saved_state); } -void MacroAssembler::os_breakpoint() { - // instead of directly emitting a breakpoint, call os:breakpoint for - // better debugability - // This shouldn't need alignment, it's an empty function - call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint))); +void MacroAssembler::stop(const char* msg) { + ExternalAddress message((address)msg); + // push address of message + pushptr(message.addr()); + { Label L; call(L, relocInfo::none); bind(L); } // push eip + pusha(); // push registers + call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug32))); + hlt(); } -// Write serialization page so VM thread can do a pseudo remote membar. -// We use the current thread pointer to calculate a thread specific -// offset to write to within the page. This minimizes bus traffic -// due to cache line collision. -void MacroAssembler::serialize_memory(Register thread, - Register tmp) { +void MacroAssembler::warn(const char* msg) { + push_CPU_state(); - movl(tmp, thread); - shrl(tmp, os::get_serialize_page_shift_count()); - andl(tmp, (os::vm_page_size() - sizeof(int))); + ExternalAddress message((address) msg); + // push address of message + pushptr(message.addr()); - Address index(noreg, tmp, Address::times_1); - ExternalAddress page(os::get_memory_serialize_page()); - - movptr(ArrayAddress(page, index), tmp); + call(RuntimeAddress(CAST_FROM_FN_PTR(address, warning))); + addl(rsp, wordSize); // discard argument + pop_CPU_state(); } -void MacroAssembler::verify_tlab() { -#ifdef ASSERT - if (UseTLAB) { - Label next, ok; - Register t1 = rsi; +#else // _LP64 - pushq(t1); +// 64 bit versions - movq(t1, Address(r15_thread, in_bytes(JavaThread::tlab_top_offset()))); - cmpq(t1, Address(r15_thread, in_bytes(JavaThread::tlab_start_offset()))); - jcc(Assembler::aboveEqual, next); - stop("assert(top >= start)"); - should_not_reach_here(); +Address MacroAssembler::as_Address(AddressLiteral adr) { + // amd64 always does this as a pc-rel + // we can be absolute or disp based on the instruction type + // jmp/call are displacements others are absolute + assert(!adr.is_lval(), "must be rval"); + assert(reachable(adr), "must be"); + return Address((int32_t)(intptr_t)(adr.target() - pc()), adr.target(), adr.reloc()); - bind(next); - movq(t1, Address(r15_thread, in_bytes(JavaThread::tlab_end_offset()))); - cmpq(t1, Address(r15_thread, in_bytes(JavaThread::tlab_top_offset()))); - jcc(Assembler::aboveEqual, ok); - stop("assert(top <= end)"); - should_not_reach_here(); - - bind(ok); - - popq(t1); - } -#endif } -// Defines obj, preserves var_size_in_bytes -void MacroAssembler::eden_allocate(Register obj, - Register var_size_in_bytes, - int con_size_in_bytes, - Register t1, - Label& slow_case) { - assert(obj == rax, "obj must be in rax for cmpxchg"); - assert_different_registers(obj, var_size_in_bytes, t1); - Register end = t1; - Label retry; - bind(retry); - ExternalAddress heap_top((address) Universe::heap()->top_addr()); - movptr(obj, heap_top); - if (var_size_in_bytes == noreg) { - leaq(end, Address(obj, con_size_in_bytes)); - } else { - leaq(end, Address(obj, var_size_in_bytes, Address::times_1)); - } - // if end < obj then we wrapped around => object too long => slow case - cmpq(end, obj); - jcc(Assembler::below, slow_case); - cmpptr(end, ExternalAddress((address) Universe::heap()->end_addr())); - - jcc(Assembler::above, slow_case); - // Compare obj with the top addr, and if still equal, store the new - // top addr in end at the address of the top addr pointer. Sets ZF - // if was equal, and clears it otherwise. Use lock prefix for - // atomicity on MPs. - if (os::is_MP()) { - lock(); - } - cmpxchgptr(end, heap_top); - // if someone beat us on the allocation, try again, otherwise continue - jcc(Assembler::notEqual, retry); +Address MacroAssembler::as_Address(ArrayAddress adr) { + AddressLiteral base = adr.base(); + lea(rscratch1, base); + Address index = adr.index(); + assert(index._disp == 0, "must not have disp"); // maybe it can? + Address array(rscratch1, index._index, index._scale, index._disp); + return array; } -// Defines obj, preserves var_size_in_bytes, okay for t2 == var_size_in_bytes. -void MacroAssembler::tlab_allocate(Register obj, - Register var_size_in_bytes, - int con_size_in_bytes, - Register t1, - Register t2, - Label& slow_case) { - assert_different_registers(obj, t1, t2); - assert_different_registers(obj, var_size_in_bytes, t1); - Register end = t2; - - verify_tlab(); - - movq(obj, Address(r15_thread, JavaThread::tlab_top_offset())); - if (var_size_in_bytes == noreg) { - leaq(end, Address(obj, con_size_in_bytes)); - } else { - leaq(end, Address(obj, var_size_in_bytes, Address::times_1)); - } - cmpq(end, Address(r15_thread, JavaThread::tlab_end_offset())); - jcc(Assembler::above, slow_case); - - // update the tlab top pointer - movq(Address(r15_thread, JavaThread::tlab_top_offset()), end); - - // recover var_size_in_bytes if necessary - if (var_size_in_bytes == end) { - subq(var_size_in_bytes, obj); - } - verify_tlab(); -} - -// Preserves rbx and rdx. -void MacroAssembler::tlab_refill(Label& retry, - Label& try_eden, - Label& slow_case) { - Register top = rax; - Register t1 = rcx; - Register t2 = rsi; - Register t3 = r10; - Register thread_reg = r15_thread; - assert_different_registers(top, thread_reg, t1, t2, t3, - /* preserve: */ rbx, rdx); - Label do_refill, discard_tlab; - - if (CMSIncrementalMode || !Universe::heap()->supports_inline_contig_alloc()) { - // No allocation in the shared eden. - jmp(slow_case); - } - - movq(top, Address(thread_reg, in_bytes(JavaThread::tlab_top_offset()))); - movq(t1, Address(thread_reg, in_bytes(JavaThread::tlab_end_offset()))); - - // calculate amount of free space - subq(t1, top); - shrq(t1, LogHeapWordSize); - - // Retain tlab and allocate object in shared space if - // the amount free in the tlab is too large to discard. - cmpq(t1, Address(thread_reg, // size_t - in_bytes(JavaThread::tlab_refill_waste_limit_offset()))); - jcc(Assembler::lessEqual, discard_tlab); - - // Retain - mov64(t2, ThreadLocalAllocBuffer::refill_waste_limit_increment()); - addq(Address(thread_reg, // size_t - in_bytes(JavaThread::tlab_refill_waste_limit_offset())), - t2); - if (TLABStats) { - // increment number of slow_allocations - addl(Address(thread_reg, // unsigned int - in_bytes(JavaThread::tlab_slow_allocations_offset())), - 1); - } - jmp(try_eden); - - bind(discard_tlab); - if (TLABStats) { - // increment number of refills - addl(Address(thread_reg, // unsigned int - in_bytes(JavaThread::tlab_number_of_refills_offset())), - 1); - // accumulate wastage -- t1 is amount free in tlab - addl(Address(thread_reg, // unsigned int - in_bytes(JavaThread::tlab_fast_refill_waste_offset())), - t1); - } - - // if tlab is currently allocated (top or end != null) then - // fill [top, end + alignment_reserve) with array object - testq(top, top); - jcc(Assembler::zero, do_refill); - - // set up the mark word - mov64(t3, (int64_t) markOopDesc::prototype()->copy_set_hash(0x2)); - movq(Address(top, oopDesc::mark_offset_in_bytes()), t3); - // set the length to the remaining space - subq(t1, typeArrayOopDesc::header_size(T_INT)); - addq(t1, (int)ThreadLocalAllocBuffer::alignment_reserve()); - shlq(t1, log2_intptr(HeapWordSize / sizeof(jint))); - movq(Address(top, arrayOopDesc::length_offset_in_bytes()), t1); - // set klass to intArrayKlass - movptr(t1, ExternalAddress((address) Universe::intArrayKlassObj_addr())); - // store klass last. concurrent gcs assumes klass length is valid if - // klass field is not null. - store_klass(top, t1); - - // refill the tlab with an eden allocation - bind(do_refill); - movq(t1, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset()))); - shlq(t1, LogHeapWordSize); - // add object_size ?? - eden_allocate(top, t1, 0, t2, slow_case); - - // Check that t1 was preserved in eden_allocate. -#ifdef ASSERT - if (UseTLAB) { - Label ok; - Register tsize = rsi; - assert_different_registers(tsize, thread_reg, t1); - pushq(tsize); - movq(tsize, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset()))); - shlq(tsize, LogHeapWordSize); - cmpq(t1, tsize); - jcc(Assembler::equal, ok); - stop("assert(t1 != tlab size)"); - should_not_reach_here(); - - bind(ok); - popq(tsize); - } -#endif - movq(Address(thread_reg, in_bytes(JavaThread::tlab_start_offset())), top); - movq(Address(thread_reg, in_bytes(JavaThread::tlab_top_offset())), top); - addq(top, t1); - subq(top, (int)ThreadLocalAllocBuffer::alignment_reserve_in_bytes()); - movq(Address(thread_reg, in_bytes(JavaThread::tlab_end_offset())), top); - verify_tlab(); - jmp(retry); -} - - -int MacroAssembler::biased_locking_enter(Register lock_reg, Register obj_reg, Register swap_reg, Register tmp_reg, +int MacroAssembler::biased_locking_enter(Register lock_reg, + Register obj_reg, + Register swap_reg, + Register tmp_reg, bool swap_reg_contains_mark, - Label& done, Label* slow_case, + Label& done, + Label* slow_case, BiasedLockingCounters* counters) { assert(UseBiasedLocking, "why call this otherwise?"); assert(swap_reg == rax, "swap_reg must be rax for cmpxchgq"); @@ -5129,6 +4958,426 @@ int MacroAssembler::biased_locking_enter(Register lock_reg, Register obj_reg, Re return null_check_offset; } +void MacroAssembler::call_VM_leaf_base(address entry_point, int num_args) { + Label L, E; + +#ifdef _WIN64 + // Windows always allocates space for it's register args + assert(num_args <= 4, "only register arguments supported"); + subq(rsp, frame::arg_reg_save_area_bytes); +#endif + + // Align stack if necessary + testl(rsp, 15); + jcc(Assembler::zero, L); + + subq(rsp, 8); + { + call(RuntimeAddress(entry_point)); + } + addq(rsp, 8); + jmp(E); + + bind(L); + { + call(RuntimeAddress(entry_point)); + } + + bind(E); + +#ifdef _WIN64 + // restore stack pointer + addq(rsp, frame::arg_reg_save_area_bytes); +#endif + +} + +void MacroAssembler::cmp64(Register src1, AddressLiteral src2) { + assert(!src2.is_lval(), "should use cmpptr"); + + if (reachable(src2)) { + cmpq(src1, as_Address(src2)); + } else { + lea(rscratch1, src2); + Assembler::cmpq(src1, Address(rscratch1, 0)); + } +} + +int MacroAssembler::corrected_idivq(Register reg) { + // Full implementation of Java ldiv and lrem; checks for special + // case as described in JVM spec., p.243 & p.271. The function + // returns the (pc) offset of the idivl instruction - may be needed + // for implicit exceptions. + // + // normal case special case + // + // input : rax: dividend min_long + // reg: divisor (may not be eax/edx) -1 + // + // output: rax: quotient (= rax idiv reg) min_long + // rdx: remainder (= rax irem reg) 0 + assert(reg != rax && reg != rdx, "reg cannot be rax or rdx register"); + static const int64_t min_long = 0x8000000000000000; + Label normal_case, special_case; + + // check for special case + cmp64(rax, ExternalAddress((address) &min_long)); + jcc(Assembler::notEqual, normal_case); + xorl(rdx, rdx); // prepare rdx for possible special case (where + // remainder = 0) + cmpq(reg, -1); + jcc(Assembler::equal, special_case); + + // handle normal case + bind(normal_case); + cdqq(); + int idivq_offset = offset(); + idivq(reg); + + // normal and special case exit + bind(special_case); + + return idivq_offset; +} + +void MacroAssembler::decrementq(Register reg, int value) { + if (value == min_jint) { subq(reg, value); return; } + if (value < 0) { incrementq(reg, -value); return; } + if (value == 0) { ; return; } + if (value == 1 && UseIncDec) { decq(reg) ; return; } + /* else */ { subq(reg, value) ; return; } +} + +void MacroAssembler::decrementq(Address dst, int value) { + if (value == min_jint) { subq(dst, value); return; } + if (value < 0) { incrementq(dst, -value); return; } + if (value == 0) { ; return; } + if (value == 1 && UseIncDec) { decq(dst) ; return; } + /* else */ { subq(dst, value) ; return; } +} + +void MacroAssembler::fat_nop() { + // A 5 byte nop that is safe for patching (see patch_verified_entry) + // Recommened sequence from 'Software Optimization Guide for the AMD + // Hammer Processor' + emit_byte(0x66); + emit_byte(0x66); + emit_byte(0x90); + emit_byte(0x66); + emit_byte(0x90); +} + +void MacroAssembler::incrementq(Register reg, int value) { + if (value == min_jint) { addq(reg, value); return; } + if (value < 0) { decrementq(reg, -value); return; } + if (value == 0) { ; return; } + if (value == 1 && UseIncDec) { incq(reg) ; return; } + /* else */ { addq(reg, value) ; return; } +} + +void MacroAssembler::incrementq(Address dst, int value) { + if (value == min_jint) { addq(dst, value); return; } + if (value < 0) { decrementq(dst, -value); return; } + if (value == 0) { ; return; } + if (value == 1 && UseIncDec) { incq(dst) ; return; } + /* else */ { addq(dst, value) ; return; } +} + +// 32bit can do a case table jump in one instruction but we no longer allow the base +// to be installed in the Address class +void MacroAssembler::jump(ArrayAddress entry) { + lea(rscratch1, entry.base()); + Address dispatch = entry.index(); + assert(dispatch._base == noreg, "must be"); + dispatch._base = rscratch1; + jmp(dispatch); +} + +void MacroAssembler::lcmp2int(Register x_hi, Register x_lo, Register y_hi, Register y_lo) { + ShouldNotReachHere(); // 64bit doesn't use two regs + cmpq(x_lo, y_lo); +} + +void MacroAssembler::lea(Register dst, AddressLiteral src) { + mov_literal64(dst, (intptr_t)src.target(), src.rspec()); +} + +void MacroAssembler::lea(Address dst, AddressLiteral adr) { + mov_literal64(rscratch1, (intptr_t)adr.target(), adr.rspec()); + movptr(dst, rscratch1); +} + +void MacroAssembler::leave() { + // %%% is this really better? Why not on 32bit too? + emit_byte(0xC9); // LEAVE +} + +void MacroAssembler::lneg(Register hi, Register lo) { + ShouldNotReachHere(); // 64bit doesn't use two regs + negq(lo); +} + +void MacroAssembler::movoop(Register dst, jobject obj) { + mov_literal64(dst, (intptr_t)obj, oop_Relocation::spec_for_immediate()); +} + +void MacroAssembler::movoop(Address dst, jobject obj) { + mov_literal64(rscratch1, (intptr_t)obj, oop_Relocation::spec_for_immediate()); + movq(dst, rscratch1); +} + +void MacroAssembler::movptr(Register dst, AddressLiteral src) { + if (src.is_lval()) { + mov_literal64(dst, (intptr_t)src.target(), src.rspec()); + } else { + if (reachable(src)) { + movq(dst, as_Address(src)); + } else { + lea(rscratch1, src); + movq(dst, Address(rscratch1,0)); + } + } +} + +void MacroAssembler::movptr(ArrayAddress dst, Register src) { + movq(as_Address(dst), src); +} + +void MacroAssembler::movptr(Register dst, ArrayAddress src) { + movq(dst, as_Address(src)); +} + +// src should NEVER be a real pointer. Use AddressLiteral for true pointers +void MacroAssembler::movptr(Address dst, intptr_t src) { + mov64(rscratch1, src); + movq(dst, rscratch1); +} + +// These are mostly for initializing NULL +void MacroAssembler::movptr(Address dst, int32_t src) { + movslq(dst, src); +} + +void MacroAssembler::movptr(Register dst, int32_t src) { + mov64(dst, (intptr_t)src); +} + +void MacroAssembler::pushoop(jobject obj) { + movoop(rscratch1, obj); + push(rscratch1); +} + +void MacroAssembler::pushptr(AddressLiteral src) { + lea(rscratch1, src); + if (src.is_lval()) { + push(rscratch1); + } else { + pushq(Address(rscratch1, 0)); + } +} + +void MacroAssembler::reset_last_Java_frame(bool clear_fp, + bool clear_pc) { + // we must set sp to zero to clear frame + movptr(Address(r15_thread, JavaThread::last_Java_sp_offset()), (int32_t)NULL_WORD); + // must clear fp, so that compiled frames are not confused; it is + // possible that we need it only for debugging + if (clear_fp) { + movptr(Address(r15_thread, JavaThread::last_Java_fp_offset()), (int32_t)NULL_WORD); + } + + if (clear_pc) { + movptr(Address(r15_thread, JavaThread::last_Java_pc_offset()), (int32_t)NULL_WORD); + } +} + +void MacroAssembler::set_last_Java_frame(Register last_java_sp, + Register last_java_fp, + address last_java_pc) { + // determine last_java_sp register + if (!last_java_sp->is_valid()) { + last_java_sp = rsp; + } + + // last_java_fp is optional + if (last_java_fp->is_valid()) { + movptr(Address(r15_thread, JavaThread::last_Java_fp_offset()), + last_java_fp); + } + + // last_java_pc is optional + if (last_java_pc != NULL) { + Address java_pc(r15_thread, + JavaThread::frame_anchor_offset() + JavaFrameAnchor::last_Java_pc_offset()); + lea(rscratch1, InternalAddress(last_java_pc)); + movptr(java_pc, rscratch1); + } + + movptr(Address(r15_thread, JavaThread::last_Java_sp_offset()), last_java_sp); +} + +static void pass_arg0(MacroAssembler* masm, Register arg) { + if (c_rarg0 != arg ) { + masm->mov(c_rarg0, arg); + } +} + +static void pass_arg1(MacroAssembler* masm, Register arg) { + if (c_rarg1 != arg ) { + masm->mov(c_rarg1, arg); + } +} + +static void pass_arg2(MacroAssembler* masm, Register arg) { + if (c_rarg2 != arg ) { + masm->mov(c_rarg2, arg); + } +} + +static void pass_arg3(MacroAssembler* masm, Register arg) { + if (c_rarg3 != arg ) { + masm->mov(c_rarg3, arg); + } +} + +void MacroAssembler::stop(const char* msg) { + address rip = pc(); + pusha(); // get regs on stack + lea(c_rarg0, ExternalAddress((address) msg)); + lea(c_rarg1, InternalAddress(rip)); + movq(c_rarg2, rsp); // pass pointer to regs array + andq(rsp, -16); // align stack as required by ABI + call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug64))); + hlt(); +} + +void MacroAssembler::warn(const char* msg) { + push(r12); + movq(r12, rsp); + andq(rsp, -16); // align stack as required by push_CPU_state and call + + push_CPU_state(); // keeps alignment at 16 bytes + lea(c_rarg0, ExternalAddress((address) msg)); + call_VM_leaf(CAST_FROM_FN_PTR(address, warning), c_rarg0); + pop_CPU_state(); + + movq(rsp, r12); + pop(r12); +} + +#ifndef PRODUCT +extern "C" void findpc(intptr_t x); +#endif + +void MacroAssembler::debug64(char* msg, int64_t pc, int64_t regs[]) { + // In order to get locks to work, we need to fake a in_VM state + if (ShowMessageBoxOnError ) { + JavaThread* thread = JavaThread::current(); + JavaThreadState saved_state = thread->thread_state(); + thread->set_thread_state(_thread_in_vm); +#ifndef PRODUCT + if (CountBytecodes || TraceBytecodes || StopInterpreterAt) { + ttyLocker ttyl; + BytecodeCounter::print(); + } +#endif + // To see where a verify_oop failed, get $ebx+40/X for this frame. + // XXX correct this offset for amd64 + // This is the value of eip which points to where verify_oop will return. + if (os::message_box(msg, "Execution stopped, print registers?")) { + ttyLocker ttyl; + tty->print_cr("rip = 0x%016lx", pc); +#ifndef PRODUCT + tty->cr(); + findpc(pc); + tty->cr(); +#endif + tty->print_cr("rax = 0x%016lx", regs[15]); + tty->print_cr("rbx = 0x%016lx", regs[12]); + tty->print_cr("rcx = 0x%016lx", regs[14]); + tty->print_cr("rdx = 0x%016lx", regs[13]); + tty->print_cr("rdi = 0x%016lx", regs[8]); + tty->print_cr("rsi = 0x%016lx", regs[9]); + tty->print_cr("rbp = 0x%016lx", regs[10]); + tty->print_cr("rsp = 0x%016lx", regs[11]); + tty->print_cr("r8 = 0x%016lx", regs[7]); + tty->print_cr("r9 = 0x%016lx", regs[6]); + tty->print_cr("r10 = 0x%016lx", regs[5]); + tty->print_cr("r11 = 0x%016lx", regs[4]); + tty->print_cr("r12 = 0x%016lx", regs[3]); + tty->print_cr("r13 = 0x%016lx", regs[2]); + tty->print_cr("r14 = 0x%016lx", regs[1]); + tty->print_cr("r15 = 0x%016lx", regs[0]); + BREAKPOINT; + } + ThreadStateTransition::transition(thread, _thread_in_vm, saved_state); + } else { + ttyLocker ttyl; + ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n", + msg); + } +} + +#endif // _LP64 + +// Now versions that are common to 32/64 bit + +void MacroAssembler::addptr(Register dst, int32_t imm32) { + LP64_ONLY(addq(dst, imm32)) NOT_LP64(addl(dst, imm32)); +} + +void MacroAssembler::addptr(Register dst, Register src) { + LP64_ONLY(addq(dst, src)) NOT_LP64(addl(dst, src)); +} + +void MacroAssembler::addptr(Address dst, Register src) { + LP64_ONLY(addq(dst, src)) NOT_LP64(addl(dst, src)); +} + +void MacroAssembler::align(int modulus) { + if (offset() % modulus != 0) { + nop(modulus - (offset() % modulus)); + } +} + +void MacroAssembler::andpd(XMMRegister dst, AddressLiteral src) { + andpd(dst, as_Address(src)); +} + +void MacroAssembler::andptr(Register dst, int32_t imm32) { + LP64_ONLY(andq(dst, imm32)) NOT_LP64(andl(dst, imm32)); +} + +void MacroAssembler::atomic_incl(AddressLiteral counter_addr) { + pushf(); + if (os::is_MP()) + lock(); + incrementl(counter_addr); + popf(); +} + +// Writes to stack successive pages until offset reached to check for +// stack overflow + shadow pages. This clobbers tmp. +void MacroAssembler::bang_stack_size(Register size, Register tmp) { + movptr(tmp, rsp); + // Bang stack for total size given plus shadow page size. + // Bang one page at a time because large size can bang beyond yellow and + // red zones. + Label loop; + bind(loop); + movl(Address(tmp, (-os::vm_page_size())), size ); + subptr(tmp, os::vm_page_size()); + subl(size, os::vm_page_size()); + jcc(Assembler::greater, loop); + + // Bang down shadow pages too. + // The -1 because we already subtracted 1 page. + for (int i = 0; i< StackShadowPages-1; i++) { + // this could be any sized move but this is can be a debugging crumb + // so the bigger the better. + movptr(Address(tmp, (-i*os::vm_page_size())), size ); + } +} void MacroAssembler::biased_locking_exit(Register obj_reg, Register temp_reg, Label& done) { assert(UseBiasedLocking, "why call this otherwise?"); @@ -5139,41 +5388,1943 @@ void MacroAssembler::biased_locking_exit(Register obj_reg, Register temp_reg, La // a higher level. Second, if the bias was revoked while we held the // lock, the object could not be rebiased toward another thread, so // the bias bit would be clear. - movq(temp_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); - andq(temp_reg, markOopDesc::biased_lock_mask_in_place); - cmpq(temp_reg, markOopDesc::biased_lock_pattern); + movptr(temp_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); + andptr(temp_reg, markOopDesc::biased_lock_mask_in_place); + cmpptr(temp_reg, markOopDesc::biased_lock_pattern); jcc(Assembler::equal, done); } +void MacroAssembler::c2bool(Register x) { + // implements x == 0 ? 0 : 1 + // note: must only look at least-significant byte of x + // since C-style booleans are stored in one byte + // only! (was bug) + andl(x, 0xFF); + setb(Assembler::notZero, x); +} + +// Wouldn't need if AddressLiteral version had new name +void MacroAssembler::call(Label& L, relocInfo::relocType rtype) { + Assembler::call(L, rtype); +} + +void MacroAssembler::call(Register entry) { + Assembler::call(entry); +} + +void MacroAssembler::call(AddressLiteral entry) { + if (reachable(entry)) { + Assembler::call_literal(entry.target(), entry.rspec()); + } else { + lea(rscratch1, entry); + Assembler::call(rscratch1); + } +} + +// Implementation of call_VM versions + +void MacroAssembler::call_VM(Register oop_result, + address entry_point, + bool check_exceptions) { + Label C, E; + call(C, relocInfo::none); + jmp(E); + + bind(C); + call_VM_helper(oop_result, entry_point, 0, check_exceptions); + ret(0); + + bind(E); +} + +void MacroAssembler::call_VM(Register oop_result, + address entry_point, + Register arg_1, + bool check_exceptions) { + Label C, E; + call(C, relocInfo::none); + jmp(E); + + bind(C); + pass_arg1(this, arg_1); + call_VM_helper(oop_result, entry_point, 1, check_exceptions); + ret(0); + + bind(E); +} + +void MacroAssembler::call_VM(Register oop_result, + address entry_point, + Register arg_1, + Register arg_2, + bool check_exceptions) { + Label C, E; + call(C, relocInfo::none); + jmp(E); + + bind(C); + + LP64_ONLY(assert(arg_1 != c_rarg2, "smashed arg")); + + pass_arg2(this, arg_2); + pass_arg1(this, arg_1); + call_VM_helper(oop_result, entry_point, 2, check_exceptions); + ret(0); + + bind(E); +} + +void MacroAssembler::call_VM(Register oop_result, + address entry_point, + Register arg_1, + Register arg_2, + Register arg_3, + bool check_exceptions) { + Label C, E; + call(C, relocInfo::none); + jmp(E); + + bind(C); + + LP64_ONLY(assert(arg_1 != c_rarg3, "smashed arg")); + LP64_ONLY(assert(arg_2 != c_rarg3, "smashed arg")); + pass_arg3(this, arg_3); + + LP64_ONLY(assert(arg_1 != c_rarg2, "smashed arg")); + pass_arg2(this, arg_2); + + pass_arg1(this, arg_1); + call_VM_helper(oop_result, entry_point, 3, check_exceptions); + ret(0); + + bind(E); +} + +void MacroAssembler::call_VM(Register oop_result, + Register last_java_sp, + address entry_point, + int number_of_arguments, + bool check_exceptions) { + Register thread = LP64_ONLY(r15_thread) NOT_LP64(noreg); + call_VM_base(oop_result, thread, last_java_sp, entry_point, number_of_arguments, check_exceptions); +} + +void MacroAssembler::call_VM(Register oop_result, + Register last_java_sp, + address entry_point, + Register arg_1, + bool check_exceptions) { + pass_arg1(this, arg_1); + call_VM(oop_result, last_java_sp, entry_point, 1, check_exceptions); +} + +void MacroAssembler::call_VM(Register oop_result, + Register last_java_sp, + address entry_point, + Register arg_1, + Register arg_2, + bool check_exceptions) { + + LP64_ONLY(assert(arg_1 != c_rarg2, "smashed arg")); + pass_arg2(this, arg_2); + pass_arg1(this, arg_1); + call_VM(oop_result, last_java_sp, entry_point, 2, check_exceptions); +} + +void MacroAssembler::call_VM(Register oop_result, + Register last_java_sp, + address entry_point, + Register arg_1, + Register arg_2, + Register arg_3, + bool check_exceptions) { + LP64_ONLY(assert(arg_1 != c_rarg3, "smashed arg")); + LP64_ONLY(assert(arg_2 != c_rarg3, "smashed arg")); + pass_arg3(this, arg_3); + LP64_ONLY(assert(arg_1 != c_rarg2, "smashed arg")); + pass_arg2(this, arg_2); + pass_arg1(this, arg_1); + call_VM(oop_result, last_java_sp, entry_point, 3, check_exceptions); +} + +void MacroAssembler::call_VM_base(Register oop_result, + Register java_thread, + Register last_java_sp, + address entry_point, + int number_of_arguments, + bool check_exceptions) { + // determine java_thread register + if (!java_thread->is_valid()) { +#ifdef _LP64 + java_thread = r15_thread; +#else + java_thread = rdi; + get_thread(java_thread); +#endif // LP64 + } + // determine last_java_sp register + if (!last_java_sp->is_valid()) { + last_java_sp = rsp; + } + // debugging support + assert(number_of_arguments >= 0 , "cannot have negative number of arguments"); + LP64_ONLY(assert(java_thread == r15_thread, "unexpected register")); + assert(java_thread != oop_result , "cannot use the same register for java_thread & oop_result"); + assert(java_thread != last_java_sp, "cannot use the same register for java_thread & last_java_sp"); + + // push java thread (becomes first argument of C function) + + NOT_LP64(push(java_thread); number_of_arguments++); + LP64_ONLY(mov(c_rarg0, r15_thread)); + + // set last Java frame before call + assert(last_java_sp != rbp, "can't use ebp/rbp"); + + // Only interpreter should have to set fp + set_last_Java_frame(java_thread, last_java_sp, rbp, NULL); + + // do the call, remove parameters + MacroAssembler::call_VM_leaf_base(entry_point, number_of_arguments); + + // restore the thread (cannot use the pushed argument since arguments + // may be overwritten by C code generated by an optimizing compiler); + // however can use the register value directly if it is callee saved. + if (LP64_ONLY(true ||) java_thread == rdi || java_thread == rsi) { + // rdi & rsi (also r15) are callee saved -> nothing to do +#ifdef ASSERT + guarantee(java_thread != rax, "change this code"); + push(rax); + { Label L; + get_thread(rax); + cmpptr(java_thread, rax); + jcc(Assembler::equal, L); + stop("MacroAssembler::call_VM_base: rdi not callee saved?"); + bind(L); + } + pop(rax); +#endif + } else { + get_thread(java_thread); + } + // reset last Java frame + // Only interpreter should have to clear fp + reset_last_Java_frame(java_thread, true, false); + +#ifndef CC_INTERP + // C++ interp handles this in the interpreter + check_and_handle_popframe(java_thread); + check_and_handle_earlyret(java_thread); +#endif /* CC_INTERP */ + + if (check_exceptions) { + // check for pending exceptions (java_thread is set upon return) + cmpptr(Address(java_thread, Thread::pending_exception_offset()), (int32_t) NULL_WORD); +#ifndef _LP64 + jump_cc(Assembler::notEqual, + RuntimeAddress(StubRoutines::forward_exception_entry())); +#else + // This used to conditionally jump to forward_exception however it is + // possible if we relocate that the branch will not reach. So we must jump + // around so we can always reach + + Label ok; + jcc(Assembler::equal, ok); + jump(RuntimeAddress(StubRoutines::forward_exception_entry())); + bind(ok); +#endif // LP64 + } + + // get oop result if there is one and reset the value in the thread + if (oop_result->is_valid()) { + movptr(oop_result, Address(java_thread, JavaThread::vm_result_offset())); + movptr(Address(java_thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD); + verify_oop(oop_result, "broken oop in call_VM_base"); + } +} + +void MacroAssembler::call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions) { + + // Calculate the value for last_Java_sp + // somewhat subtle. call_VM does an intermediate call + // which places a return address on the stack just under the + // stack pointer as the user finsihed with it. This allows + // use to retrieve last_Java_pc from last_Java_sp[-1]. + // On 32bit we then have to push additional args on the stack to accomplish + // the actual requested call. On 64bit call_VM only can use register args + // so the only extra space is the return address that call_VM created. + // This hopefully explains the calculations here. + +#ifdef _LP64 + // We've pushed one address, correct last_Java_sp + lea(rax, Address(rsp, wordSize)); +#else + lea(rax, Address(rsp, (1 + number_of_arguments) * wordSize)); +#endif // LP64 + + call_VM_base(oop_result, noreg, rax, entry_point, number_of_arguments, check_exceptions); + +} + +void MacroAssembler::call_VM_leaf(address entry_point, int number_of_arguments) { + call_VM_leaf_base(entry_point, number_of_arguments); +} + +void MacroAssembler::call_VM_leaf(address entry_point, Register arg_0) { + pass_arg0(this, arg_0); + call_VM_leaf(entry_point, 1); +} + +void MacroAssembler::call_VM_leaf(address entry_point, Register arg_0, Register arg_1) { + + LP64_ONLY(assert(arg_0 != c_rarg1, "smashed arg")); + pass_arg1(this, arg_1); + pass_arg0(this, arg_0); + call_VM_leaf(entry_point, 2); +} + +void MacroAssembler::call_VM_leaf(address entry_point, Register arg_0, Register arg_1, Register arg_2) { + LP64_ONLY(assert(arg_0 != c_rarg2, "smashed arg")); + LP64_ONLY(assert(arg_1 != c_rarg2, "smashed arg")); + pass_arg2(this, arg_2); + LP64_ONLY(assert(arg_0 != c_rarg1, "smashed arg")); + pass_arg1(this, arg_1); + pass_arg0(this, arg_0); + call_VM_leaf(entry_point, 3); +} + +void MacroAssembler::check_and_handle_earlyret(Register java_thread) { +} + +void MacroAssembler::check_and_handle_popframe(Register java_thread) { +} + +void MacroAssembler::cmp32(AddressLiteral src1, int32_t imm) { + if (reachable(src1)) { + cmpl(as_Address(src1), imm); + } else { + lea(rscratch1, src1); + cmpl(Address(rscratch1, 0), imm); + } +} + +void MacroAssembler::cmp32(Register src1, AddressLiteral src2) { + assert(!src2.is_lval(), "use cmpptr"); + if (reachable(src2)) { + cmpl(src1, as_Address(src2)); + } else { + lea(rscratch1, src2); + cmpl(src1, Address(rscratch1, 0)); + } +} + +void MacroAssembler::cmp32(Register src1, int32_t imm) { + Assembler::cmpl(src1, imm); +} + +void MacroAssembler::cmp32(Register src1, Address src2) { + Assembler::cmpl(src1, src2); +} + +void MacroAssembler::cmpsd2int(XMMRegister opr1, XMMRegister opr2, Register dst, bool unordered_is_less) { + ucomisd(opr1, opr2); + + Label L; + if (unordered_is_less) { + movl(dst, -1); + jcc(Assembler::parity, L); + jcc(Assembler::below , L); + movl(dst, 0); + jcc(Assembler::equal , L); + increment(dst); + } else { // unordered is greater + movl(dst, 1); + jcc(Assembler::parity, L); + jcc(Assembler::above , L); + movl(dst, 0); + jcc(Assembler::equal , L); + decrementl(dst); + } + bind(L); +} + +void MacroAssembler::cmpss2int(XMMRegister opr1, XMMRegister opr2, Register dst, bool unordered_is_less) { + ucomiss(opr1, opr2); + + Label L; + if (unordered_is_less) { + movl(dst, -1); + jcc(Assembler::parity, L); + jcc(Assembler::below , L); + movl(dst, 0); + jcc(Assembler::equal , L); + increment(dst); + } else { // unordered is greater + movl(dst, 1); + jcc(Assembler::parity, L); + jcc(Assembler::above , L); + movl(dst, 0); + jcc(Assembler::equal , L); + decrementl(dst); + } + bind(L); +} + + +void MacroAssembler::cmp8(AddressLiteral src1, int imm) { + if (reachable(src1)) { + cmpb(as_Address(src1), imm); + } else { + lea(rscratch1, src1); + cmpb(Address(rscratch1, 0), imm); + } +} + +void MacroAssembler::cmpptr(Register src1, AddressLiteral src2) { +#ifdef _LP64 + if (src2.is_lval()) { + movptr(rscratch1, src2); + Assembler::cmpq(src1, rscratch1); + } else if (reachable(src2)) { + cmpq(src1, as_Address(src2)); + } else { + lea(rscratch1, src2); + Assembler::cmpq(src1, Address(rscratch1, 0)); + } +#else + if (src2.is_lval()) { + cmp_literal32(src1, (int32_t) src2.target(), src2.rspec()); + } else { + cmpl(src1, as_Address(src2)); + } +#endif // _LP64 +} + +void MacroAssembler::cmpptr(Address src1, AddressLiteral src2) { + assert(src2.is_lval(), "not a mem-mem compare"); +#ifdef _LP64 + // moves src2's literal address + movptr(rscratch1, src2); + Assembler::cmpq(src1, rscratch1); +#else + cmp_literal32(src1, (int32_t) src2.target(), src2.rspec()); +#endif // _LP64 +} + +void MacroAssembler::locked_cmpxchgptr(Register reg, AddressLiteral adr) { + if (reachable(adr)) { + if (os::is_MP()) + lock(); + cmpxchgptr(reg, as_Address(adr)); + } else { + lea(rscratch1, adr); + if (os::is_MP()) + lock(); + cmpxchgptr(reg, Address(rscratch1, 0)); + } +} + +void MacroAssembler::cmpxchgptr(Register reg, Address adr) { + LP64_ONLY(cmpxchgq(reg, adr)) NOT_LP64(cmpxchgl(reg, adr)); +} + +void MacroAssembler::comisd(XMMRegister dst, AddressLiteral src) { + comisd(dst, as_Address(src)); +} + +void MacroAssembler::comiss(XMMRegister dst, AddressLiteral src) { + comiss(dst, as_Address(src)); +} + + +void MacroAssembler::cond_inc32(Condition cond, AddressLiteral counter_addr) { + Condition negated_cond = negate_condition(cond); + Label L; + jcc(negated_cond, L); + atomic_incl(counter_addr); + bind(L); +} + +int MacroAssembler::corrected_idivl(Register reg) { + // Full implementation of Java idiv and irem; checks for + // special case as described in JVM spec., p.243 & p.271. + // The function returns the (pc) offset of the idivl + // instruction - may be needed for implicit exceptions. + // + // normal case special case + // + // input : rax,: dividend min_int + // reg: divisor (may not be rax,/rdx) -1 + // + // output: rax,: quotient (= rax, idiv reg) min_int + // rdx: remainder (= rax, irem reg) 0 + assert(reg != rax && reg != rdx, "reg cannot be rax, or rdx register"); + const int min_int = 0x80000000; + Label normal_case, special_case; + + // check for special case + cmpl(rax, min_int); + jcc(Assembler::notEqual, normal_case); + xorl(rdx, rdx); // prepare rdx for possible special case (where remainder = 0) + cmpl(reg, -1); + jcc(Assembler::equal, special_case); + + // handle normal case + bind(normal_case); + cdql(); + int idivl_offset = offset(); + idivl(reg); + + // normal and special case exit + bind(special_case); + + return idivl_offset; +} + + + +void MacroAssembler::decrementl(Register reg, int value) { + if (value == min_jint) {subl(reg, value) ; return; } + if (value < 0) { incrementl(reg, -value); return; } + if (value == 0) { ; return; } + if (value == 1 && UseIncDec) { decl(reg) ; return; } + /* else */ { subl(reg, value) ; return; } +} + +void MacroAssembler::decrementl(Address dst, int value) { + if (value == min_jint) {subl(dst, value) ; return; } + if (value < 0) { incrementl(dst, -value); return; } + if (value == 0) { ; return; } + if (value == 1 && UseIncDec) { decl(dst) ; return; } + /* else */ { subl(dst, value) ; return; } +} + +void MacroAssembler::division_with_shift (Register reg, int shift_value) { + assert (shift_value > 0, "illegal shift value"); + Label _is_positive; + testl (reg, reg); + jcc (Assembler::positive, _is_positive); + int offset = (1 << shift_value) - 1 ; + + if (offset == 1) { + incrementl(reg); + } else { + addl(reg, offset); + } + + bind (_is_positive); + sarl(reg, shift_value); +} + +// !defined(COMPILER2) is because of stupid core builds +#if !defined(_LP64) || defined(COMPILER1) || !defined(COMPILER2) +void MacroAssembler::empty_FPU_stack() { + if (VM_Version::supports_mmx()) { + emms(); + } else { + for (int i = 8; i-- > 0; ) ffree(i); + } +} +#endif // !LP64 || C1 || !C2 + + +// Defines obj, preserves var_size_in_bytes +void MacroAssembler::eden_allocate(Register obj, + Register var_size_in_bytes, + int con_size_in_bytes, + Register t1, + Label& slow_case) { + assert(obj == rax, "obj must be in rax, for cmpxchg"); + assert_different_registers(obj, var_size_in_bytes, t1); + Register end = t1; + Label retry; + bind(retry); + ExternalAddress heap_top((address) Universe::heap()->top_addr()); + movptr(obj, heap_top); + if (var_size_in_bytes == noreg) { + lea(end, Address(obj, con_size_in_bytes)); + } else { + lea(end, Address(obj, var_size_in_bytes, Address::times_1)); + } + // if end < obj then we wrapped around => object too long => slow case + cmpptr(end, obj); + jcc(Assembler::below, slow_case); + cmpptr(end, ExternalAddress((address) Universe::heap()->end_addr())); + jcc(Assembler::above, slow_case); + // Compare obj with the top addr, and if still equal, store the new top addr in + // end at the address of the top addr pointer. Sets ZF if was equal, and clears + // it otherwise. Use lock prefix for atomicity on MPs. + locked_cmpxchgptr(end, heap_top); + jcc(Assembler::notEqual, retry); +} + +void MacroAssembler::enter() { + push(rbp); + mov(rbp, rsp); +} + +void MacroAssembler::fcmp(Register tmp) { + fcmp(tmp, 1, true, true); +} + +void MacroAssembler::fcmp(Register tmp, int index, bool pop_left, bool pop_right) { + assert(!pop_right || pop_left, "usage error"); + if (VM_Version::supports_cmov()) { + assert(tmp == noreg, "unneeded temp"); + if (pop_left) { + fucomip(index); + } else { + fucomi(index); + } + if (pop_right) { + fpop(); + } + } else { + assert(tmp != noreg, "need temp"); + if (pop_left) { + if (pop_right) { + fcompp(); + } else { + fcomp(index); + } + } else { + fcom(index); + } + // convert FPU condition into eflags condition via rax, + save_rax(tmp); + fwait(); fnstsw_ax(); + sahf(); + restore_rax(tmp); + } + // condition codes set as follows: + // + // CF (corresponds to C0) if x < y + // PF (corresponds to C2) if unordered + // ZF (corresponds to C3) if x = y +} + +void MacroAssembler::fcmp2int(Register dst, bool unordered_is_less) { + fcmp2int(dst, unordered_is_less, 1, true, true); +} + +void MacroAssembler::fcmp2int(Register dst, bool unordered_is_less, int index, bool pop_left, bool pop_right) { + fcmp(VM_Version::supports_cmov() ? noreg : dst, index, pop_left, pop_right); + Label L; + if (unordered_is_less) { + movl(dst, -1); + jcc(Assembler::parity, L); + jcc(Assembler::below , L); + movl(dst, 0); + jcc(Assembler::equal , L); + increment(dst); + } else { // unordered is greater + movl(dst, 1); + jcc(Assembler::parity, L); + jcc(Assembler::above , L); + movl(dst, 0); + jcc(Assembler::equal , L); + decrementl(dst); + } + bind(L); +} + +void MacroAssembler::fld_d(AddressLiteral src) { + fld_d(as_Address(src)); +} + +void MacroAssembler::fld_s(AddressLiteral src) { + fld_s(as_Address(src)); +} + +void MacroAssembler::fld_x(AddressLiteral src) { + Assembler::fld_x(as_Address(src)); +} + +void MacroAssembler::fldcw(AddressLiteral src) { + Assembler::fldcw(as_Address(src)); +} + +void MacroAssembler::fpop() { + ffree(); + fincstp(); +} + +void MacroAssembler::fremr(Register tmp) { + save_rax(tmp); + { Label L; + bind(L); + fprem(); + fwait(); fnstsw_ax(); +#ifdef _LP64 + testl(rax, 0x400); + jcc(Assembler::notEqual, L); +#else + sahf(); + jcc(Assembler::parity, L); +#endif // _LP64 + } + restore_rax(tmp); + // Result is in ST0. + // Note: fxch & fpop to get rid of ST1 + // (otherwise FPU stack could overflow eventually) + fxch(1); + fpop(); +} + + +void MacroAssembler::incrementl(AddressLiteral dst) { + if (reachable(dst)) { + incrementl(as_Address(dst)); + } else { + lea(rscratch1, dst); + incrementl(Address(rscratch1, 0)); + } +} + +void MacroAssembler::incrementl(ArrayAddress dst) { + incrementl(as_Address(dst)); +} + +void MacroAssembler::incrementl(Register reg, int value) { + if (value == min_jint) {addl(reg, value) ; return; } + if (value < 0) { decrementl(reg, -value); return; } + if (value == 0) { ; return; } + if (value == 1 && UseIncDec) { incl(reg) ; return; } + /* else */ { addl(reg, value) ; return; } +} + +void MacroAssembler::incrementl(Address dst, int value) { + if (value == min_jint) {addl(dst, value) ; return; } + if (value < 0) { decrementl(dst, -value); return; } + if (value == 0) { ; return; } + if (value == 1 && UseIncDec) { incl(dst) ; return; } + /* else */ { addl(dst, value) ; return; } +} + +void MacroAssembler::jump(AddressLiteral dst) { + if (reachable(dst)) { + jmp_literal(dst.target(), dst.rspec()); + } else { + lea(rscratch1, dst); + jmp(rscratch1); + } +} + +void MacroAssembler::jump_cc(Condition cc, AddressLiteral dst) { + if (reachable(dst)) { + InstructionMark im(this); + relocate(dst.reloc()); + const int short_size = 2; + const int long_size = 6; + int offs = (intptr_t)dst.target() - ((intptr_t)_code_pos); + if (dst.reloc() == relocInfo::none && is8bit(offs - short_size)) { + // 0111 tttn #8-bit disp + emit_byte(0x70 | cc); + emit_byte((offs - short_size) & 0xFF); + } else { + // 0000 1111 1000 tttn #32-bit disp + emit_byte(0x0F); + emit_byte(0x80 | cc); + emit_long(offs - long_size); + } + } else { +#ifdef ASSERT + warning("reversing conditional branch"); +#endif /* ASSERT */ + Label skip; + jccb(reverse[cc], skip); + lea(rscratch1, dst); + Assembler::jmp(rscratch1); + bind(skip); + } +} + +void MacroAssembler::ldmxcsr(AddressLiteral src) { + if (reachable(src)) { + Assembler::ldmxcsr(as_Address(src)); + } else { + lea(rscratch1, src); + Assembler::ldmxcsr(Address(rscratch1, 0)); + } +} + +int MacroAssembler::load_signed_byte(Register dst, Address src) { + int off; + if (LP64_ONLY(true ||) VM_Version::is_P6()) { + off = offset(); + movsbl(dst, src); // movsxb + } else { + off = load_unsigned_byte(dst, src); + shll(dst, 24); + sarl(dst, 24); + } + return off; +} + +// word => int32 which seems bad for 64bit +int MacroAssembler::load_signed_word(Register dst, Address src) { + int off; + if (LP64_ONLY(true ||) VM_Version::is_P6()) { + // This is dubious to me since it seems safe to do a signed 16 => 64 bit + // version but this is what 64bit has always done. This seems to imply + // that users are only using 32bits worth. + off = offset(); + movswl(dst, src); // movsxw + } else { + off = load_unsigned_word(dst, src); + shll(dst, 16); + sarl(dst, 16); + } + return off; +} + +int MacroAssembler::load_unsigned_byte(Register dst, Address src) { + // According to Intel Doc. AP-526, "Zero-Extension of Short", p.16, + // and "3.9 Partial Register Penalties", p. 22). + int off; + if (LP64_ONLY(true || ) VM_Version::is_P6() || src.uses(dst)) { + off = offset(); + movzbl(dst, src); // movzxb + } else { + xorl(dst, dst); + off = offset(); + movb(dst, src); + } + return off; +} + +int MacroAssembler::load_unsigned_word(Register dst, Address src) { + // According to Intel Doc. AP-526, "Zero-Extension of Short", p.16, + // and "3.9 Partial Register Penalties", p. 22). + int off; + if (LP64_ONLY(true ||) VM_Version::is_P6() || src.uses(dst)) { + off = offset(); + movzwl(dst, src); // movzxw + } else { + xorl(dst, dst); + off = offset(); + movw(dst, src); + } + return off; +} + +void MacroAssembler::mov32(AddressLiteral dst, Register src) { + if (reachable(dst)) { + movl(as_Address(dst), src); + } else { + lea(rscratch1, dst); + movl(Address(rscratch1, 0), src); + } +} + +void MacroAssembler::mov32(Register dst, AddressLiteral src) { + if (reachable(src)) { + movl(dst, as_Address(src)); + } else { + lea(rscratch1, src); + movl(dst, Address(rscratch1, 0)); + } +} + +// C++ bool manipulation + +void MacroAssembler::movbool(Register dst, Address src) { + if(sizeof(bool) == 1) + movb(dst, src); + else if(sizeof(bool) == 2) + movw(dst, src); + else if(sizeof(bool) == 4) + movl(dst, src); + else + // unsupported + ShouldNotReachHere(); +} + +void MacroAssembler::movbool(Address dst, bool boolconst) { + if(sizeof(bool) == 1) + movb(dst, (int) boolconst); + else if(sizeof(bool) == 2) + movw(dst, (int) boolconst); + else if(sizeof(bool) == 4) + movl(dst, (int) boolconst); + else + // unsupported + ShouldNotReachHere(); +} + +void MacroAssembler::movbool(Address dst, Register src) { + if(sizeof(bool) == 1) + movb(dst, src); + else if(sizeof(bool) == 2) + movw(dst, src); + else if(sizeof(bool) == 4) + movl(dst, src); + else + // unsupported + ShouldNotReachHere(); +} + +void MacroAssembler::movbyte(ArrayAddress dst, int src) { + movb(as_Address(dst), src); +} + +void MacroAssembler::movdbl(XMMRegister dst, AddressLiteral src) { + if (reachable(src)) { + if (UseXmmLoadAndClearUpper) { + movsd (dst, as_Address(src)); + } else { + movlpd(dst, as_Address(src)); + } + } else { + lea(rscratch1, src); + if (UseXmmLoadAndClearUpper) { + movsd (dst, Address(rscratch1, 0)); + } else { + movlpd(dst, Address(rscratch1, 0)); + } + } +} + +void MacroAssembler::movflt(XMMRegister dst, AddressLiteral src) { + if (reachable(src)) { + movss(dst, as_Address(src)); + } else { + lea(rscratch1, src); + movss(dst, Address(rscratch1, 0)); + } +} + +void MacroAssembler::movptr(Register dst, Register src) { + LP64_ONLY(movq(dst, src)) NOT_LP64(movl(dst, src)); +} + +void MacroAssembler::movptr(Register dst, Address src) { + LP64_ONLY(movq(dst, src)) NOT_LP64(movl(dst, src)); +} + +// src should NEVER be a real pointer. Use AddressLiteral for true pointers +void MacroAssembler::movptr(Register dst, intptr_t src) { + LP64_ONLY(mov64(dst, src)) NOT_LP64(movl(dst, src)); +} + +void MacroAssembler::movptr(Address dst, Register src) { + LP64_ONLY(movq(dst, src)) NOT_LP64(movl(dst, src)); +} + +void MacroAssembler::movss(XMMRegister dst, AddressLiteral src) { + if (reachable(src)) { + movss(dst, as_Address(src)); + } else { + lea(rscratch1, src); + movss(dst, Address(rscratch1, 0)); + } +} + +void MacroAssembler::null_check(Register reg, int offset) { + if (needs_explicit_null_check(offset)) { + // provoke OS NULL exception if reg = NULL by + // accessing M[reg] w/o changing any (non-CC) registers + // NOTE: cmpl is plenty here to provoke a segv + cmpptr(rax, Address(reg, 0)); + // Note: should probably use testl(rax, Address(reg, 0)); + // may be shorter code (however, this version of + // testl needs to be implemented first) + } else { + // nothing to do, (later) access of M[reg + offset] + // will provoke OS NULL exception if reg = NULL + } +} + +void MacroAssembler::os_breakpoint() { + // instead of directly emitting a breakpoint, call os:breakpoint for better debugability + // (e.g., MSVC can't call ps() otherwise) + call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint))); +} + +void MacroAssembler::pop_CPU_state() { + pop_FPU_state(); + pop_IU_state(); +} + +void MacroAssembler::pop_FPU_state() { + NOT_LP64(frstor(Address(rsp, 0));) + LP64_ONLY(fxrstor(Address(rsp, 0));) + addptr(rsp, FPUStateSizeInWords * wordSize); +} + +void MacroAssembler::pop_IU_state() { + popa(); + LP64_ONLY(addq(rsp, 8)); + popf(); +} + +// Save Integer and Float state +// Warning: Stack must be 16 byte aligned (64bit) +void MacroAssembler::push_CPU_state() { + push_IU_state(); + push_FPU_state(); +} + +void MacroAssembler::push_FPU_state() { + subptr(rsp, FPUStateSizeInWords * wordSize); +#ifndef _LP64 + fnsave(Address(rsp, 0)); + fwait(); +#else + fxsave(Address(rsp, 0)); +#endif // LP64 +} + +void MacroAssembler::push_IU_state() { + // Push flags first because pusha kills them + pushf(); + // Make sure rsp stays 16-byte aligned + LP64_ONLY(subq(rsp, 8)); + pusha(); +} + +void MacroAssembler::reset_last_Java_frame(Register java_thread, bool clear_fp, bool clear_pc) { + // determine java_thread register + if (!java_thread->is_valid()) { + java_thread = rdi; + get_thread(java_thread); + } + // we must set sp to zero to clear frame + movptr(Address(java_thread, JavaThread::last_Java_sp_offset()), (int32_t)NULL_WORD); + if (clear_fp) { + movptr(Address(java_thread, JavaThread::last_Java_fp_offset()), (int32_t)NULL_WORD); + } + + if (clear_pc) + movptr(Address(java_thread, JavaThread::last_Java_pc_offset()), (int32_t)NULL_WORD); + +} + +void MacroAssembler::restore_rax(Register tmp) { + if (tmp == noreg) pop(rax); + else if (tmp != rax) mov(rax, tmp); +} + +void MacroAssembler::round_to(Register reg, int modulus) { + addptr(reg, modulus - 1); + andptr(reg, -modulus); +} + +void MacroAssembler::save_rax(Register tmp) { + if (tmp == noreg) push(rax); + else if (tmp != rax) mov(tmp, rax); +} + +// Write serialization page so VM thread can do a pseudo remote membar. +// We use the current thread pointer to calculate a thread specific +// offset to write to within the page. This minimizes bus traffic +// due to cache line collision. +void MacroAssembler::serialize_memory(Register thread, Register tmp) { + movl(tmp, thread); + shrl(tmp, os::get_serialize_page_shift_count()); + andl(tmp, (os::vm_page_size() - sizeof(int))); + + Address index(noreg, tmp, Address::times_1); + ExternalAddress page(os::get_memory_serialize_page()); + + movptr(ArrayAddress(page, index), tmp); +} + +// Calls to C land +// +// When entering C land, the rbp, & rsp of the last Java frame have to be recorded +// in the (thread-local) JavaThread object. When leaving C land, the last Java fp +// has to be reset to 0. This is required to allow proper stack traversal. +void MacroAssembler::set_last_Java_frame(Register java_thread, + Register last_java_sp, + Register last_java_fp, + address last_java_pc) { + // determine java_thread register + if (!java_thread->is_valid()) { + java_thread = rdi; + get_thread(java_thread); + } + // determine last_java_sp register + if (!last_java_sp->is_valid()) { + last_java_sp = rsp; + } + + // last_java_fp is optional + + if (last_java_fp->is_valid()) { + movptr(Address(java_thread, JavaThread::last_Java_fp_offset()), last_java_fp); + } + + // last_java_pc is optional + + if (last_java_pc != NULL) { + lea(Address(java_thread, + JavaThread::frame_anchor_offset() + JavaFrameAnchor::last_Java_pc_offset()), + InternalAddress(last_java_pc)); + + } + movptr(Address(java_thread, JavaThread::last_Java_sp_offset()), last_java_sp); +} + +void MacroAssembler::shlptr(Register dst, int imm8) { + LP64_ONLY(shlq(dst, imm8)) NOT_LP64(shll(dst, imm8)); +} + +void MacroAssembler::shrptr(Register dst, int imm8) { + LP64_ONLY(shrq(dst, imm8)) NOT_LP64(shrl(dst, imm8)); +} + +void MacroAssembler::sign_extend_byte(Register reg) { + if (LP64_ONLY(true ||) (VM_Version::is_P6() && reg->has_byte_register())) { + movsbl(reg, reg); // movsxb + } else { + shll(reg, 24); + sarl(reg, 24); + } +} + +void MacroAssembler::sign_extend_short(Register reg) { + if (LP64_ONLY(true ||) VM_Version::is_P6()) { + movswl(reg, reg); // movsxw + } else { + shll(reg, 16); + sarl(reg, 16); + } +} + +void MacroAssembler::store_check(Register obj) { + // Does a store check for the oop in register obj. The content of + // register obj is destroyed afterwards. + store_check_part_1(obj); + store_check_part_2(obj); +} + +void MacroAssembler::store_check(Register obj, Address dst) { + store_check(obj); +} + + +// split the store check operation so that other instructions can be scheduled inbetween +void MacroAssembler::store_check_part_1(Register obj) { + BarrierSet* bs = Universe::heap()->barrier_set(); + assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind"); + shrptr(obj, CardTableModRefBS::card_shift); +} + +void MacroAssembler::store_check_part_2(Register obj) { + BarrierSet* bs = Universe::heap()->barrier_set(); + assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind"); + CardTableModRefBS* ct = (CardTableModRefBS*)bs; + assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); + + // The calculation for byte_map_base is as follows: + // byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift); + // So this essentially converts an address to a displacement and + // it will never need to be relocated. On 64bit however the value may be too + // large for a 32bit displacement + + intptr_t disp = (intptr_t) ct->byte_map_base; + if (is_simm32(disp)) { + Address cardtable(noreg, obj, Address::times_1, disp); + movb(cardtable, 0); + } else { + // By doing it as an ExternalAddress disp could be converted to a rip-relative + // displacement and done in a single instruction given favorable mapping and + // a smarter version of as_Address. Worst case it is two instructions which + // is no worse off then loading disp into a register and doing as a simple + // Address() as above. + // We can't do as ExternalAddress as the only style since if disp == 0 we'll + // assert since NULL isn't acceptable in a reloci (see 6644928). In any case + // in some cases we'll get a single instruction version. + + ExternalAddress cardtable((address)disp); + Address index(noreg, obj, Address::times_1); + movb(as_Address(ArrayAddress(cardtable, index)), 0); + } +} + +void MacroAssembler::subptr(Register dst, int32_t imm32) { + LP64_ONLY(subq(dst, imm32)) NOT_LP64(subl(dst, imm32)); +} + +void MacroAssembler::subptr(Register dst, Register src) { + LP64_ONLY(subq(dst, src)) NOT_LP64(subl(dst, src)); +} + +void MacroAssembler::test32(Register src1, AddressLiteral src2) { + // src2 must be rval + + if (reachable(src2)) { + testl(src1, as_Address(src2)); + } else { + lea(rscratch1, src2); + testl(src1, Address(rscratch1, 0)); + } +} + +// C++ bool manipulation +void MacroAssembler::testbool(Register dst) { + if(sizeof(bool) == 1) + testb(dst, 0xff); + else if(sizeof(bool) == 2) { + // testw implementation needed for two byte bools + ShouldNotReachHere(); + } else if(sizeof(bool) == 4) + testl(dst, dst); + else + // unsupported + ShouldNotReachHere(); +} + +void MacroAssembler::testptr(Register dst, Register src) { + LP64_ONLY(testq(dst, src)) NOT_LP64(testl(dst, src)); +} + +// Defines obj, preserves var_size_in_bytes, okay for t2 == var_size_in_bytes. +void MacroAssembler::tlab_allocate(Register obj, + Register var_size_in_bytes, + int con_size_in_bytes, + Register t1, + Register t2, + Label& slow_case) { + assert_different_registers(obj, t1, t2); + assert_different_registers(obj, var_size_in_bytes, t1); + Register end = t2; + Register thread = NOT_LP64(t1) LP64_ONLY(r15_thread); + + verify_tlab(); + + NOT_LP64(get_thread(thread)); + + movptr(obj, Address(thread, JavaThread::tlab_top_offset())); + if (var_size_in_bytes == noreg) { + lea(end, Address(obj, con_size_in_bytes)); + } else { + lea(end, Address(obj, var_size_in_bytes, Address::times_1)); + } + cmpptr(end, Address(thread, JavaThread::tlab_end_offset())); + jcc(Assembler::above, slow_case); + + // update the tlab top pointer + movptr(Address(thread, JavaThread::tlab_top_offset()), end); + + // recover var_size_in_bytes if necessary + if (var_size_in_bytes == end) { + subptr(var_size_in_bytes, obj); + } + verify_tlab(); +} + +// Preserves rbx, and rdx. +void MacroAssembler::tlab_refill(Label& retry, + Label& try_eden, + Label& slow_case) { + Register top = rax; + Register t1 = rcx; + Register t2 = rsi; + Register thread_reg = NOT_LP64(rdi) LP64_ONLY(r15_thread); + assert_different_registers(top, thread_reg, t1, t2, /* preserve: */ rbx, rdx); + Label do_refill, discard_tlab; + + if (CMSIncrementalMode || !Universe::heap()->supports_inline_contig_alloc()) { + // No allocation in the shared eden. + jmp(slow_case); + } + + NOT_LP64(get_thread(thread_reg)); + + movptr(top, Address(thread_reg, in_bytes(JavaThread::tlab_top_offset()))); + movptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_end_offset()))); + + // calculate amount of free space + subptr(t1, top); + shrptr(t1, LogHeapWordSize); + + // Retain tlab and allocate object in shared space if + // the amount free in the tlab is too large to discard. + cmpptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_refill_waste_limit_offset()))); + jcc(Assembler::lessEqual, discard_tlab); + + // Retain + // %%% yuck as movptr... + movptr(t2, (int32_t) ThreadLocalAllocBuffer::refill_waste_limit_increment()); + addptr(Address(thread_reg, in_bytes(JavaThread::tlab_refill_waste_limit_offset())), t2); + if (TLABStats) { + // increment number of slow_allocations + addl(Address(thread_reg, in_bytes(JavaThread::tlab_slow_allocations_offset())), 1); + } + jmp(try_eden); + + bind(discard_tlab); + if (TLABStats) { + // increment number of refills + addl(Address(thread_reg, in_bytes(JavaThread::tlab_number_of_refills_offset())), 1); + // accumulate wastage -- t1 is amount free in tlab + addl(Address(thread_reg, in_bytes(JavaThread::tlab_fast_refill_waste_offset())), t1); + } + + // if tlab is currently allocated (top or end != null) then + // fill [top, end + alignment_reserve) with array object + testptr (top, top); + jcc(Assembler::zero, do_refill); + + // set up the mark word + movptr(Address(top, oopDesc::mark_offset_in_bytes()), (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2)); + // set the length to the remaining space + subptr(t1, typeArrayOopDesc::header_size(T_INT)); + addptr(t1, (int32_t)ThreadLocalAllocBuffer::alignment_reserve()); + shlptr(t1, log2_intptr(HeapWordSize/sizeof(jint))); + movptr(Address(top, arrayOopDesc::length_offset_in_bytes()), t1); + // set klass to intArrayKlass + // dubious reloc why not an oop reloc? + movptr(t1, ExternalAddress((address) Universe::intArrayKlassObj_addr())); + // store klass last. concurrent gcs assumes klass length is valid if + // klass field is not null. + store_klass(top, t1); + + // refill the tlab with an eden allocation + bind(do_refill); + movptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset()))); + shlptr(t1, LogHeapWordSize); + // add object_size ?? + eden_allocate(top, t1, 0, t2, slow_case); + + // Check that t1 was preserved in eden_allocate. +#ifdef ASSERT + if (UseTLAB) { + Label ok; + Register tsize = rsi; + assert_different_registers(tsize, thread_reg, t1); + push(tsize); + movptr(tsize, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset()))); + shlptr(tsize, LogHeapWordSize); + cmpptr(t1, tsize); + jcc(Assembler::equal, ok); + stop("assert(t1 != tlab size)"); + should_not_reach_here(); + + bind(ok); + pop(tsize); + } +#endif + movptr(Address(thread_reg, in_bytes(JavaThread::tlab_start_offset())), top); + movptr(Address(thread_reg, in_bytes(JavaThread::tlab_top_offset())), top); + addptr(top, t1); + subptr(top, (int32_t)ThreadLocalAllocBuffer::alignment_reserve_in_bytes()); + movptr(Address(thread_reg, in_bytes(JavaThread::tlab_end_offset())), top); + verify_tlab(); + jmp(retry); +} + +static const double pi_4 = 0.7853981633974483; + +void MacroAssembler::trigfunc(char trig, int num_fpu_regs_in_use) { + // A hand-coded argument reduction for values in fabs(pi/4, pi/2) + // was attempted in this code; unfortunately it appears that the + // switch to 80-bit precision and back causes this to be + // unprofitable compared with simply performing a runtime call if + // the argument is out of the (-pi/4, pi/4) range. + + Register tmp = noreg; + if (!VM_Version::supports_cmov()) { + // fcmp needs a temporary so preserve rbx, + tmp = rbx; + push(tmp); + } + + Label slow_case, done; + + // x ?<= pi/4 + fld_d(ExternalAddress((address)&pi_4)); + fld_s(1); // Stack: X PI/4 X + fabs(); // Stack: |X| PI/4 X + fcmp(tmp); + jcc(Assembler::above, slow_case); + + // fastest case: -pi/4 <= x <= pi/4 + switch(trig) { + case 's': + fsin(); + break; + case 'c': + fcos(); + break; + case 't': + ftan(); + break; + default: + assert(false, "bad intrinsic"); + break; + } + jmp(done); + + // slow case: runtime call + bind(slow_case); + // Preserve registers across runtime call + pusha(); + int incoming_argument_and_return_value_offset = -1; + if (num_fpu_regs_in_use > 1) { + // Must preserve all other FPU regs (could alternatively convert + // SharedRuntime::dsin and dcos into assembly routines known not to trash + // FPU state, but can not trust C compiler) + NEEDS_CLEANUP; + // NOTE that in this case we also push the incoming argument to + // the stack and restore it later; we also use this stack slot to + // hold the return value from dsin or dcos. + for (int i = 0; i < num_fpu_regs_in_use; i++) { + subptr(rsp, sizeof(jdouble)); + fstp_d(Address(rsp, 0)); + } + incoming_argument_and_return_value_offset = sizeof(jdouble)*(num_fpu_regs_in_use-1); + fld_d(Address(rsp, incoming_argument_and_return_value_offset)); + } + subptr(rsp, sizeof(jdouble)); + fstp_d(Address(rsp, 0)); +#ifdef _LP64 + movdbl(xmm0, Address(rsp, 0)); +#endif // _LP64 + + // NOTE: we must not use call_VM_leaf here because that requires a + // complete interpreter frame in debug mode -- same bug as 4387334 + // MacroAssembler::call_VM_leaf_base is perfectly safe and will + // do proper 64bit abi + + NEEDS_CLEANUP; + // Need to add stack banging before this runtime call if it needs to + // be taken; however, there is no generic stack banging routine at + // the MacroAssembler level + switch(trig) { + case 's': + { + MacroAssembler::call_VM_leaf_base(CAST_FROM_FN_PTR(address, SharedRuntime::dsin), 0); + } + break; + case 'c': + { + MacroAssembler::call_VM_leaf_base(CAST_FROM_FN_PTR(address, SharedRuntime::dcos), 0); + } + break; + case 't': + { + MacroAssembler::call_VM_leaf_base(CAST_FROM_FN_PTR(address, SharedRuntime::dtan), 0); + } + break; + default: + assert(false, "bad intrinsic"); + break; + } +#ifdef _LP64 + movsd(Address(rsp, 0), xmm0); + fld_d(Address(rsp, 0)); +#endif // _LP64 + addptr(rsp, sizeof(jdouble)); + if (num_fpu_regs_in_use > 1) { + // Must save return value to stack and then restore entire FPU stack + fstp_d(Address(rsp, incoming_argument_and_return_value_offset)); + for (int i = 0; i < num_fpu_regs_in_use; i++) { + fld_d(Address(rsp, 0)); + addptr(rsp, sizeof(jdouble)); + } + } + popa(); + + // Come here with result in F-TOS + bind(done); + + if (tmp != noreg) { + pop(tmp); + } +} + + +void MacroAssembler::ucomisd(XMMRegister dst, AddressLiteral src) { + ucomisd(dst, as_Address(src)); +} + +void MacroAssembler::ucomiss(XMMRegister dst, AddressLiteral src) { + ucomiss(dst, as_Address(src)); +} + +void MacroAssembler::xorpd(XMMRegister dst, AddressLiteral src) { + if (reachable(src)) { + xorpd(dst, as_Address(src)); + } else { + lea(rscratch1, src); + xorpd(dst, Address(rscratch1, 0)); + } +} + +void MacroAssembler::xorps(XMMRegister dst, AddressLiteral src) { + if (reachable(src)) { + xorps(dst, as_Address(src)); + } else { + lea(rscratch1, src); + xorps(dst, Address(rscratch1, 0)); + } +} + +void MacroAssembler::verify_oop(Register reg, const char* s) { + if (!VerifyOops) return; + + // Pass register number to verify_oop_subroutine + char* b = new char[strlen(s) + 50]; + sprintf(b, "verify_oop: %s: %s", reg->name(), s); + push(rax); // save rax, + push(reg); // pass register argument + ExternalAddress buffer((address) b); + // avoid using pushptr, as it modifies scratch registers + // and our contract is not to modify anything + movptr(rax, buffer.addr()); + push(rax); + // call indirectly to solve generation ordering problem + movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address())); + call(rax); +} + + +void MacroAssembler::verify_oop_addr(Address addr, const char* s) { + if (!VerifyOops) return; + + // Address adjust(addr.base(), addr.index(), addr.scale(), addr.disp() + BytesPerWord); + // Pass register number to verify_oop_subroutine + char* b = new char[strlen(s) + 50]; + sprintf(b, "verify_oop_addr: %s", s); + + push(rax); // save rax, + // addr may contain rsp so we will have to adjust it based on the push + // we just did + // NOTE: 64bit seemed to have had a bug in that it did movq(addr, rax); which + // stores rax into addr which is backwards of what was intended. + if (addr.uses(rsp)) { + lea(rax, addr); + pushptr(Address(rax, BytesPerWord)); + } else { + pushptr(addr); + } + + ExternalAddress buffer((address) b); + // pass msg argument + // avoid using pushptr, as it modifies scratch registers + // and our contract is not to modify anything + movptr(rax, buffer.addr()); + push(rax); + + // call indirectly to solve generation ordering problem + movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address())); + call(rax); + // Caller pops the arguments and restores rax, from the stack +} + +void MacroAssembler::verify_tlab() { +#ifdef ASSERT + if (UseTLAB && VerifyOops) { + Label next, ok; + Register t1 = rsi; + Register thread_reg = NOT_LP64(rbx) LP64_ONLY(r15_thread); + + push(t1); + NOT_LP64(push(thread_reg)); + NOT_LP64(get_thread(thread_reg)); + + movptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_top_offset()))); + cmpptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_start_offset()))); + jcc(Assembler::aboveEqual, next); + stop("assert(top >= start)"); + should_not_reach_here(); + + bind(next); + movptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_end_offset()))); + cmpptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_top_offset()))); + jcc(Assembler::aboveEqual, ok); + stop("assert(top <= end)"); + should_not_reach_here(); + + bind(ok); + NOT_LP64(pop(thread_reg)); + pop(t1); + } +#endif +} + +class ControlWord { + public: + int32_t _value; + + int rounding_control() const { return (_value >> 10) & 3 ; } + int precision_control() const { return (_value >> 8) & 3 ; } + bool precision() const { return ((_value >> 5) & 1) != 0; } + bool underflow() const { return ((_value >> 4) & 1) != 0; } + bool overflow() const { return ((_value >> 3) & 1) != 0; } + bool zero_divide() const { return ((_value >> 2) & 1) != 0; } + bool denormalized() const { return ((_value >> 1) & 1) != 0; } + bool invalid() const { return ((_value >> 0) & 1) != 0; } + + void print() const { + // rounding control + const char* rc; + switch (rounding_control()) { + case 0: rc = "round near"; break; + case 1: rc = "round down"; break; + case 2: rc = "round up "; break; + case 3: rc = "chop "; break; + }; + // precision control + const char* pc; + switch (precision_control()) { + case 0: pc = "24 bits "; break; + case 1: pc = "reserved"; break; + case 2: pc = "53 bits "; break; + case 3: pc = "64 bits "; break; + }; + // flags + char f[9]; + f[0] = ' '; + f[1] = ' '; + f[2] = (precision ()) ? 'P' : 'p'; + f[3] = (underflow ()) ? 'U' : 'u'; + f[4] = (overflow ()) ? 'O' : 'o'; + f[5] = (zero_divide ()) ? 'Z' : 'z'; + f[6] = (denormalized()) ? 'D' : 'd'; + f[7] = (invalid ()) ? 'I' : 'i'; + f[8] = '\x0'; + // output + printf("%04x masks = %s, %s, %s", _value & 0xFFFF, f, rc, pc); + } + +}; + +class StatusWord { + public: + int32_t _value; + + bool busy() const { return ((_value >> 15) & 1) != 0; } + bool C3() const { return ((_value >> 14) & 1) != 0; } + bool C2() const { return ((_value >> 10) & 1) != 0; } + bool C1() const { return ((_value >> 9) & 1) != 0; } + bool C0() const { return ((_value >> 8) & 1) != 0; } + int top() const { return (_value >> 11) & 7 ; } + bool error_status() const { return ((_value >> 7) & 1) != 0; } + bool stack_fault() const { return ((_value >> 6) & 1) != 0; } + bool precision() const { return ((_value >> 5) & 1) != 0; } + bool underflow() const { return ((_value >> 4) & 1) != 0; } + bool overflow() const { return ((_value >> 3) & 1) != 0; } + bool zero_divide() const { return ((_value >> 2) & 1) != 0; } + bool denormalized() const { return ((_value >> 1) & 1) != 0; } + bool invalid() const { return ((_value >> 0) & 1) != 0; } + + void print() const { + // condition codes + char c[5]; + c[0] = (C3()) ? '3' : '-'; + c[1] = (C2()) ? '2' : '-'; + c[2] = (C1()) ? '1' : '-'; + c[3] = (C0()) ? '0' : '-'; + c[4] = '\x0'; + // flags + char f[9]; + f[0] = (error_status()) ? 'E' : '-'; + f[1] = (stack_fault ()) ? 'S' : '-'; + f[2] = (precision ()) ? 'P' : '-'; + f[3] = (underflow ()) ? 'U' : '-'; + f[4] = (overflow ()) ? 'O' : '-'; + f[5] = (zero_divide ()) ? 'Z' : '-'; + f[6] = (denormalized()) ? 'D' : '-'; + f[7] = (invalid ()) ? 'I' : '-'; + f[8] = '\x0'; + // output + printf("%04x flags = %s, cc = %s, top = %d", _value & 0xFFFF, f, c, top()); + } + +}; + +class TagWord { + public: + int32_t _value; + + int tag_at(int i) const { return (_value >> (i*2)) & 3; } + + void print() const { + printf("%04x", _value & 0xFFFF); + } + +}; + +class FPU_Register { + public: + int32_t _m0; + int32_t _m1; + int16_t _ex; + + bool is_indefinite() const { + return _ex == -1 && _m1 == (int32_t)0xC0000000 && _m0 == 0; + } + + void print() const { + char sign = (_ex < 0) ? '-' : '+'; + const char* kind = (_ex == 0x7FFF || _ex == (int16_t)-1) ? "NaN" : " "; + printf("%c%04hx.%08x%08x %s", sign, _ex, _m1, _m0, kind); + }; + +}; + +class FPU_State { + public: + enum { + register_size = 10, + number_of_registers = 8, + register_mask = 7 + }; + + ControlWord _control_word; + StatusWord _status_word; + TagWord _tag_word; + int32_t _error_offset; + int32_t _error_selector; + int32_t _data_offset; + int32_t _data_selector; + int8_t _register[register_size * number_of_registers]; + + int tag_for_st(int i) const { return _tag_word.tag_at((_status_word.top() + i) & register_mask); } + FPU_Register* st(int i) const { return (FPU_Register*)&_register[register_size * i]; } + + const char* tag_as_string(int tag) const { + switch (tag) { + case 0: return "valid"; + case 1: return "zero"; + case 2: return "special"; + case 3: return "empty"; + } + ShouldNotReachHere() + return NULL; + } + + void print() const { + // print computation registers + { int t = _status_word.top(); + for (int i = 0; i < number_of_registers; i++) { + int j = (i - t) & register_mask; + printf("%c r%d = ST%d = ", (j == 0 ? '*' : ' '), i, j); + st(j)->print(); + printf(" %s\n", tag_as_string(_tag_word.tag_at(i))); + } + } + printf("\n"); + // print control registers + printf("ctrl = "); _control_word.print(); printf("\n"); + printf("stat = "); _status_word .print(); printf("\n"); + printf("tags = "); _tag_word .print(); printf("\n"); + } + +}; + +class Flag_Register { + public: + int32_t _value; + + bool overflow() const { return ((_value >> 11) & 1) != 0; } + bool direction() const { return ((_value >> 10) & 1) != 0; } + bool sign() const { return ((_value >> 7) & 1) != 0; } + bool zero() const { return ((_value >> 6) & 1) != 0; } + bool auxiliary_carry() const { return ((_value >> 4) & 1) != 0; } + bool parity() const { return ((_value >> 2) & 1) != 0; } + bool carry() const { return ((_value >> 0) & 1) != 0; } + + void print() const { + // flags + char f[8]; + f[0] = (overflow ()) ? 'O' : '-'; + f[1] = (direction ()) ? 'D' : '-'; + f[2] = (sign ()) ? 'S' : '-'; + f[3] = (zero ()) ? 'Z' : '-'; + f[4] = (auxiliary_carry()) ? 'A' : '-'; + f[5] = (parity ()) ? 'P' : '-'; + f[6] = (carry ()) ? 'C' : '-'; + f[7] = '\x0'; + // output + printf("%08x flags = %s", _value, f); + } + +}; + +class IU_Register { + public: + int32_t _value; + + void print() const { + printf("%08x %11d", _value, _value); + } + +}; + +class IU_State { + public: + Flag_Register _eflags; + IU_Register _rdi; + IU_Register _rsi; + IU_Register _rbp; + IU_Register _rsp; + IU_Register _rbx; + IU_Register _rdx; + IU_Register _rcx; + IU_Register _rax; + + void print() const { + // computation registers + printf("rax, = "); _rax.print(); printf("\n"); + printf("rbx, = "); _rbx.print(); printf("\n"); + printf("rcx = "); _rcx.print(); printf("\n"); + printf("rdx = "); _rdx.print(); printf("\n"); + printf("rdi = "); _rdi.print(); printf("\n"); + printf("rsi = "); _rsi.print(); printf("\n"); + printf("rbp, = "); _rbp.print(); printf("\n"); + printf("rsp = "); _rsp.print(); printf("\n"); + printf("\n"); + // control registers + printf("flgs = "); _eflags.print(); printf("\n"); + } +}; + + +class CPU_State { + public: + FPU_State _fpu_state; + IU_State _iu_state; + + void print() const { + printf("--------------------------------------------------\n"); + _iu_state .print(); + printf("\n"); + _fpu_state.print(); + printf("--------------------------------------------------\n"); + } + +}; + + +static void _print_CPU_state(CPU_State* state) { + state->print(); +}; + + +void MacroAssembler::print_CPU_state() { + push_CPU_state(); + push(rsp); // pass CPU state + call(RuntimeAddress(CAST_FROM_FN_PTR(address, _print_CPU_state))); + addptr(rsp, wordSize); // discard argument + pop_CPU_state(); +} + + +static bool _verify_FPU(int stack_depth, char* s, CPU_State* state) { + static int counter = 0; + FPU_State* fs = &state->_fpu_state; + counter++; + // For leaf calls, only verify that the top few elements remain empty. + // We only need 1 empty at the top for C2 code. + if( stack_depth < 0 ) { + if( fs->tag_for_st(7) != 3 ) { + printf("FPR7 not empty\n"); + state->print(); + assert(false, "error"); + return false; + } + return true; // All other stack states do not matter + } + + assert((fs->_control_word._value & 0xffff) == StubRoutines::_fpu_cntrl_wrd_std, + "bad FPU control word"); + + // compute stack depth + int i = 0; + while (i < FPU_State::number_of_registers && fs->tag_for_st(i) < 3) i++; + int d = i; + while (i < FPU_State::number_of_registers && fs->tag_for_st(i) == 3) i++; + // verify findings + if (i != FPU_State::number_of_registers) { + // stack not contiguous + printf("%s: stack not contiguous at ST%d\n", s, i); + state->print(); + assert(false, "error"); + return false; + } + // check if computed stack depth corresponds to expected stack depth + if (stack_depth < 0) { + // expected stack depth is -stack_depth or less + if (d > -stack_depth) { + // too many elements on the stack + printf("%s: <= %d stack elements expected but found %d\n", s, -stack_depth, d); + state->print(); + assert(false, "error"); + return false; + } + } else { + // expected stack depth is stack_depth + if (d != stack_depth) { + // wrong stack depth + printf("%s: %d stack elements expected but found %d\n", s, stack_depth, d); + state->print(); + assert(false, "error"); + return false; + } + } + // everything is cool + return true; +} + + +void MacroAssembler::verify_FPU(int stack_depth, const char* s) { + if (!VerifyFPU) return; + push_CPU_state(); + push(rsp); // pass CPU state + ExternalAddress msg((address) s); + // pass message string s + pushptr(msg.addr()); + push(stack_depth); // pass stack depth + call(RuntimeAddress(CAST_FROM_FN_PTR(address, _verify_FPU))); + addptr(rsp, 3 * wordSize); // discard arguments + // check for error + { Label L; + testl(rax, rax); + jcc(Assembler::notZero, L); + int3(); // break if error condition + bind(L); + } + pop_CPU_state(); +} void MacroAssembler::load_klass(Register dst, Register src) { +#ifdef _LP64 if (UseCompressedOops) { movl(dst, Address(src, oopDesc::klass_offset_in_bytes())); decode_heap_oop_not_null(dst); - } else { - movq(dst, Address(src, oopDesc::klass_offset_in_bytes())); - } + } else +#endif + movptr(dst, Address(src, oopDesc::klass_offset_in_bytes())); } void MacroAssembler::load_prototype_header(Register dst, Register src) { +#ifdef _LP64 if (UseCompressedOops) { movl(dst, Address(src, oopDesc::klass_offset_in_bytes())); movq(dst, Address(r12_heapbase, dst, Address::times_8, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); - } else { - movq(dst, Address(src, oopDesc::klass_offset_in_bytes())); - movq(dst, Address(dst, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); - } + } else +#endif + { + movptr(dst, Address(src, oopDesc::klass_offset_in_bytes())); + movptr(dst, Address(dst, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + } } void MacroAssembler::store_klass(Register dst, Register src) { +#ifdef _LP64 if (UseCompressedOops) { encode_heap_oop_not_null(src); movl(Address(dst, oopDesc::klass_offset_in_bytes()), src); - } else { - movq(Address(dst, oopDesc::klass_offset_in_bytes()), src); - } + } else +#endif + movptr(Address(dst, oopDesc::klass_offset_in_bytes()), src); } +#ifdef _LP64 void MacroAssembler::store_klass_gap(Register dst, Register src) { if (UseCompressedOops) { // Store to klass gap in destination @@ -5206,12 +7357,12 @@ void MacroAssembler::encode_heap_oop(Register r) { #ifdef ASSERT if (CheckCompressedOops) { Label ok; - pushq(rscratch1); // cmpptr trashes rscratch1 + push(rscratch1); // cmpptr trashes rscratch1 cmpptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr())); jcc(Assembler::equal, ok); stop("MacroAssembler::encode_heap_oop: heap base corrupted?"); bind(ok); - popq(rscratch1); + pop(rscratch1); } #endif verify_oop(r, "broken oop in encode_heap_oop"); @@ -5261,13 +7412,13 @@ void MacroAssembler::decode_heap_oop(Register r) { #ifdef ASSERT if (CheckCompressedOops) { Label ok; - pushq(rscratch1); + push(rscratch1); cmpptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr())); jcc(Assembler::equal, ok); stop("MacroAssembler::decode_heap_oop: heap base corrupted?"); bind(ok); - popq(rscratch1); + pop(rscratch1); } #endif @@ -5307,14 +7458,15 @@ void MacroAssembler::set_narrow_oop(Register dst, jobject obj) { assert(oop_recorder() != NULL, "this assembler needs an OopRecorder"); int oop_index = oop_recorder()->find_index(obj); RelocationHolder rspec = oop_Relocation::spec(oop_index); - - // movl dst,obj - InstructionMark im(this); - int encode = prefix_and_encode(dst->encoding()); - emit_byte(0xB8 | encode); - emit_data(oop_index, rspec, narrow_oop_operand); + mov_literal32(dst, oop_index, rspec, narrow_oop_operand); } +void MacroAssembler::reinit_heapbase() { + if (UseCompressedOops) { + movptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr())); + } +} +#endif // _LP64 Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) { switch (cond) { @@ -5339,23 +7491,6 @@ Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) ShouldNotReachHere(); return Assembler::overflow; } - -void MacroAssembler::cond_inc32(Condition cond, AddressLiteral counter_addr) { - Condition negated_cond = negate_condition(cond); - Label L; - jcc(negated_cond, L); - atomic_incl(counter_addr); - bind(L); -} - -void MacroAssembler::atomic_incl(AddressLiteral counter_addr) { - pushfq(); - if (os::is_MP()) - lock(); - incrementl(counter_addr); - popfq(); -} - SkipIfEqual::SkipIfEqual( MacroAssembler* masm, const bool* flag_addr, bool value) { _masm = masm; @@ -5366,28 +7501,3 @@ SkipIfEqual::SkipIfEqual( SkipIfEqual::~SkipIfEqual() { _masm->bind(_label); } - -void MacroAssembler::bang_stack_size(Register size, Register tmp) { - movq(tmp, rsp); - // Bang stack for total size given plus shadow page size. - // Bang one page at a time because large size can bang beyond yellow and - // red zones. - Label loop; - bind(loop); - movl(Address(tmp, (-os::vm_page_size())), size ); - subq(tmp, os::vm_page_size()); - subl(size, os::vm_page_size()); - jcc(Assembler::greater, loop); - - // Bang down shadow pages too. - // The -1 because we already subtracted 1 page. - for (int i = 0; i< StackShadowPages-1; i++) { - movq(Address(tmp, (-i*os::vm_page_size())), size ); - } -} - -void MacroAssembler::reinit_heapbase() { - if (UseCompressedOops) { - movptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr())); - } -} diff --git a/hotspot/src/cpu/x86/vm/assembler_x86_32.hpp b/hotspot/src/cpu/x86/vm/assembler_x86.hpp similarity index 63% rename from hotspot/src/cpu/x86/vm/assembler_x86_32.hpp rename to hotspot/src/cpu/x86/vm/assembler_x86.hpp index 9588449955c..d9637ffc9e2 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86_32.hpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp @@ -58,10 +58,10 @@ REGISTER_DECLARATION(Register, c_rarg1, rdx); REGISTER_DECLARATION(Register, c_rarg2, r8); REGISTER_DECLARATION(Register, c_rarg3, r9); -REGISTER_DECLARATION(FloatRegister, c_farg0, xmm0); -REGISTER_DECLARATION(FloatRegister, c_farg1, xmm1); -REGISTER_DECLARATION(FloatRegister, c_farg2, xmm2); -REGISTER_DECLARATION(FloatRegister, c_farg3, xmm3); +REGISTER_DECLARATION(XMMRegister, c_farg0, xmm0); +REGISTER_DECLARATION(XMMRegister, c_farg1, xmm1); +REGISTER_DECLARATION(XMMRegister, c_farg2, xmm2); +REGISTER_DECLARATION(XMMRegister, c_farg3, xmm3); #else @@ -72,14 +72,14 @@ REGISTER_DECLARATION(Register, c_rarg3, rcx); REGISTER_DECLARATION(Register, c_rarg4, r8); REGISTER_DECLARATION(Register, c_rarg5, r9); -REGISTER_DECLARATION(FloatRegister, c_farg0, xmm0); -REGISTER_DECLARATION(FloatRegister, c_farg1, xmm1); -REGISTER_DECLARATION(FloatRegister, c_farg2, xmm2); -REGISTER_DECLARATION(FloatRegister, c_farg3, xmm3); -REGISTER_DECLARATION(FloatRegister, c_farg4, xmm4); -REGISTER_DECLARATION(FloatRegister, c_farg5, xmm5); -REGISTER_DECLARATION(FloatRegister, c_farg6, xmm6); -REGISTER_DECLARATION(FloatRegister, c_farg7, xmm7); +REGISTER_DECLARATION(XMMRegister, c_farg0, xmm0); +REGISTER_DECLARATION(XMMRegister, c_farg1, xmm1); +REGISTER_DECLARATION(XMMRegister, c_farg2, xmm2); +REGISTER_DECLARATION(XMMRegister, c_farg3, xmm3); +REGISTER_DECLARATION(XMMRegister, c_farg4, xmm4); +REGISTER_DECLARATION(XMMRegister, c_farg5, xmm5); +REGISTER_DECLARATION(XMMRegister, c_farg6, xmm6); +REGISTER_DECLARATION(XMMRegister, c_farg7, xmm7); #endif // _WIN64 @@ -112,20 +112,27 @@ REGISTER_DECLARATION(Register, j_rarg4, c_rarg5); #endif /* _WIN64 */ REGISTER_DECLARATION(Register, j_rarg5, c_rarg0); -REGISTER_DECLARATION(FloatRegister, j_farg0, xmm0); -REGISTER_DECLARATION(FloatRegister, j_farg1, xmm1); -REGISTER_DECLARATION(FloatRegister, j_farg2, xmm2); -REGISTER_DECLARATION(FloatRegister, j_farg3, xmm3); -REGISTER_DECLARATION(FloatRegister, j_farg4, xmm4); -REGISTER_DECLARATION(FloatRegister, j_farg5, xmm5); -REGISTER_DECLARATION(FloatRegister, j_farg6, xmm6); -REGISTER_DECLARATION(FloatRegister, j_farg7, xmm7); +REGISTER_DECLARATION(XMMRegister, j_farg0, xmm0); +REGISTER_DECLARATION(XMMRegister, j_farg1, xmm1); +REGISTER_DECLARATION(XMMRegister, j_farg2, xmm2); +REGISTER_DECLARATION(XMMRegister, j_farg3, xmm3); +REGISTER_DECLARATION(XMMRegister, j_farg4, xmm4); +REGISTER_DECLARATION(XMMRegister, j_farg5, xmm5); +REGISTER_DECLARATION(XMMRegister, j_farg6, xmm6); +REGISTER_DECLARATION(XMMRegister, j_farg7, xmm7); REGISTER_DECLARATION(Register, rscratch1, r10); // volatile REGISTER_DECLARATION(Register, rscratch2, r11); // volatile +REGISTER_DECLARATION(Register, r12_heapbase, r12); // callee-saved REGISTER_DECLARATION(Register, r15_thread, r15); // callee-saved +#else +// rscratch1 will apear in 32bit code that is dead but of course must compile +// Using noreg ensures if the dead code is incorrectly live and executed it +// will cause an assertion failure +#define rscratch1 noreg + #endif // _LP64 // Address is an abstraction used to represent a memory location @@ -143,7 +150,8 @@ class Address VALUE_OBJ_CLASS_SPEC { times_1 = 0, times_2 = 1, times_4 = 2, - times_8 = 3 + times_8 = 3, + times_ptr = LP64_ONLY(times_8) NOT_LP64(times_4) }; private: @@ -153,12 +161,15 @@ class Address VALUE_OBJ_CLASS_SPEC { int _disp; RelocationHolder _rspec; - // Easily misused constructor make them private -#ifndef _LP64 - Address(address loc, RelocationHolder spec); -#endif // _LP64 + // Easily misused constructors make them private + // %%% can we make these go away? + NOT_LP64(Address(address loc, RelocationHolder spec);) + Address(int disp, address loc, relocInfo::relocType rtype); + Address(int disp, address loc, RelocationHolder spec); public: + + int disp() { return _disp; } // creation Address() : _base(noreg), @@ -358,11 +369,7 @@ class ArrayAddress VALUE_OBJ_CLASS_SPEC { }; -#ifndef _LP64 -const int FPUStateSizeInWords = 27; -#else -const int FPUStateSizeInWords = 512 / wordSize; -#endif // _LP64 +const int FPUStateSizeInWords = NOT_LP64(27) LP64_ONLY( 512 / wordSize); // The Intel x86/Amd64 Assembler: Pure assembler doing NO optimizations on the instruction // level (e.g. mov rax, 0 is not translated into xor rax, rax!); i.e., what you write @@ -371,62 +378,7 @@ const int FPUStateSizeInWords = 512 / wordSize; class Assembler : public AbstractAssembler { friend class AbstractAssembler; // for the non-virtual hack friend class LIR_Assembler; // as_Address() - - protected: - #ifdef ASSERT - void check_relocation(RelocationHolder const& rspec, int format); - #endif - - inline void emit_long64(jlong x); - - void emit_data(jint data, relocInfo::relocType rtype, int format /* = 0 */); - void emit_data(jint data, RelocationHolder const& rspec, int format /* = 0 */); - void emit_data64(jlong data, relocInfo::relocType rtype, int format = 0); - void emit_data64(jlong data, RelocationHolder const& rspec, int format = 0); - - // Helper functions for groups of instructions - void emit_arith_b(int op1, int op2, Register dst, int imm8); - - void emit_arith(int op1, int op2, Register dst, int imm32); - // only x86?? - void emit_arith(int op1, int op2, Register dst, jobject obj); - void emit_arith(int op1, int op2, Register dst, Register src); - - void emit_operand(Register reg, - Register base, Register index, Address::ScaleFactor scale, - int disp, - RelocationHolder const& rspec); - void emit_operand(Register reg, Address adr); - - // Immediate-to-memory forms - void emit_arith_operand(int op1, Register rm, Address adr, int imm32); - - void emit_farith(int b1, int b2, int i); - - // macroassembler?? QQQ - bool reachable(AddressLiteral adr) { return true; } - - // These are all easily abused and hence protected - - // Make these disappear in 64bit mode since they would never be correct -#ifndef _LP64 - void cmp_literal32(Register src1, int32_t imm32, RelocationHolder const& rspec); - void cmp_literal32(Address src1, int32_t imm32, RelocationHolder const& rspec); - - void mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec); - void mov_literal32(Address dst, int32_t imm32, RelocationHolder const& rspec); - - void push_literal32(int32_t imm32, RelocationHolder const& rspec); -#endif // _LP64 - - // These are unique in that we are ensured by the caller that the 32bit - // relative in these instructions will always be able to reach the potentially - // 64bit address described by entry. Since they can take a 64bit address they - // don't have the 32 suffix like the other instructions in this class. - - void call_literal(address entry, RelocationHolder const& rspec); - void jmp_literal(address entry, RelocationHolder const& rspec); - + friend class StubGenerator; public: enum Condition { // The x86 condition codes used for conditional jumps/moves. @@ -484,12 +436,177 @@ class Assembler : public AbstractAssembler { enum WhichOperand { // input to locate_operand, and format code for relocations - imm32_operand = 0, // embedded 32-bit immediate operand + imm_operand = 0, // embedded 32-bit|64-bit immediate operand disp32_operand = 1, // embedded 32-bit displacement or address call32_operand = 2, // embedded 32-bit self-relative displacement +#ifndef _LP64 _WhichOperand_limit = 3 +#else + narrow_oop_operand = 3, // embedded 32-bit immediate narrow oop + _WhichOperand_limit = 4 +#endif }; + + + // NOTE: The general philopsophy of the declarations here is that 64bit versions + // of instructions are freely declared without the need for wrapping them an ifdef. + // (Some dangerous instructions are ifdef's out of inappropriate jvm's.) + // In the .cpp file the implementations are wrapped so that they are dropped out + // of the resulting jvm. This is done mostly to keep the footprint of KERNEL + // to the size it was prior to merging up the 32bit and 64bit assemblers. + // + // This does mean you'll get a linker/runtime error if you use a 64bit only instruction + // in a 32bit vm. This is somewhat unfortunate but keeps the ifdef noise down. + +private: + + + // 64bit prefixes + int prefix_and_encode(int reg_enc, bool byteinst = false); + int prefixq_and_encode(int reg_enc); + + int prefix_and_encode(int dst_enc, int src_enc, bool byteinst = false); + int prefixq_and_encode(int dst_enc, int src_enc); + + void prefix(Register reg); + void prefix(Address adr); + void prefixq(Address adr); + + void prefix(Address adr, Register reg, bool byteinst = false); + void prefixq(Address adr, Register reg); + + void prefix(Address adr, XMMRegister reg); + + void prefetch_prefix(Address src); + + // Helper functions for groups of instructions + void emit_arith_b(int op1, int op2, Register dst, int imm8); + + void emit_arith(int op1, int op2, Register dst, int32_t imm32); + // only 32bit?? + void emit_arith(int op1, int op2, Register dst, jobject obj); + void emit_arith(int op1, int op2, Register dst, Register src); + + void emit_operand(Register reg, + Register base, Register index, Address::ScaleFactor scale, + int disp, + RelocationHolder const& rspec, + int rip_relative_correction = 0); + + void emit_operand(Register reg, Address adr, int rip_relative_correction = 0); + + // operands that only take the original 32bit registers + void emit_operand32(Register reg, Address adr); + + void emit_operand(XMMRegister reg, + Register base, Register index, Address::ScaleFactor scale, + int disp, + RelocationHolder const& rspec); + + void emit_operand(XMMRegister reg, Address adr); + + void emit_operand(MMXRegister reg, Address adr); + + // workaround gcc (3.2.1-7) bug + void emit_operand(Address adr, MMXRegister reg); + + + // Immediate-to-memory forms + void emit_arith_operand(int op1, Register rm, Address adr, int32_t imm32); + + void emit_farith(int b1, int b2, int i); + + + protected: + #ifdef ASSERT + void check_relocation(RelocationHolder const& rspec, int format); + #endif + + inline void emit_long64(jlong x); + + void emit_data(jint data, relocInfo::relocType rtype, int format); + void emit_data(jint data, RelocationHolder const& rspec, int format); + void emit_data64(jlong data, relocInfo::relocType rtype, int format = 0); + void emit_data64(jlong data, RelocationHolder const& rspec, int format = 0); + + + bool reachable(AddressLiteral adr) NOT_LP64({ return true;}); + + // These are all easily abused and hence protected + + void mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec, int format = 0); + + // 32BIT ONLY SECTION +#ifndef _LP64 + // Make these disappear in 64bit mode since they would never be correct + void cmp_literal32(Register src1, int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY + void cmp_literal32(Address src1, int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY + + void mov_literal32(Address dst, int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY + + void push_literal32(int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY +#else + // 64BIT ONLY SECTION + void mov_literal64(Register dst, intptr_t imm64, RelocationHolder const& rspec); // 64BIT ONLY +#endif // _LP64 + + // These are unique in that we are ensured by the caller that the 32bit + // relative in these instructions will always be able to reach the potentially + // 64bit address described by entry. Since they can take a 64bit address they + // don't have the 32 suffix like the other instructions in this class. + + void call_literal(address entry, RelocationHolder const& rspec); + void jmp_literal(address entry, RelocationHolder const& rspec); + + // Avoid using directly section + // Instructions in this section are actually usable by anyone without danger + // of failure but have performance issues that are addressed my enhanced + // instructions which will do the proper thing base on the particular cpu. + // We protect them because we don't trust you... + + // Don't use next inc() and dec() methods directly. INC & DEC instructions + // could cause a partial flag stall since they don't set CF flag. + // Use MacroAssembler::decrement() & MacroAssembler::increment() methods + // which call inc() & dec() or add() & sub() in accordance with + // the product flag UseIncDec value. + + void decl(Register dst); + void decl(Address dst); + void decq(Register dst); + void decq(Address dst); + + void incl(Register dst); + void incl(Address dst); + void incq(Register dst); + void incq(Address dst); + + // New cpus require use of movsd and movss to avoid partial register stall + // when loading from memory. But for old Opteron use movlpd instead of movsd. + // The selection is done in MacroAssembler::movdbl() and movflt(). + + // Move Scalar Single-Precision Floating-Point Values + void movss(XMMRegister dst, Address src); + void movss(XMMRegister dst, XMMRegister src); + void movss(Address dst, XMMRegister src); + + // Move Scalar Double-Precision Floating-Point Values + void movsd(XMMRegister dst, Address src); + void movsd(XMMRegister dst, XMMRegister src); + void movsd(Address dst, XMMRegister src); + void movlpd(XMMRegister dst, Address src); + + // New cpus require use of movaps and movapd to avoid partial register stall + // when moving between registers. + void movaps(XMMRegister dst, XMMRegister src); + void movapd(XMMRegister dst, XMMRegister src); + + // End avoid using directly + + + // Instruction prefixes + void prefix(Prefix p); + public: // Creation @@ -499,219 +616,351 @@ class Assembler : public AbstractAssembler { static address locate_operand(address inst, WhichOperand which); static address locate_next_instruction(address inst); - // Stack - void pushad(); - void popad(); + // Utilities - void pushfd(); - void popfd(); +#ifdef _LP64 + static bool is_simm(int64_t x, int nbits) { return -( CONST64(1) << (nbits-1) ) <= x && x < ( CONST64(1) << (nbits-1) ); } + static bool is_simm32(int64_t x) { return x == (int64_t)(int32_t)x; } +#else + static bool is_simm(int32_t x, int nbits) { return -( 1 << (nbits-1) ) <= x && x < ( 1 << (nbits-1) ); } + static bool is_simm32(int32_t x) { return true; } +#endif // LP64 - void pushl(int imm32); - void pushoop(jobject obj); + // Generic instructions + // Does 32bit or 64bit as needed for the platform. In some sense these + // belong in macro assembler but there is no need for both varieties to exist - void pushl(Register src); - void pushl(Address src); - // void pushl(Label& L, relocInfo::relocType rtype); ? needed? + void lea(Register dst, Address src); - // dummy to prevent NULL being converted to Register - void pushl(void* dummy); + void mov(Register dst, Register src); - void popl(Register dst); - void popl(Address dst); + void pusha(); + void popa(); - // Instruction prefixes - void prefix(Prefix p); + void pushf(); + void popf(); - // Moves - void movb(Register dst, Address src); - void movb(Address dst, int imm8); - void movb(Address dst, Register src); + void push(int32_t imm32); - void movw(Address dst, int imm16); - void movw(Register dst, Address src); - void movw(Address dst, Register src); + void push(Register src); - // these are dummies used to catch attempting to convert NULL to Register - void movl(Register dst, void* junk); - void movl(Address dst, void* junk); + void pop(Register dst); - void movl(Register dst, int imm32); - void movl(Address dst, int imm32); - void movl(Register dst, Register src); - void movl(Register dst, Address src); - void movl(Address dst, Register src); + // These are dummies to prevent surprise implicit conversions to Register + void push(void* v); + void pop(void* v); - void movsxb(Register dst, Address src); - void movsxb(Register dst, Register src); - void movsxw(Register dst, Address src); - void movsxw(Register dst, Register src); + // These do register sized moves/scans + void rep_mov(); + void rep_set(); + void repne_scan(); +#ifdef _LP64 + void repne_scanl(); +#endif - void movzxb(Register dst, Address src); - void movzxb(Register dst, Register src); + // Vanilla instructions in lexical order - void movzxw(Register dst, Address src); - void movzxw(Register dst, Register src); - - // Conditional moves (P6 only) - void cmovl(Condition cc, Register dst, Register src); - void cmovl(Condition cc, Register dst, Address src); - - // Prefetches (SSE, SSE2, 3DNOW only) - void prefetcht0(Address src); - void prefetcht1(Address src); - void prefetcht2(Address src); - void prefetchnta(Address src); - void prefetchw(Address src); - void prefetchr(Address src); - - // Arithmetics - void adcl(Register dst, int imm32); + void adcl(Register dst, int32_t imm32); void adcl(Register dst, Address src); void adcl(Register dst, Register src); - void addl(Address dst, int imm32); + void adcq(Register dst, int32_t imm32); + void adcq(Register dst, Address src); + void adcq(Register dst, Register src); + + + void addl(Address dst, int32_t imm32); void addl(Address dst, Register src); - void addl(Register dst, int imm32); + void addl(Register dst, int32_t imm32); void addl(Register dst, Address src); void addl(Register dst, Register src); - void andl(Register dst, int imm32); - void andl(Register dst, Address src); - void andl(Register dst, Register src); + void addq(Address dst, int32_t imm32); + void addq(Address dst, Register src); + void addq(Register dst, int32_t imm32); + void addq(Register dst, Address src); + void addq(Register dst, Register src); - void cmpb(Address dst, int imm8); - void cmpw(Address dst, int imm16); - void cmpl(Address dst, int imm32); - void cmpl(Register dst, int imm32); - void cmpl(Register dst, Register src); - void cmpl(Register dst, Address src); - // this is a dummy used to catch attempting to convert NULL to Register - void cmpl(Register dst, void* junk); - - protected: - // Don't use next inc() and dec() methods directly. INC & DEC instructions - // could cause a partial flag stall since they don't set CF flag. - // Use MacroAssembler::decrement() & MacroAssembler::increment() methods - // which call inc() & dec() or add() & sub() in accordance with - // the product flag UseIncDec value. - - void decl(Register dst); - void decl(Address dst); - - void incl(Register dst); - void incl(Address dst); - - public: - void idivl(Register src); - void cdql(); - - void imull(Register dst, Register src); - void imull(Register dst, Register src, int value); - - void leal(Register dst, Address src); - - void mull(Address src); - void mull(Register src); - - void negl(Register dst); - - void notl(Register dst); - - void orl(Address dst, int imm32); - void orl(Register dst, int imm32); - void orl(Register dst, Address src); - void orl(Register dst, Register src); - - void rcll(Register dst, int imm8); - - void sarl(Register dst, int imm8); - void sarl(Register dst); - - void sbbl(Address dst, int imm32); - void sbbl(Register dst, int imm32); - void sbbl(Register dst, Address src); - void sbbl(Register dst, Register src); - - void shldl(Register dst, Register src); - - void shll(Register dst, int imm8); - void shll(Register dst); - - void shrdl(Register dst, Register src); - - void shrl(Register dst, int imm8); - void shrl(Register dst); - - void subl(Address dst, int imm32); - void subl(Address dst, Register src); - void subl(Register dst, int imm32); - void subl(Register dst, Address src); - void subl(Register dst, Register src); - - void testb(Register dst, int imm8); - void testl(Register dst, int imm32); - void testl(Register dst, Address src); - void testl(Register dst, Register src); - - void xaddl(Address dst, Register src); - - void xorl(Register dst, int imm32); - void xorl(Register dst, Address src); - void xorl(Register dst, Register src); - - // Miscellaneous - void bswap(Register reg); - void lock(); - - void xchg (Register reg, Address adr); - void xchgl(Register dst, Register src); - - void cmpxchg (Register reg, Address adr); - void cmpxchg8 (Address adr); - - void nop(int i = 1); void addr_nop_4(); void addr_nop_5(); void addr_nop_7(); void addr_nop_8(); - void hlt(); - void ret(int imm16); - void set_byte_if_not_zero(Register dst); // sets reg to 1 if not zero, otherwise 0 - void smovl(); - void rep_movl(); - void rep_set(); - void repne_scan(); - void setb(Condition cc, Register dst); - void membar(); // Serializing memory-fence - void cpuid(); - void cld(); - void std(); + // Add Scalar Double-Precision Floating-Point Values + void addsd(XMMRegister dst, Address src); + void addsd(XMMRegister dst, XMMRegister src); - void emit_raw (unsigned char); + // Add Scalar Single-Precision Floating-Point Values + void addss(XMMRegister dst, Address src); + void addss(XMMRegister dst, XMMRegister src); + + void andl(Register dst, int32_t imm32); + void andl(Register dst, Address src); + void andl(Register dst, Register src); + + void andq(Register dst, int32_t imm32); + void andq(Register dst, Address src); + void andq(Register dst, Register src); + + + // Bitwise Logical AND of Packed Double-Precision Floating-Point Values + void andpd(XMMRegister dst, Address src); + void andpd(XMMRegister dst, XMMRegister src); + + void bswapl(Register reg); + + void bswapq(Register reg); - // Calls void call(Label& L, relocInfo::relocType rtype); void call(Register reg); // push pc; pc <- reg void call(Address adr); // push pc; pc <- adr - // Jumps - void jmp(Address entry); // pc <- entry - void jmp(Register entry); // pc <- entry + void cdql(); - // Label operations & relative jumps (PPUM Appendix D) - void jmp(Label& L, relocInfo::relocType rtype = relocInfo::none); // unconditional jump to L + void cdqq(); - // Force an 8-bit jump offset - // void jmpb(address entry); + void cld() { emit_byte(0xfc); } + + void clflush(Address adr); + + void cmovl(Condition cc, Register dst, Register src); + void cmovl(Condition cc, Register dst, Address src); + + void cmovq(Condition cc, Register dst, Register src); + void cmovq(Condition cc, Register dst, Address src); + + + void cmpb(Address dst, int imm8); + + void cmpl(Address dst, int32_t imm32); + + void cmpl(Register dst, int32_t imm32); + void cmpl(Register dst, Register src); + void cmpl(Register dst, Address src); + + void cmpq(Address dst, int32_t imm32); + void cmpq(Address dst, Register src); + + void cmpq(Register dst, int32_t imm32); + void cmpq(Register dst, Register src); + void cmpq(Register dst, Address src); + + // these are dummies used to catch attempting to convert NULL to Register + void cmpl(Register dst, void* junk); // dummy + void cmpq(Register dst, void* junk); // dummy + + void cmpw(Address dst, int imm16); + + void cmpxchg8 (Address adr); + + void cmpxchgl(Register reg, Address adr); + + void cmpxchgq(Register reg, Address adr); + + // Ordered Compare Scalar Double-Precision Floating-Point Values and set EFLAGS + void comisd(XMMRegister dst, Address src); + + // Ordered Compare Scalar Single-Precision Floating-Point Values and set EFLAGS + void comiss(XMMRegister dst, Address src); + + // Identify processor type and features + void cpuid() { + emit_byte(0x0F); + emit_byte(0xA2); + } + + // Convert Scalar Double-Precision Floating-Point Value to Scalar Single-Precision Floating-Point Value + void cvtsd2ss(XMMRegister dst, XMMRegister src); + + // Convert Doubleword Integer to Scalar Double-Precision Floating-Point Value + void cvtsi2sdl(XMMRegister dst, Register src); + void cvtsi2sdq(XMMRegister dst, Register src); + + // Convert Doubleword Integer to Scalar Single-Precision Floating-Point Value + void cvtsi2ssl(XMMRegister dst, Register src); + void cvtsi2ssq(XMMRegister dst, Register src); + + // Convert Packed Signed Doubleword Integers to Packed Double-Precision Floating-Point Value + void cvtdq2pd(XMMRegister dst, XMMRegister src); + + // Convert Packed Signed Doubleword Integers to Packed Single-Precision Floating-Point Value + void cvtdq2ps(XMMRegister dst, XMMRegister src); + + // Convert Scalar Single-Precision Floating-Point Value to Scalar Double-Precision Floating-Point Value + void cvtss2sd(XMMRegister dst, XMMRegister src); + + // Convert with Truncation Scalar Double-Precision Floating-Point Value to Doubleword Integer + void cvttsd2sil(Register dst, Address src); + void cvttsd2sil(Register dst, XMMRegister src); + void cvttsd2siq(Register dst, XMMRegister src); + + // Convert with Truncation Scalar Single-Precision Floating-Point Value to Doubleword Integer + void cvttss2sil(Register dst, XMMRegister src); + void cvttss2siq(Register dst, XMMRegister src); + + // Divide Scalar Double-Precision Floating-Point Values + void divsd(XMMRegister dst, Address src); + void divsd(XMMRegister dst, XMMRegister src); + + // Divide Scalar Single-Precision Floating-Point Values + void divss(XMMRegister dst, Address src); + void divss(XMMRegister dst, XMMRegister src); + + void emms(); + + void fabs(); + + void fadd(int i); + + void fadd_d(Address src); + void fadd_s(Address src); + + // "Alternate" versions of x87 instructions place result down in FPU + // stack instead of on TOS + + void fadda(int i); // "alternate" fadd + void faddp(int i = 1); + + void fchs(); + + void fcom(int i); + + void fcomp(int i = 1); + void fcomp_d(Address src); + void fcomp_s(Address src); + + void fcompp(); + + void fcos(); + + void fdecstp(); + + void fdiv(int i); + void fdiv_d(Address src); + void fdivr_s(Address src); + void fdiva(int i); // "alternate" fdiv + void fdivp(int i = 1); + + void fdivr(int i); + void fdivr_d(Address src); + void fdiv_s(Address src); + + void fdivra(int i); // "alternate" reversed fdiv + + void fdivrp(int i = 1); + + void ffree(int i = 0); + + void fild_d(Address adr); + void fild_s(Address adr); + + void fincstp(); + + void finit(); + + void fist_s (Address adr); + void fistp_d(Address adr); + void fistp_s(Address adr); + + void fld1(); + + void fld_d(Address adr); + void fld_s(Address adr); + void fld_s(int index); + void fld_x(Address adr); // extended-precision (80-bit) format + + void fldcw(Address src); + + void fldenv(Address src); + + void fldlg2(); + + void fldln2(); + + void fldz(); + + void flog(); + void flog10(); + + void fmul(int i); + + void fmul_d(Address src); + void fmul_s(Address src); + + void fmula(int i); // "alternate" fmul + + void fmulp(int i = 1); + + void fnsave(Address dst); + + void fnstcw(Address src); + + void fnstsw_ax(); + + void fprem(); + void fprem1(); + + void frstor(Address src); + + void fsin(); + + void fsqrt(); + + void fst_d(Address adr); + void fst_s(Address adr); + + void fstp_d(Address adr); + void fstp_d(int index); + void fstp_s(Address adr); + void fstp_x(Address adr); // extended-precision (80-bit) format + + void fsub(int i); + void fsub_d(Address src); + void fsub_s(Address src); + + void fsuba(int i); // "alternate" fsub + + void fsubp(int i = 1); + + void fsubr(int i); + void fsubr_d(Address src); + void fsubr_s(Address src); + + void fsubra(int i); // "alternate" reversed fsub + + void fsubrp(int i = 1); + + void ftan(); + + void ftst(); + + void fucomi(int i = 1); + void fucomip(int i = 1); + + void fwait(); + + void fxch(int i = 1); + + void fxrstor(Address src); + + void fxsave(Address dst); + + void fyl2x(); + + void hlt(); + + void idivl(Register src); + + void idivq(Register src); + + void imull(Register dst, Register src); + void imull(Register dst, Register src, int value); + + void imulq(Register dst, Register src); + void imulq(Register dst, Register src, int value); - // Unconditional 8-bit offset jump to L. - // WARNING: be very careful using this for forward jumps. If the label is - // not bound within an 8-bit offset of this instruction, a run-time error - // will occur. - void jmpb(Label& L); // jcc is the generic conditional branch generator to run- // time routines, jcc is used for branches to labels. jcc @@ -737,250 +986,321 @@ class Assembler : public AbstractAssembler { // will occur. void jccb(Condition cc, Label& L); - // Floating-point operations - void fld1(); - void fldz(); + void jmp(Address entry); // pc <- entry - void fld_s(Address adr); - void fld_s(int index); - void fld_d(Address adr); - void fld_x(Address adr); // extended-precision (80-bit) format + // Label operations & relative jumps (PPUM Appendix D) + void jmp(Label& L, relocInfo::relocType rtype = relocInfo::none); // unconditional jump to L - void fst_s(Address adr); - void fst_d(Address adr); + void jmp(Register entry); // pc <- entry - void fstp_s(Address adr); - void fstp_d(Address adr); - void fstp_d(int index); - void fstp_x(Address adr); // extended-precision (80-bit) format + // Unconditional 8-bit offset jump to L. + // WARNING: be very careful using this for forward jumps. If the label is + // not bound within an 8-bit offset of this instruction, a run-time error + // will occur. + void jmpb(Label& L); - void fild_s(Address adr); - void fild_d(Address adr); + void ldmxcsr( Address src ); - void fist_s (Address adr); - void fistp_s(Address adr); - void fistp_d(Address adr); + void leal(Register dst, Address src); - void fabs(); - void fchs(); + void leaq(Register dst, Address src); - void flog(); - void flog10(); + void lfence() { + emit_byte(0x0F); + emit_byte(0xAE); + emit_byte(0xE8); + } - void fldln2(); - void fyl2x(); - void fldlg2(); + void lock(); - void fcos(); - void fsin(); - void ftan(); - void fsqrt(); + enum Membar_mask_bits { + StoreStore = 1 << 3, + LoadStore = 1 << 2, + StoreLoad = 1 << 1, + LoadLoad = 1 << 0 + }; - // "Alternate" versions of instructions place result down in FPU - // stack instead of on TOS - void fadd_s(Address src); - void fadd_d(Address src); - void fadd(int i); - void fadda(int i); // "alternate" fadd + // Serializes memory. + void membar(Membar_mask_bits order_constraint) { + // We only have to handle StoreLoad and LoadLoad + if (order_constraint & StoreLoad) { + // MFENCE subsumes LFENCE + mfence(); + } /* [jk] not needed currently: else if (order_constraint & LoadLoad) { + lfence(); + } */ + } - void fsub_s(Address src); - void fsub_d(Address src); - void fsubr_s(Address src); - void fsubr_d(Address src); + void mfence(); - void fmul_s(Address src); - void fmul_d(Address src); - void fmul(int i); - void fmula(int i); // "alternate" fmul + // Moves - void fdiv_s(Address src); - void fdiv_d(Address src); - void fdivr_s(Address src); - void fdivr_d(Address src); + void mov64(Register dst, int64_t imm64); - void fsub(int i); - void fsuba(int i); // "alternate" fsub - void fsubr(int i); - void fsubra(int i); // "alternate" reversed fsub - void fdiv(int i); - void fdiva(int i); // "alternate" fdiv - void fdivr(int i); - void fdivra(int i); // "alternate" reversed fdiv + void movb(Address dst, Register src); + void movb(Address dst, int imm8); + void movb(Register dst, Address src); - void faddp(int i = 1); - void fsubp(int i = 1); - void fsubrp(int i = 1); - void fmulp(int i = 1); - void fdivp(int i = 1); - void fdivrp(int i = 1); - void fprem(); - void fprem1(); + void movdl(XMMRegister dst, Register src); + void movdl(Register dst, XMMRegister src); - void fxch(int i = 1); - void fincstp(); - void fdecstp(); - void ffree(int i = 0); + // Move Double Quadword + void movdq(XMMRegister dst, Register src); + void movdq(Register dst, XMMRegister src); - void fcomp_s(Address src); - void fcomp_d(Address src); - void fcom(int i); - void fcomp(int i = 1); - void fcompp(); + // Move Aligned Double Quadword + void movdqa(Address dst, XMMRegister src); + void movdqa(XMMRegister dst, Address src); + void movdqa(XMMRegister dst, XMMRegister src); - void fucomi(int i = 1); - void fucomip(int i = 1); + void movl(Register dst, int32_t imm32); + void movl(Address dst, int32_t imm32); + void movl(Register dst, Register src); + void movl(Register dst, Address src); + void movl(Address dst, Register src); - void ftst(); - void fnstsw_ax(); - void fwait(); - void finit(); - void fldcw(Address src); - void fnstcw(Address src); + // These dummies prevent using movl from converting a zero (like NULL) into Register + // by giving the compiler two choices it can't resolve - void fnsave(Address dst); - void frstor(Address src); - void fldenv(Address src); + void movl(Address dst, void* junk); + void movl(Register dst, void* junk); + +#ifdef _LP64 + void movq(Register dst, Register src); + void movq(Register dst, Address src); + void movq(Address dst, Register src); +#endif + + void movq(Address dst, MMXRegister src ); + void movq(MMXRegister dst, Address src ); + +#ifdef _LP64 + // These dummies prevent using movq from converting a zero (like NULL) into Register + // by giving the compiler two choices it can't resolve + + void movq(Address dst, void* dummy); + void movq(Register dst, void* dummy); +#endif + + // Move Quadword + void movq(Address dst, XMMRegister src); + void movq(XMMRegister dst, Address src); + + void movsbl(Register dst, Address src); + void movsbl(Register dst, Register src); + +#ifdef _LP64 + // Move signed 32bit immediate to 64bit extending sign + void movslq(Address dst, int32_t imm64); + void movslq(Register dst, int32_t imm64); + + void movslq(Register dst, Address src); + void movslq(Register dst, Register src); + void movslq(Register dst, void* src); // Dummy declaration to cause NULL to be ambiguous +#endif + + void movswl(Register dst, Address src); + void movswl(Register dst, Register src); + + void movw(Address dst, int imm16); + void movw(Register dst, Address src); + void movw(Address dst, Register src); + + void movzbl(Register dst, Address src); + void movzbl(Register dst, Register src); + + void movzwl(Register dst, Address src); + void movzwl(Register dst, Register src); + + void mull(Address src); + void mull(Register src); + + // Multiply Scalar Double-Precision Floating-Point Values + void mulsd(XMMRegister dst, Address src); + void mulsd(XMMRegister dst, XMMRegister src); + + // Multiply Scalar Single-Precision Floating-Point Values + void mulss(XMMRegister dst, Address src); + void mulss(XMMRegister dst, XMMRegister src); + + void negl(Register dst); + +#ifdef _LP64 + void negq(Register dst); +#endif + + void nop(int i = 1); + + void notl(Register dst); + +#ifdef _LP64 + void notq(Register dst); +#endif + + void orl(Address dst, int32_t imm32); + void orl(Register dst, int32_t imm32); + void orl(Register dst, Address src); + void orl(Register dst, Register src); + + void orq(Address dst, int32_t imm32); + void orq(Register dst, int32_t imm32); + void orq(Register dst, Address src); + void orq(Register dst, Register src); + + void popl(Address dst); + +#ifdef _LP64 + void popq(Address dst); +#endif + + // Prefetches (SSE, SSE2, 3DNOW only) + + void prefetchnta(Address src); + void prefetchr(Address src); + void prefetcht0(Address src); + void prefetcht1(Address src); + void prefetcht2(Address src); + void prefetchw(Address src); + + // Shuffle Packed Doublewords + void pshufd(XMMRegister dst, XMMRegister src, int mode); + void pshufd(XMMRegister dst, Address src, int mode); + + // Shuffle Packed Low Words + void pshuflw(XMMRegister dst, XMMRegister src, int mode); + void pshuflw(XMMRegister dst, Address src, int mode); + + // Shift Right Logical Quadword Immediate + void psrlq(XMMRegister dst, int shift); + + // Interleave Low Bytes + void punpcklbw(XMMRegister dst, XMMRegister src); + + void pushl(Address src); + + void pushq(Address src); + + // Xor Packed Byte Integer Values + void pxor(XMMRegister dst, Address src); + void pxor(XMMRegister dst, XMMRegister src); + + void rcll(Register dst, int imm8); + + void rclq(Register dst, int imm8); + + void ret(int imm16); void sahf(); - protected: - void emit_sse_operand(XMMRegister reg, Address adr); - void emit_sse_operand(Register reg, Address adr); - void emit_sse_operand(XMMRegister dst, XMMRegister src); - void emit_sse_operand(XMMRegister dst, Register src); - void emit_sse_operand(Register dst, XMMRegister src); + void sarl(Register dst, int imm8); + void sarl(Register dst); - void emit_operand(MMXRegister reg, Address adr); + void sarq(Register dst, int imm8); + void sarq(Register dst); - public: - // mmx operations - void movq( MMXRegister dst, Address src ); - void movq( Address dst, MMXRegister src ); - void emms(); + void sbbl(Address dst, int32_t imm32); + void sbbl(Register dst, int32_t imm32); + void sbbl(Register dst, Address src); + void sbbl(Register dst, Register src); - // xmm operations - void addss(XMMRegister dst, Address src); // Add Scalar Single-Precision Floating-Point Values - void addss(XMMRegister dst, XMMRegister src); - void addsd(XMMRegister dst, Address src); // Add Scalar Double-Precision Floating-Point Values - void addsd(XMMRegister dst, XMMRegister src); + void sbbq(Address dst, int32_t imm32); + void sbbq(Register dst, int32_t imm32); + void sbbq(Register dst, Address src); + void sbbq(Register dst, Register src); - void subss(XMMRegister dst, Address src); // Subtract Scalar Single-Precision Floating-Point Values - void subss(XMMRegister dst, XMMRegister src); - void subsd(XMMRegister dst, Address src); // Subtract Scalar Double-Precision Floating-Point Values - void subsd(XMMRegister dst, XMMRegister src); + void setb(Condition cc, Register dst); - void mulss(XMMRegister dst, Address src); // Multiply Scalar Single-Precision Floating-Point Values - void mulss(XMMRegister dst, XMMRegister src); - void mulsd(XMMRegister dst, Address src); // Multiply Scalar Double-Precision Floating-Point Values - void mulsd(XMMRegister dst, XMMRegister src); + void shldl(Register dst, Register src); - void divss(XMMRegister dst, Address src); // Divide Scalar Single-Precision Floating-Point Values - void divss(XMMRegister dst, XMMRegister src); - void divsd(XMMRegister dst, Address src); // Divide Scalar Double-Precision Floating-Point Values - void divsd(XMMRegister dst, XMMRegister src); + void shll(Register dst, int imm8); + void shll(Register dst); - void sqrtss(XMMRegister dst, Address src); // Compute Square Root of Scalar Single-Precision Floating-Point Value - void sqrtss(XMMRegister dst, XMMRegister src); - void sqrtsd(XMMRegister dst, Address src); // Compute Square Root of Scalar Double-Precision Floating-Point Value + void shlq(Register dst, int imm8); + void shlq(Register dst); + + void shrdl(Register dst, Register src); + + void shrl(Register dst, int imm8); + void shrl(Register dst); + + void shrq(Register dst, int imm8); + void shrq(Register dst); + + void smovl(); // QQQ generic? + + // Compute Square Root of Scalar Double-Precision Floating-Point Value + void sqrtsd(XMMRegister dst, Address src); void sqrtsd(XMMRegister dst, XMMRegister src); - void pxor(XMMRegister dst, Address src); // Xor Packed Byte Integer Values - void pxor(XMMRegister dst, XMMRegister src); // Xor Packed Byte Integer Values + void std() { emit_byte(0xfd); } - void comiss(XMMRegister dst, Address src); // Ordered Compare Scalar Single-Precision Floating-Point Values and set EFLAGS - void comiss(XMMRegister dst, XMMRegister src); - void comisd(XMMRegister dst, Address src); // Ordered Compare Scalar Double-Precision Floating-Point Values and set EFLAGS - void comisd(XMMRegister dst, XMMRegister src); + void stmxcsr( Address dst ); - void ucomiss(XMMRegister dst, Address src); // Unordered Compare Scalar Single-Precision Floating-Point Values and set EFLAGS - void ucomiss(XMMRegister dst, XMMRegister src); - void ucomisd(XMMRegister dst, Address src); // Unordered Compare Scalar Double-Precision Floating-Point Values and set EFLAGS + void subl(Address dst, int32_t imm32); + void subl(Address dst, Register src); + void subl(Register dst, int32_t imm32); + void subl(Register dst, Address src); + void subl(Register dst, Register src); + + void subq(Address dst, int32_t imm32); + void subq(Address dst, Register src); + void subq(Register dst, int32_t imm32); + void subq(Register dst, Address src); + void subq(Register dst, Register src); + + + // Subtract Scalar Double-Precision Floating-Point Values + void subsd(XMMRegister dst, Address src); + void subsd(XMMRegister dst, XMMRegister src); + + // Subtract Scalar Single-Precision Floating-Point Values + void subss(XMMRegister dst, Address src); + void subss(XMMRegister dst, XMMRegister src); + + void testb(Register dst, int imm8); + + void testl(Register dst, int32_t imm32); + void testl(Register dst, Register src); + void testl(Register dst, Address src); + + void testq(Register dst, int32_t imm32); + void testq(Register dst, Register src); + + + // Unordered Compare Scalar Double-Precision Floating-Point Values and set EFLAGS + void ucomisd(XMMRegister dst, Address src); void ucomisd(XMMRegister dst, XMMRegister src); - void cvtss2sd(XMMRegister dst, Address src); // Convert Scalar Single-Precision Floating-Point Value to Scalar Double-Precision Floating-Point Value - void cvtss2sd(XMMRegister dst, XMMRegister src); - void cvtsd2ss(XMMRegister dst, Address src); // Convert Scalar Double-Precision Floating-Point Value to Scalar Single-Precision Floating-Point Value - void cvtsd2ss(XMMRegister dst, XMMRegister src); - void cvtdq2pd(XMMRegister dst, XMMRegister src); - void cvtdq2ps(XMMRegister dst, XMMRegister src); + // Unordered Compare Scalar Single-Precision Floating-Point Values and set EFLAGS + void ucomiss(XMMRegister dst, Address src); + void ucomiss(XMMRegister dst, XMMRegister src); - void cvtsi2ss(XMMRegister dst, Address src); // Convert Doubleword Integer to Scalar Single-Precision Floating-Point Value - void cvtsi2ss(XMMRegister dst, Register src); - void cvtsi2sd(XMMRegister dst, Address src); // Convert Doubleword Integer to Scalar Double-Precision Floating-Point Value - void cvtsi2sd(XMMRegister dst, Register src); + void xaddl(Address dst, Register src); - void cvtss2si(Register dst, Address src); // Convert Scalar Single-Precision Floating-Point Value to Doubleword Integer - void cvtss2si(Register dst, XMMRegister src); - void cvtsd2si(Register dst, Address src); // Convert Scalar Double-Precision Floating-Point Value to Doubleword Integer - void cvtsd2si(Register dst, XMMRegister src); + void xaddq(Address dst, Register src); - void cvttss2si(Register dst, Address src); // Convert with Truncation Scalar Single-Precision Floating-Point Value to Doubleword Integer - void cvttss2si(Register dst, XMMRegister src); - void cvttsd2si(Register dst, Address src); // Convert with Truncation Scalar Double-Precision Floating-Point Value to Doubleword Integer - void cvttsd2si(Register dst, XMMRegister src); + void xchgl(Register reg, Address adr); + void xchgl(Register dst, Register src); - protected: // Avoid using the next instructions directly. - // New cpus require use of movsd and movss to avoid partial register stall - // when loading from memory. But for old Opteron use movlpd instead of movsd. - // The selection is done in MacroAssembler::movdbl() and movflt(). - void movss(XMMRegister dst, Address src); // Move Scalar Single-Precision Floating-Point Values - void movss(XMMRegister dst, XMMRegister src); - void movss(Address dst, XMMRegister src); - void movsd(XMMRegister dst, Address src); // Move Scalar Double-Precision Floating-Point Values - void movsd(XMMRegister dst, XMMRegister src); - void movsd(Address dst, XMMRegister src); - void movlpd(XMMRegister dst, Address src); - // New cpus require use of movaps and movapd to avoid partial register stall - // when moving between registers. - void movaps(XMMRegister dst, XMMRegister src); - void movapd(XMMRegister dst, XMMRegister src); - public: + void xchgq(Register reg, Address adr); + void xchgq(Register dst, Register src); - void andps(XMMRegister dst, Address src); // Bitwise Logical AND of Packed Single-Precision Floating-Point Values - void andps(XMMRegister dst, XMMRegister src); - void andpd(XMMRegister dst, Address src); // Bitwise Logical AND of Packed Double-Precision Floating-Point Values - void andpd(XMMRegister dst, XMMRegister src); + void xorl(Register dst, int32_t imm32); + void xorl(Register dst, Address src); + void xorl(Register dst, Register src); - void andnps(XMMRegister dst, Address src); // Bitwise Logical AND NOT of Packed Single-Precision Floating-Point Values - void andnps(XMMRegister dst, XMMRegister src); - void andnpd(XMMRegister dst, Address src); // Bitwise Logical AND NOT of Packed Double-Precision Floating-Point Values - void andnpd(XMMRegister dst, XMMRegister src); + void xorq(Register dst, Address src); + void xorq(Register dst, Register src); - void orps(XMMRegister dst, Address src); // Bitwise Logical OR of Packed Single-Precision Floating-Point Values - void orps(XMMRegister dst, XMMRegister src); - void orpd(XMMRegister dst, Address src); // Bitwise Logical OR of Packed Double-Precision Floating-Point Values - void orpd(XMMRegister dst, XMMRegister src); - - void xorps(XMMRegister dst, Address src); // Bitwise Logical XOR of Packed Single-Precision Floating-Point Values - void xorps(XMMRegister dst, XMMRegister src); - void xorpd(XMMRegister dst, Address src); // Bitwise Logical XOR of Packed Double-Precision Floating-Point Values + // Bitwise Logical XOR of Packed Double-Precision Floating-Point Values + void xorpd(XMMRegister dst, Address src); void xorpd(XMMRegister dst, XMMRegister src); - void movq(XMMRegister dst, Address src); // Move Quadword - void movq(XMMRegister dst, XMMRegister src); - void movq(Address dst, XMMRegister src); + // Bitwise Logical XOR of Packed Single-Precision Floating-Point Values + void xorps(XMMRegister dst, Address src); + void xorps(XMMRegister dst, XMMRegister src); - void movd(XMMRegister dst, Address src); // Move Doubleword - void movd(XMMRegister dst, Register src); - void movd(Register dst, XMMRegister src); - void movd(Address dst, XMMRegister src); - - void movdqa(XMMRegister dst, Address src); // Move Aligned Double Quadword - void movdqa(XMMRegister dst, XMMRegister src); - void movdqa(Address dst, XMMRegister src); - - void pshufd(XMMRegister dst, XMMRegister src, int mode); // Shuffle Packed Doublewords - void pshufd(XMMRegister dst, Address src, int mode); - void pshuflw(XMMRegister dst, XMMRegister src, int mode); // Shuffle Packed Low Words - void pshuflw(XMMRegister dst, Address src, int mode); - - void psrlq(XMMRegister dst, int shift); // Shift Right Logical Quadword Immediate - - void punpcklbw(XMMRegister dst, XMMRegister src); // Interleave Low Bytes - void punpcklbw(XMMRegister dst, Address src); - - void ldmxcsr( Address src ); - void stmxcsr( Address dst ); + void set_byte_if_not_zero(Register dst); // sets reg to 1 if not zero, otherwise 0 }; @@ -1077,10 +1397,22 @@ class MacroAssembler: public Assembler { void extend_sign(Register hi, Register lo); // Support for inc/dec with optimal instruction selection depending on value - void increment(Register reg, int value = 1); - void decrement(Register reg, int value = 1); - void increment(Address dst, int value = 1); - void decrement(Address dst, int value = 1); + + void increment(Register reg, int value = 1) { LP64_ONLY(incrementq(reg, value)) NOT_LP64(incrementl(reg, value)) ; } + void decrement(Register reg, int value = 1) { LP64_ONLY(decrementq(reg, value)) NOT_LP64(decrementl(reg, value)) ; } + + void decrementl(Address dst, int value = 1); + void decrementl(Register reg, int value = 1); + + void decrementq(Register reg, int value = 1); + void decrementq(Address dst, int value = 1); + + void incrementl(Address dst, int value = 1); + void incrementl(Register reg, int value = 1); + + void incrementq(Register reg, int value = 1); + void incrementq(Address dst, int value = 1); + // Support optimal SSE move instructions. void movflt(XMMRegister dst, XMMRegister src) { @@ -1104,9 +1436,8 @@ class MacroAssembler: public Assembler { } void movdbl(Address dst, XMMRegister src) { movsd(dst, src); } - void increment(AddressLiteral dst); - void increment(ArrayAddress dst); - + void incrementl(AddressLiteral dst); + void incrementl(ArrayAddress dst); // Alignment void align(int modulus); @@ -1128,25 +1459,70 @@ class MacroAssembler: public Assembler { // They make sure that the stack linkage is setup correctly. call_VM's correspond // to ENTRY/ENTRY_X entry points while call_VM_leaf's correspond to LEAF entry points. - void call_VM(Register oop_result, address entry_point, bool check_exceptions = true); - void call_VM(Register oop_result, address entry_point, Register arg_1, bool check_exceptions = true); - void call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, bool check_exceptions = true); - void call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, Register arg_3, bool check_exceptions = true); - void call_VM(Register oop_result, Register last_java_sp, address entry_point, int number_of_arguments = 0, bool check_exceptions = true); - void call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, bool check_exceptions = true); - void call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, bool check_exceptions = true); - void call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, Register arg_3, bool check_exceptions = true); + void call_VM(Register oop_result, + address entry_point, + bool check_exceptions = true); + void call_VM(Register oop_result, + address entry_point, + Register arg_1, + bool check_exceptions = true); + void call_VM(Register oop_result, + address entry_point, + Register arg_1, Register arg_2, + bool check_exceptions = true); + void call_VM(Register oop_result, + address entry_point, + Register arg_1, Register arg_2, Register arg_3, + bool check_exceptions = true); - void call_VM_leaf(address entry_point, int number_of_arguments = 0); - void call_VM_leaf(address entry_point, Register arg_1); - void call_VM_leaf(address entry_point, Register arg_1, Register arg_2); - void call_VM_leaf(address entry_point, Register arg_1, Register arg_2, Register arg_3); + // Overloadings with last_Java_sp + void call_VM(Register oop_result, + Register last_java_sp, + address entry_point, + int number_of_arguments = 0, + bool check_exceptions = true); + void call_VM(Register oop_result, + Register last_java_sp, + address entry_point, + Register arg_1, bool + check_exceptions = true); + void call_VM(Register oop_result, + Register last_java_sp, + address entry_point, + Register arg_1, Register arg_2, + bool check_exceptions = true); + void call_VM(Register oop_result, + Register last_java_sp, + address entry_point, + Register arg_1, Register arg_2, Register arg_3, + bool check_exceptions = true); + + void call_VM_leaf(address entry_point, + int number_of_arguments = 0); + void call_VM_leaf(address entry_point, + Register arg_1); + void call_VM_leaf(address entry_point, + Register arg_1, Register arg_2); + void call_VM_leaf(address entry_point, + Register arg_1, Register arg_2, Register arg_3); // last Java Frame (fills frame anchor) - void set_last_Java_frame(Register thread, Register last_java_sp, Register last_java_fp, address last_java_pc); + void set_last_Java_frame(Register thread, + Register last_java_sp, + Register last_java_fp, + address last_java_pc); + + // thread in the default location (r15_thread on 64bit) + void set_last_Java_frame(Register last_java_sp, + Register last_java_fp, + address last_java_pc); + void reset_last_Java_frame(Register thread, bool clear_fp, bool clear_pc); + // thread in the default location (r15_thread on 64bit) + void reset_last_Java_frame(bool clear_fp, bool clear_pc); + // Stores void store_check(Register obj); // store check for obj - register is destroyed afterwards void store_check(Register obj, Address dst); // same as above, dst is exact store location (reg. is destroyed) @@ -1165,18 +1541,48 @@ class MacroAssembler: public Assembler { void movbool(Address dst, Register src); void testbool(Register dst); - // Int division/reminder for Java + // oop manipulations + void load_klass(Register dst, Register src); + void store_klass(Register dst, Register src); + + void load_prototype_header(Register dst, Register src); + +#ifdef _LP64 + void store_klass_gap(Register dst, Register src); + + void load_heap_oop(Register dst, Address src); + void store_heap_oop(Address dst, Register src); + void encode_heap_oop(Register r); + void decode_heap_oop(Register r); + void encode_heap_oop_not_null(Register r); + void decode_heap_oop_not_null(Register r); + void encode_heap_oop_not_null(Register dst, Register src); + void decode_heap_oop_not_null(Register dst, Register src); + + void set_narrow_oop(Register dst, jobject obj); + + // if heap base register is used - reinit it with the correct value + void reinit_heapbase(); +#endif // _LP64 + + // Int division/remainder for Java // (as idivl, but checks for special case as described in JVM spec.) // returns idivl instruction offset for implicit exception handling int corrected_idivl(Register reg); + // Long division/remainder for Java + // (as idivq, but checks for special case as described in JVM spec.) + // returns idivq instruction offset for implicit exception handling + int corrected_idivq(Register reg); + void int3(); + // Long operation macros for a 32bit cpu // Long negation for Java void lneg(Register hi, Register lo); // Long multiplication for Java - // (destroys contents of rax, rbx, rcx and rdx) + // (destroys contents of eax, ebx, ecx and edx) void lmul(int x_rsp_offset, int y_rsp_offset); // rdx:rax = x * y // Long shifts for Java @@ -1188,6 +1594,16 @@ class MacroAssembler: public Assembler { // (semantics as described in JVM spec.) void lcmp2int(Register x_hi, Register x_lo, Register y_hi, Register y_lo); // x_hi = lcmp(x, y) + + // misc + + // Sign extension + void sign_extend_short(Register reg); + void sign_extend_byte(Register reg); + + // Division by power of 2, rounding towards 0 + void division_with_shift(Register reg, int shift_value); + // Compares the top-most stack entries on the FPU stack and sets the eflags as follows: // // CF (corresponds to C0) if x < y @@ -1255,13 +1671,6 @@ class MacroAssembler: public Assembler { void push_CPU_state(); void pop_CPU_state(); - // Sign extension - void sign_extend_short(Register reg); - void sign_extend_byte(Register reg); - - // Division by power of 2, rounding towards 0 - void division_with_shift(Register reg, int shift_value); - // Round up to a power of two void round_to(Register reg, int modulus); @@ -1291,17 +1700,31 @@ class MacroAssembler: public Assembler { void set_word_if_not_zero(Register reg); // sets reg to 1 if not zero, otherwise 0 // Debugging - void verify_oop(Register reg, const char* s = "broken oop"); // only if +VerifyOops + + // only if +VerifyOops + void verify_oop(Register reg, const char* s = "broken oop"); void verify_oop_addr(Address addr, const char * s = "broken oop addr"); - void verify_FPU(int stack_depth, const char* s = "illegal FPU state"); // only if +VerifyFPU - void stop(const char* msg); // prints msg, dumps registers and stops execution - void warn(const char* msg); // prints msg and continues - static void debug(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip, char* msg); + // only if +VerifyFPU + void verify_FPU(int stack_depth, const char* s = "illegal FPU state"); + + // prints msg, dumps registers and stops execution + void stop(const char* msg); + + // prints msg and continues + void warn(const char* msg); + + static void debug32(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip, char* msg); + static void debug64(char* msg, int64_t pc, int64_t regs[]); + void os_breakpoint(); + void untested() { stop("untested"); } + void unimplemented(const char* what = "") { char* b = new char[1024]; jio_snprintf(b, sizeof(b), "unimplemented: %s", what); stop(b); } + void should_not_reach_here() { stop("should not reach here"); } + void print_CPU_state(); // Stack overflow checking @@ -1348,9 +1771,20 @@ class MacroAssembler: public Assembler { // Arithmetics - void cmp8(AddressLiteral src1, int8_t imm); - // QQQ renamed to drag out the casting of address to int32_t/intptr_t + void addptr(Address dst, int32_t src) { LP64_ONLY(addq(dst, src)) NOT_LP64(addl(dst, src)) ; } + void addptr(Address dst, Register src); + + void addptr(Register dst, Address src) { LP64_ONLY(addq(dst, src)) NOT_LP64(addl(dst, src)); } + void addptr(Register dst, int32_t src); + void addptr(Register dst, Register src); + + void andptr(Register dst, int32_t src); + void andptr(Register src1, Register src2) { LP64_ONLY(andq(src1, src2)) NOT_LP64(andl(src1, src2)) ; } + + void cmp8(AddressLiteral src1, int imm); + + // renamed to drag out the casting of address to int32_t/intptr_t void cmp32(Register src1, int32_t imm); void cmp32(AddressLiteral src1, int32_t imm); @@ -1359,16 +1793,63 @@ class MacroAssembler: public Assembler { void cmp32(Register src1, Address src2); +#ifndef _LP64 + void cmpoop(Address dst, jobject obj); + void cmpoop(Register dst, jobject obj); +#endif // _LP64 + // NOTE src2 must be the lval. This is NOT an mem-mem compare void cmpptr(Address src1, AddressLiteral src2); void cmpptr(Register src1, AddressLiteral src2); - void cmpoop(Address dst, jobject obj); - void cmpoop(Register dst, jobject obj); + void cmpptr(Register src1, Register src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } + void cmpptr(Register src1, Address src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } + // void cmpptr(Address src1, Register src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } + + void cmpptr(Register src1, int32_t src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } + void cmpptr(Address src1, int32_t src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } + + // cmp64 to avoild hiding cmpq + void cmp64(Register src1, AddressLiteral src); + + void cmpxchgptr(Register reg, Address adr); + + void locked_cmpxchgptr(Register reg, AddressLiteral adr); + + + void imulptr(Register dst, Register src) { LP64_ONLY(imulq(dst, src)) NOT_LP64(imull(dst, src)); } + + + void negptr(Register dst) { LP64_ONLY(negq(dst)) NOT_LP64(negl(dst)); } + + void notptr(Register dst) { LP64_ONLY(notq(dst)) NOT_LP64(notl(dst)); } + + void shlptr(Register dst, int32_t shift); + void shlptr(Register dst) { LP64_ONLY(shlq(dst)) NOT_LP64(shll(dst)); } + + void shrptr(Register dst, int32_t shift); + void shrptr(Register dst) { LP64_ONLY(shrq(dst)) NOT_LP64(shrl(dst)); } + + void sarptr(Register dst) { LP64_ONLY(sarq(dst)) NOT_LP64(sarl(dst)); } + void sarptr(Register dst, int32_t src) { LP64_ONLY(sarq(dst, src)) NOT_LP64(sarl(dst, src)); } + + void subptr(Address dst, int32_t src) { LP64_ONLY(subq(dst, src)) NOT_LP64(subl(dst, src)); } + + void subptr(Register dst, Address src) { LP64_ONLY(subq(dst, src)) NOT_LP64(subl(dst, src)); } + void subptr(Register dst, int32_t src); + void subptr(Register dst, Register src); + + + void sbbptr(Address dst, int32_t src) { LP64_ONLY(sbbq(dst, src)) NOT_LP64(sbbl(dst, src)); } + void sbbptr(Register dst, int32_t src) { LP64_ONLY(sbbq(dst, src)) NOT_LP64(sbbl(dst, src)); } + + void xchgptr(Register src1, Register src2) { LP64_ONLY(xchgq(src1, src2)) NOT_LP64(xchgl(src1, src2)) ; } + void xchgptr(Register src1, Address src2) { LP64_ONLY(xchgq(src1, src2)) NOT_LP64(xchgl(src1, src2)) ; } + + void xaddptr(Address src1, Register src2) { LP64_ONLY(xaddq(src1, src2)) NOT_LP64(xaddl(src1, src2)) ; } - void cmpxchgptr(Register reg, AddressLiteral adr); // Helper functions for statistics gathering. // Conditionally (atomically, on MPs) increments passed counter address, preserving condition codes. @@ -1378,8 +1859,21 @@ class MacroAssembler: public Assembler { void lea(Register dst, AddressLiteral adr); void lea(Address dst, AddressLiteral adr); + void lea(Register dst, Address adr) { Assembler::lea(dst, adr); } - void test32(Register dst, AddressLiteral src); + void leal32(Register dst, Address src) { leal(dst, src); } + + void test32(Register src1, AddressLiteral src2); + + void orptr(Register dst, Address src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); } + void orptr(Register dst, Register src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); } + void orptr(Register dst, int32_t src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); } + + void testptr(Register src, int32_t imm32) { LP64_ONLY(testq(src, imm32)) NOT_LP64(testl(src, imm32)); } + void testptr(Register src1, Register src2); + + void xorptr(Register dst, Register src) { LP64_ONLY(xorq(dst, src)) NOT_LP64(xorl(dst, src)); } + void xorptr(Register dst, Address src) { LP64_ONLY(xorq(dst, src)) NOT_LP64(xorl(dst, src)); } // Calls @@ -1431,11 +1925,19 @@ class MacroAssembler: public Assembler { void ldmxcsr(Address src) { Assembler::ldmxcsr(src); } void ldmxcsr(AddressLiteral src); +private: + // these are private because users should be doing movflt/movdbl + void movss(Address dst, XMMRegister src) { Assembler::movss(dst, src); } void movss(XMMRegister dst, XMMRegister src) { Assembler::movss(dst, src); } void movss(XMMRegister dst, Address src) { Assembler::movss(dst, src); } void movss(XMMRegister dst, AddressLiteral src); + void movlpd(XMMRegister dst, Address src) {Assembler::movlpd(dst, src); } + void movlpd(XMMRegister dst, AddressLiteral src); + +public: + void movsd(XMMRegister dst, XMMRegister src) { Assembler::movsd(dst, src); } void movsd(Address dst, XMMRegister src) { Assembler::movsd(dst, src); } void movsd(XMMRegister dst, Address src) { Assembler::movsd(dst, src); } @@ -1461,6 +1963,11 @@ class MacroAssembler: public Assembler { // Data + void cmov(Condition cc, Register dst, Register src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmovl(cc, dst, src)); } + + void cmovptr(Condition cc, Register dst, Address src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmovl(cc, dst, src)); } + void cmovptr(Condition cc, Register dst, Register src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmovl(cc, dst, src)); } + void movoop(Register dst, jobject obj); void movoop(Address dst, jobject obj); @@ -1468,17 +1975,48 @@ class MacroAssembler: public Assembler { // can this do an lea? void movptr(Register dst, ArrayAddress src); + void movptr(Register dst, Address src); + void movptr(Register dst, AddressLiteral src); + void movptr(Register dst, intptr_t src); + void movptr(Register dst, Register src); + void movptr(Address dst, intptr_t src); + + void movptr(Address dst, Register src); + +#ifdef _LP64 + // Generally the next two are only used for moving NULL + // Although there are situations in initializing the mark word where + // they could be used. They are dangerous. + + // They only exist on LP64 so that int32_t and intptr_t are not the same + // and we have ambiguous declarations. + + void movptr(Address dst, int32_t imm32); + void movptr(Register dst, int32_t imm32); +#endif // _LP64 + // to avoid hiding movl void mov32(AddressLiteral dst, Register src); void mov32(Register dst, AddressLiteral src); + // to avoid hiding movb void movbyte(ArrayAddress dst, int src); // Can push value or effective address void pushptr(AddressLiteral src); + void pushptr(Address src) { LP64_ONLY(pushq(src)) NOT_LP64(pushl(src)); } + void popptr(Address src) { LP64_ONLY(popq(src)) NOT_LP64(popl(src)); } + + void pushoop(jobject obj); + + // sign extend as need a l to ptr sized element + void movl2ptr(Register dst, Address src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(movl(dst, src)); } + void movl2ptr(Register dst, Register src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(if (dst != src) movl(dst, src)); } + + #undef VIRTUAL }; diff --git a/hotspot/src/cpu/x86/vm/assembler_x86_64.inline.hpp b/hotspot/src/cpu/x86/vm/assembler_x86.inline.hpp similarity index 74% rename from hotspot/src/cpu/x86/vm/assembler_x86_64.inline.hpp rename to hotspot/src/cpu/x86/vm/assembler_x86.inline.hpp index 3a705ea3ea1..27c2b6addc0 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86_64.inline.hpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-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 @@ -22,12 +22,6 @@ * */ -inline void Assembler::emit_long64(jlong x) { - *(jlong*) _code_pos = x; - _code_pos += sizeof(jlong); - code_section()->set_end(_code_pos); -} - inline void MacroAssembler::pd_patch_instruction(address branch, address target) { unsigned char op = branch[0]; assert(op == 0xE8 /* call */ || @@ -69,18 +63,25 @@ inline void MacroAssembler::pd_print_patched_instruction(address branch) { } #endif // ndef PRODUCT -inline void MacroAssembler::movptr(Address dst, intptr_t src) { -#ifdef _LP64 - Assembler::mov64(dst, src); -#else - Assembler::movl(dst, src); -#endif // _LP64 -} +#ifndef _LP64 +inline int Assembler::prefix_and_encode(int reg_enc, bool byteinst) { return reg_enc; } +inline int Assembler::prefixq_and_encode(int reg_enc) { return reg_enc; } -inline void MacroAssembler::movptr(Register dst, intptr_t src) { -#ifdef _LP64 - Assembler::mov64(dst, src); +inline int Assembler::prefix_and_encode(int dst_enc, int src_enc, bool byteinst) { return dst_enc << 3 | src_enc; } +inline int Assembler::prefixq_and_encode(int dst_enc, int src_enc) { return dst_enc << 3 | src_enc; } + +inline void Assembler::prefix(Register reg) {} +inline void Assembler::prefix(Address adr) {} +inline void Assembler::prefixq(Address adr) {} + +inline void Assembler::prefix(Address adr, Register reg, bool byteinst) {} +inline void Assembler::prefixq(Address adr, Register reg) {} + +inline void Assembler::prefix(Address adr, XMMRegister reg) {} #else - Assembler::movl(dst, src); -#endif // _LP64 +inline void Assembler::emit_long64(jlong x) { + *(jlong*) _code_pos = x; + _code_pos += sizeof(jlong); + code_section()->set_end(_code_pos); } +#endif // _LP64 diff --git a/hotspot/src/cpu/x86/vm/assembler_x86_32.cpp b/hotspot/src/cpu/x86/vm/assembler_x86_32.cpp deleted file mode 100644 index 91c2e9ab193..00000000000 --- a/hotspot/src/cpu/x86/vm/assembler_x86_32.cpp +++ /dev/null @@ -1,5001 +0,0 @@ -/* - * Copyright 1997-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. - * - */ - -#include "incls/_precompiled.incl" -#include "incls/_assembler_x86_32.cpp.incl" - -// Implementation of AddressLiteral - -AddressLiteral::AddressLiteral(address target, relocInfo::relocType rtype) { - _is_lval = false; - _target = target; - switch (rtype) { - case relocInfo::oop_type: - // Oops are a special case. Normally they would be their own section - // but in cases like icBuffer they are literals in the code stream that - // we don't have a section for. We use none so that we get a literal address - // which is always patchable. - break; - case relocInfo::external_word_type: - _rspec = external_word_Relocation::spec(target); - break; - case relocInfo::internal_word_type: - _rspec = internal_word_Relocation::spec(target); - break; - case relocInfo::opt_virtual_call_type: - _rspec = opt_virtual_call_Relocation::spec(); - break; - case relocInfo::static_call_type: - _rspec = static_call_Relocation::spec(); - break; - case relocInfo::runtime_call_type: - _rspec = runtime_call_Relocation::spec(); - break; - case relocInfo::poll_type: - case relocInfo::poll_return_type: - _rspec = Relocation::spec_simple(rtype); - break; - case relocInfo::none: - break; - default: - ShouldNotReachHere(); - break; - } -} - -// Implementation of Address - -Address Address::make_array(ArrayAddress adr) { -#ifdef _LP64 - // Not implementable on 64bit machines - // Should have been handled higher up the call chain. - ShouldNotReachHere(); -#else - AddressLiteral base = adr.base(); - Address index = adr.index(); - assert(index._disp == 0, "must not have disp"); // maybe it can? - Address array(index._base, index._index, index._scale, (intptr_t) base.target()); - array._rspec = base._rspec; - return array; -#endif // _LP64 -} - -#ifndef _LP64 - -// exceedingly dangerous constructor -Address::Address(address loc, RelocationHolder spec) { - _base = noreg; - _index = noreg; - _scale = no_scale; - _disp = (intptr_t) loc; - _rspec = spec; -} -#endif // _LP64 - -// Convert the raw encoding form into the form expected by the constructor for -// Address. An index of 4 (rsp) corresponds to having no index, so convert -// that to noreg for the Address constructor. -Address Address::make_raw(int base, int index, int scale, int disp) { - bool valid_index = index != rsp->encoding(); - if (valid_index) { - Address madr(as_Register(base), as_Register(index), (Address::ScaleFactor)scale, in_ByteSize(disp)); - return madr; - } else { - Address madr(as_Register(base), noreg, Address::no_scale, in_ByteSize(disp)); - return madr; - } -} - -// Implementation of Assembler - -int AbstractAssembler::code_fill_byte() { - return (u_char)'\xF4'; // hlt -} - -// make this go away someday -void Assembler::emit_data(jint data, relocInfo::relocType rtype, int format) { - if (rtype == relocInfo::none) - emit_long(data); - else emit_data(data, Relocation::spec_simple(rtype), format); -} - - -void Assembler::emit_data(jint data, RelocationHolder const& rspec, int format) { - assert(imm32_operand == 0, "default format must be imm32 in this file"); - assert(inst_mark() != NULL, "must be inside InstructionMark"); - if (rspec.type() != relocInfo::none) { - #ifdef ASSERT - check_relocation(rspec, format); - #endif - // Do not use AbstractAssembler::relocate, which is not intended for - // embedded words. Instead, relocate to the enclosing instruction. - - // hack. call32 is too wide for mask so use disp32 - if (format == call32_operand) - code_section()->relocate(inst_mark(), rspec, disp32_operand); - else - code_section()->relocate(inst_mark(), rspec, format); - } - emit_long(data); -} - - -void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) { - assert(dst->has_byte_register(), "must have byte register"); - assert(isByte(op1) && isByte(op2), "wrong opcode"); - assert(isByte(imm8), "not a byte"); - assert((op1 & 0x01) == 0, "should be 8bit operation"); - emit_byte(op1); - emit_byte(op2 | dst->encoding()); - emit_byte(imm8); -} - - -void Assembler::emit_arith(int op1, int op2, Register dst, int imm32) { - assert(isByte(op1) && isByte(op2), "wrong opcode"); - assert((op1 & 0x01) == 1, "should be 32bit operation"); - assert((op1 & 0x02) == 0, "sign-extension bit should not be set"); - if (is8bit(imm32)) { - emit_byte(op1 | 0x02); // set sign bit - emit_byte(op2 | dst->encoding()); - emit_byte(imm32 & 0xFF); - } else { - emit_byte(op1); - emit_byte(op2 | dst->encoding()); - emit_long(imm32); - } -} - -// immediate-to-memory forms -void Assembler::emit_arith_operand(int op1, Register rm, Address adr, int imm32) { - assert((op1 & 0x01) == 1, "should be 32bit operation"); - assert((op1 & 0x02) == 0, "sign-extension bit should not be set"); - if (is8bit(imm32)) { - emit_byte(op1 | 0x02); // set sign bit - emit_operand(rm,adr); - emit_byte(imm32 & 0xFF); - } else { - emit_byte(op1); - emit_operand(rm,adr); - emit_long(imm32); - } -} - -void Assembler::emit_arith(int op1, int op2, Register dst, jobject obj) { - assert(isByte(op1) && isByte(op2), "wrong opcode"); - assert((op1 & 0x01) == 1, "should be 32bit operation"); - assert((op1 & 0x02) == 0, "sign-extension bit should not be set"); - InstructionMark im(this); - emit_byte(op1); - emit_byte(op2 | dst->encoding()); - emit_data((int)obj, relocInfo::oop_type, 0); -} - - -void Assembler::emit_arith(int op1, int op2, Register dst, Register src) { - assert(isByte(op1) && isByte(op2), "wrong opcode"); - emit_byte(op1); - emit_byte(op2 | dst->encoding() << 3 | src->encoding()); -} - - -void Assembler::emit_operand(Register reg, - Register base, - Register index, - Address::ScaleFactor scale, - int disp, - RelocationHolder const& rspec) { - - relocInfo::relocType rtype = (relocInfo::relocType) rspec.type(); - if (base->is_valid()) { - if (index->is_valid()) { - assert(scale != Address::no_scale, "inconsistent address"); - // [base + index*scale + disp] - if (disp == 0 && rtype == relocInfo::none && base != rbp) { - // [base + index*scale] - // [00 reg 100][ss index base] - assert(index != rsp, "illegal addressing mode"); - emit_byte(0x04 | reg->encoding() << 3); - emit_byte(scale << 6 | index->encoding() << 3 | base->encoding()); - } else if (is8bit(disp) && rtype == relocInfo::none) { - // [base + index*scale + imm8] - // [01 reg 100][ss index base] imm8 - assert(index != rsp, "illegal addressing mode"); - emit_byte(0x44 | reg->encoding() << 3); - emit_byte(scale << 6 | index->encoding() << 3 | base->encoding()); - emit_byte(disp & 0xFF); - } else { - // [base + index*scale + imm32] - // [10 reg 100][ss index base] imm32 - assert(index != rsp, "illegal addressing mode"); - emit_byte(0x84 | reg->encoding() << 3); - emit_byte(scale << 6 | index->encoding() << 3 | base->encoding()); - emit_data(disp, rspec, disp32_operand); - } - } else if (base == rsp) { - // [esp + disp] - if (disp == 0 && rtype == relocInfo::none) { - // [esp] - // [00 reg 100][00 100 100] - emit_byte(0x04 | reg->encoding() << 3); - emit_byte(0x24); - } else if (is8bit(disp) && rtype == relocInfo::none) { - // [esp + imm8] - // [01 reg 100][00 100 100] imm8 - emit_byte(0x44 | reg->encoding() << 3); - emit_byte(0x24); - emit_byte(disp & 0xFF); - } else { - // [esp + imm32] - // [10 reg 100][00 100 100] imm32 - emit_byte(0x84 | reg->encoding() << 3); - emit_byte(0x24); - emit_data(disp, rspec, disp32_operand); - } - } else { - // [base + disp] - assert(base != rsp, "illegal addressing mode"); - if (disp == 0 && rtype == relocInfo::none && base != rbp) { - // [base] - // [00 reg base] - assert(base != rbp, "illegal addressing mode"); - emit_byte(0x00 | reg->encoding() << 3 | base->encoding()); - } else if (is8bit(disp) && rtype == relocInfo::none) { - // [base + imm8] - // [01 reg base] imm8 - emit_byte(0x40 | reg->encoding() << 3 | base->encoding()); - emit_byte(disp & 0xFF); - } else { - // [base + imm32] - // [10 reg base] imm32 - emit_byte(0x80 | reg->encoding() << 3 | base->encoding()); - emit_data(disp, rspec, disp32_operand); - } - } - } else { - if (index->is_valid()) { - assert(scale != Address::no_scale, "inconsistent address"); - // [index*scale + disp] - // [00 reg 100][ss index 101] imm32 - assert(index != rsp, "illegal addressing mode"); - emit_byte(0x04 | reg->encoding() << 3); - emit_byte(scale << 6 | index->encoding() << 3 | 0x05); - emit_data(disp, rspec, disp32_operand); - } else { - // [disp] - // [00 reg 101] imm32 - emit_byte(0x05 | reg->encoding() << 3); - emit_data(disp, rspec, disp32_operand); - } - } -} - -// Secret local extension to Assembler::WhichOperand: -#define end_pc_operand (_WhichOperand_limit) - -address Assembler::locate_operand(address inst, WhichOperand which) { - // Decode the given instruction, and return the address of - // an embedded 32-bit operand word. - - // If "which" is disp32_operand, selects the displacement portion - // of an effective address specifier. - // If "which" is imm32_operand, selects the trailing immediate constant. - // If "which" is call32_operand, selects the displacement of a call or jump. - // Caller is responsible for ensuring that there is such an operand, - // and that it is 32 bits wide. - - // If "which" is end_pc_operand, find the end of the instruction. - - address ip = inst; - - debug_only(bool has_imm32 = false); - int tail_size = 0; // other random bytes (#32, #16, etc.) at end of insn - - again_after_prefix: - switch (0xFF & *ip++) { - - // These convenience macros generate groups of "case" labels for the switch. - #define REP4(x) (x)+0: case (x)+1: case (x)+2: case (x)+3 - #define REP8(x) (x)+0: case (x)+1: case (x)+2: case (x)+3: \ - case (x)+4: case (x)+5: case (x)+6: case (x)+7 - #define REP16(x) REP8((x)+0): \ - case REP8((x)+8) - - case CS_segment: - case SS_segment: - case DS_segment: - case ES_segment: - case FS_segment: - case GS_segment: - assert(ip == inst+1, "only one prefix allowed"); - goto again_after_prefix; - - case 0xFF: // pushl a; decl a; incl a; call a; jmp a - case 0x88: // movb a, r - case 0x89: // movl a, r - case 0x8A: // movb r, a - case 0x8B: // movl r, a - case 0x8F: // popl a - break; - - case 0x68: // pushl #32(oop?) - if (which == end_pc_operand) return ip + 4; - assert(which == imm32_operand, "pushl has no disp32"); - return ip; // not produced by emit_operand - - case 0x66: // movw ... (size prefix) - switch (0xFF & *ip++) { - case 0x8B: // movw r, a - case 0x89: // movw a, r - break; - case 0xC7: // movw a, #16 - tail_size = 2; // the imm16 - break; - case 0x0F: // several SSE/SSE2 variants - ip--; // reparse the 0x0F - goto again_after_prefix; - default: - ShouldNotReachHere(); - } - break; - - case REP8(0xB8): // movl r, #32(oop?) - if (which == end_pc_operand) return ip + 4; - assert(which == imm32_operand || which == disp32_operand, ""); - return ip; - - case 0x69: // imul r, a, #32 - case 0xC7: // movl a, #32(oop?) - tail_size = 4; - debug_only(has_imm32 = true); // has both kinds of operands! - break; - - case 0x0F: // movx..., etc. - switch (0xFF & *ip++) { - case 0x12: // movlps - case 0x28: // movaps - case 0x2E: // ucomiss - case 0x2F: // comiss - case 0x54: // andps - case 0x55: // andnps - case 0x56: // orps - case 0x57: // xorps - case 0x6E: // movd - case 0x7E: // movd - case 0xAE: // ldmxcsr a - // amd side says it these have both operands but that doesn't - // appear to be true. - // debug_only(has_imm32 = true); // has both kinds of operands! - break; - - case 0xAD: // shrd r, a, %cl - case 0xAF: // imul r, a - case 0xBE: // movsxb r, a - case 0xBF: // movsxw r, a - case 0xB6: // movzxb r, a - case 0xB7: // movzxw r, a - case REP16(0x40): // cmovl cc, r, a - case 0xB0: // cmpxchgb - case 0xB1: // cmpxchg - case 0xC1: // xaddl - case 0xC7: // cmpxchg8 - case REP16(0x90): // setcc a - // fall out of the switch to decode the address - break; - case 0xAC: // shrd r, a, #8 - tail_size = 1; // the imm8 - break; - case REP16(0x80): // jcc rdisp32 - if (which == end_pc_operand) return ip + 4; - assert(which == call32_operand, "jcc has no disp32 or imm32"); - return ip; - default: - ShouldNotReachHere(); - } - break; - - case 0x81: // addl a, #32; addl r, #32 - // also: orl, adcl, sbbl, andl, subl, xorl, cmpl - // in the case of cmpl, the imm32 might be an oop - tail_size = 4; - debug_only(has_imm32 = true); // has both kinds of operands! - break; - - case 0x85: // test r/m, r - break; - - case 0x83: // addl a, #8; addl r, #8 - // also: orl, adcl, sbbl, andl, subl, xorl, cmpl - tail_size = 1; - break; - - case 0x9B: - switch (0xFF & *ip++) { - case 0xD9: // fnstcw a - break; - default: - ShouldNotReachHere(); - } - break; - - case REP4(0x00): // addb a, r; addl a, r; addb r, a; addl r, a - case REP4(0x10): // adc... - case REP4(0x20): // and... - case REP4(0x30): // xor... - case REP4(0x08): // or... - case REP4(0x18): // sbb... - case REP4(0x28): // sub... - case REP4(0x38): // cmp... - case 0xF7: // mull a - case 0x8D: // leal r, a - case 0x87: // xchg r, a - break; - - case 0xC1: // sal a, #8; sar a, #8; shl a, #8; shr a, #8 - case 0xC6: // movb a, #8 - case 0x80: // cmpb a, #8 - case 0x6B: // imul r, a, #8 - tail_size = 1; // the imm8 - break; - - case 0xE8: // call rdisp32 - case 0xE9: // jmp rdisp32 - if (which == end_pc_operand) return ip + 4; - assert(which == call32_operand, "call has no disp32 or imm32"); - return ip; - - case 0xD1: // sal a, 1; sar a, 1; shl a, 1; shr a, 1 - case 0xD3: // sal a, %cl; sar a, %cl; shl a, %cl; shr a, %cl - case 0xD9: // fld_s a; fst_s a; fstp_s a; fldcw a - case 0xDD: // fld_d a; fst_d a; fstp_d a - case 0xDB: // fild_s a; fistp_s a; fld_x a; fstp_x a - case 0xDF: // fild_d a; fistp_d a - case 0xD8: // fadd_s a; fsubr_s a; fmul_s a; fdivr_s a; fcomp_s a - case 0xDC: // fadd_d a; fsubr_d a; fmul_d a; fdivr_d a; fcomp_d a - case 0xDE: // faddp_d a; fsubrp_d a; fmulp_d a; fdivrp_d a; fcompp_d a - break; - - case 0xF3: // For SSE - case 0xF2: // For SSE2 - ip++; ip++; - break; - - default: - ShouldNotReachHere(); - - #undef REP8 - #undef REP16 - } - - assert(which != call32_operand, "instruction is not a call, jmp, or jcc"); - assert(which != imm32_operand || has_imm32, "instruction has no imm32 field"); - - // parse the output of emit_operand - int op2 = 0xFF & *ip++; - int base = op2 & 0x07; - int op3 = -1; - const int b100 = 4; - const int b101 = 5; - if (base == b100 && (op2 >> 6) != 3) { - op3 = 0xFF & *ip++; - base = op3 & 0x07; // refetch the base - } - // now ip points at the disp (if any) - - switch (op2 >> 6) { - case 0: - // [00 reg 100][ss index base] - // [00 reg 100][00 100 rsp] - // [00 reg base] - // [00 reg 100][ss index 101][disp32] - // [00 reg 101] [disp32] - - if (base == b101) { - if (which == disp32_operand) - return ip; // caller wants the disp32 - ip += 4; // skip the disp32 - } - break; - - case 1: - // [01 reg 100][ss index base][disp8] - // [01 reg 100][00 100 rsp][disp8] - // [01 reg base] [disp8] - ip += 1; // skip the disp8 - break; - - case 2: - // [10 reg 100][ss index base][disp32] - // [10 reg 100][00 100 rsp][disp32] - // [10 reg base] [disp32] - if (which == disp32_operand) - return ip; // caller wants the disp32 - ip += 4; // skip the disp32 - break; - - case 3: - // [11 reg base] (not a memory addressing mode) - break; - } - - if (which == end_pc_operand) { - return ip + tail_size; - } - - assert(which == imm32_operand, "instruction has only an imm32 field"); - return ip; -} - -address Assembler::locate_next_instruction(address inst) { - // Secretly share code with locate_operand: - return locate_operand(inst, end_pc_operand); -} - - -#ifdef ASSERT -void Assembler::check_relocation(RelocationHolder const& rspec, int format) { - address inst = inst_mark(); - assert(inst != NULL && inst < pc(), "must point to beginning of instruction"); - address opnd; - - Relocation* r = rspec.reloc(); - if (r->type() == relocInfo::none) { - return; - } else if (r->is_call() || format == call32_operand) { - // assert(format == imm32_operand, "cannot specify a nonzero format"); - opnd = locate_operand(inst, call32_operand); - } else if (r->is_data()) { - assert(format == imm32_operand || format == disp32_operand, "format ok"); - opnd = locate_operand(inst, (WhichOperand)format); - } else { - assert(format == imm32_operand, "cannot specify a format"); - return; - } - assert(opnd == pc(), "must put operand where relocs can find it"); -} -#endif - - - -void Assembler::emit_operand(Register reg, Address adr) { - emit_operand(reg, adr._base, adr._index, adr._scale, adr._disp, adr._rspec); -} - - -void Assembler::emit_farith(int b1, int b2, int i) { - assert(isByte(b1) && isByte(b2), "wrong opcode"); - assert(0 <= i && i < 8, "illegal stack offset"); - emit_byte(b1); - emit_byte(b2 + i); -} - - -void Assembler::pushad() { - emit_byte(0x60); -} - -void Assembler::popad() { - emit_byte(0x61); -} - -void Assembler::pushfd() { - emit_byte(0x9C); -} - -void Assembler::popfd() { - emit_byte(0x9D); -} - -void Assembler::pushl(int imm32) { - emit_byte(0x68); - emit_long(imm32); -} - -#ifndef _LP64 -void Assembler::push_literal32(int32_t imm32, RelocationHolder const& rspec) { - InstructionMark im(this); - emit_byte(0x68); - emit_data(imm32, rspec, 0); -} -#endif // _LP64 - -void Assembler::pushl(Register src) { - emit_byte(0x50 | src->encoding()); -} - - -void Assembler::pushl(Address src) { - InstructionMark im(this); - emit_byte(0xFF); - emit_operand(rsi, src); -} - -void Assembler::popl(Register dst) { - emit_byte(0x58 | dst->encoding()); -} - - -void Assembler::popl(Address dst) { - InstructionMark im(this); - emit_byte(0x8F); - emit_operand(rax, dst); -} - - -void Assembler::prefix(Prefix p) { - a_byte(p); -} - - -void Assembler::movb(Register dst, Address src) { - assert(dst->has_byte_register(), "must have byte register"); - InstructionMark im(this); - emit_byte(0x8A); - emit_operand(dst, src); -} - - -void Assembler::movb(Address dst, int imm8) { - InstructionMark im(this); - emit_byte(0xC6); - emit_operand(rax, dst); - emit_byte(imm8); -} - - -void Assembler::movb(Address dst, Register src) { - assert(src->has_byte_register(), "must have byte register"); - InstructionMark im(this); - emit_byte(0x88); - emit_operand(src, dst); -} - - -void Assembler::movw(Address dst, int imm16) { - InstructionMark im(this); - - emit_byte(0x66); // switch to 16-bit mode - emit_byte(0xC7); - emit_operand(rax, dst); - emit_word(imm16); -} - - -void Assembler::movw(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x66); - emit_byte(0x8B); - emit_operand(dst, src); -} - - -void Assembler::movw(Address dst, Register src) { - InstructionMark im(this); - emit_byte(0x66); - emit_byte(0x89); - emit_operand(src, dst); -} - - -void Assembler::movl(Register dst, int imm32) { - emit_byte(0xB8 | dst->encoding()); - emit_long(imm32); -} - -#ifndef _LP64 -void Assembler::mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec) { - - InstructionMark im(this); - emit_byte(0xB8 | dst->encoding()); - emit_data((int)imm32, rspec, 0); -} -#endif // _LP64 - -void Assembler::movl(Register dst, Register src) { - emit_byte(0x8B); - emit_byte(0xC0 | (dst->encoding() << 3) | src->encoding()); -} - - -void Assembler::movl(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x8B); - emit_operand(dst, src); -} - - -void Assembler::movl(Address dst, int imm32) { - InstructionMark im(this); - emit_byte(0xC7); - emit_operand(rax, dst); - emit_long(imm32); -} - -#ifndef _LP64 -void Assembler::mov_literal32(Address dst, int32_t imm32, RelocationHolder const& rspec) { - InstructionMark im(this); - emit_byte(0xC7); - emit_operand(rax, dst); - emit_data((int)imm32, rspec, 0); -} -#endif // _LP64 - -void Assembler::movl(Address dst, Register src) { - InstructionMark im(this); - emit_byte(0x89); - emit_operand(src, dst); -} - -void Assembler::movsxb(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0xBE); - emit_operand(dst, src); -} - -void Assembler::movsxb(Register dst, Register src) { - assert(src->has_byte_register(), "must have byte register"); - emit_byte(0x0F); - emit_byte(0xBE); - emit_byte(0xC0 | (dst->encoding() << 3) | src->encoding()); -} - - -void Assembler::movsxw(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0xBF); - emit_operand(dst, src); -} - - -void Assembler::movsxw(Register dst, Register src) { - emit_byte(0x0F); - emit_byte(0xBF); - emit_byte(0xC0 | (dst->encoding() << 3) | src->encoding()); -} - - -void Assembler::movzxb(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0xB6); - emit_operand(dst, src); -} - - -void Assembler::movzxb(Register dst, Register src) { - assert(src->has_byte_register(), "must have byte register"); - emit_byte(0x0F); - emit_byte(0xB6); - emit_byte(0xC0 | (dst->encoding() << 3) | src->encoding()); -} - - -void Assembler::movzxw(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0xB7); - emit_operand(dst, src); -} - - -void Assembler::movzxw(Register dst, Register src) { - emit_byte(0x0F); - emit_byte(0xB7); - emit_byte(0xC0 | (dst->encoding() << 3) | src->encoding()); -} - - -void Assembler::cmovl(Condition cc, Register dst, Register src) { - guarantee(VM_Version::supports_cmov(), "illegal instruction"); - emit_byte(0x0F); - emit_byte(0x40 | cc); - emit_byte(0xC0 | (dst->encoding() << 3) | src->encoding()); -} - - -void Assembler::cmovl(Condition cc, Register dst, Address src) { - guarantee(VM_Version::supports_cmov(), "illegal instruction"); - // The code below seems to be wrong - however the manual is inconclusive - // do not use for now (remember to enable all callers when fixing this) - Unimplemented(); - // wrong bytes? - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0x40 | cc); - emit_operand(dst, src); -} - - -void Assembler::prefetcht0(Address src) { - assert(VM_Version::supports_sse(), "must support"); - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0x18); - emit_operand(rcx, src); // 1, src -} - - -void Assembler::prefetcht1(Address src) { - assert(VM_Version::supports_sse(), "must support"); - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0x18); - emit_operand(rdx, src); // 2, src -} - - -void Assembler::prefetcht2(Address src) { - assert(VM_Version::supports_sse(), "must support"); - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0x18); - emit_operand(rbx, src); // 3, src -} - - -void Assembler::prefetchnta(Address src) { - assert(VM_Version::supports_sse2(), "must support"); - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0x18); - emit_operand(rax, src); // 0, src -} - - -void Assembler::prefetchw(Address src) { - assert(VM_Version::supports_3dnow(), "must support"); - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0x0D); - emit_operand(rcx, src); // 1, src -} - - -void Assembler::prefetchr(Address src) { - assert(VM_Version::supports_3dnow(), "must support"); - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0x0D); - emit_operand(rax, src); // 0, src -} - - -void Assembler::adcl(Register dst, int imm32) { - emit_arith(0x81, 0xD0, dst, imm32); -} - - -void Assembler::adcl(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x13); - emit_operand(dst, src); -} - - -void Assembler::adcl(Register dst, Register src) { - emit_arith(0x13, 0xC0, dst, src); -} - - -void Assembler::addl(Address dst, int imm32) { - InstructionMark im(this); - emit_arith_operand(0x81,rax,dst,imm32); -} - - -void Assembler::addl(Address dst, Register src) { - InstructionMark im(this); - emit_byte(0x01); - emit_operand(src, dst); -} - - -void Assembler::addl(Register dst, int imm32) { - emit_arith(0x81, 0xC0, dst, imm32); -} - - -void Assembler::addl(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x03); - emit_operand(dst, src); -} - - -void Assembler::addl(Register dst, Register src) { - emit_arith(0x03, 0xC0, dst, src); -} - - -void Assembler::andl(Register dst, int imm32) { - emit_arith(0x81, 0xE0, dst, imm32); -} - - -void Assembler::andl(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x23); - emit_operand(dst, src); -} - - -void Assembler::andl(Register dst, Register src) { - emit_arith(0x23, 0xC0, dst, src); -} - - -void Assembler::cmpb(Address dst, int imm8) { - InstructionMark im(this); - emit_byte(0x80); - emit_operand(rdi, dst); - emit_byte(imm8); -} - -void Assembler::cmpw(Address dst, int imm16) { - InstructionMark im(this); - emit_byte(0x66); - emit_byte(0x81); - emit_operand(rdi, dst); - emit_word(imm16); -} - -void Assembler::cmpl(Address dst, int imm32) { - InstructionMark im(this); - emit_byte(0x81); - emit_operand(rdi, dst); - emit_long(imm32); -} - -#ifndef _LP64 -void Assembler::cmp_literal32(Register src1, int32_t imm32, RelocationHolder const& rspec) { - InstructionMark im(this); - emit_byte(0x81); - emit_byte(0xF8 | src1->encoding()); - emit_data(imm32, rspec, 0); -} - -void Assembler::cmp_literal32(Address src1, int32_t imm32, RelocationHolder const& rspec) { - InstructionMark im(this); - emit_byte(0x81); - emit_operand(rdi, src1); - emit_data(imm32, rspec, 0); -} -#endif // _LP64 - - -void Assembler::cmpl(Register dst, int imm32) { - emit_arith(0x81, 0xF8, dst, imm32); -} - - -void Assembler::cmpl(Register dst, Register src) { - emit_arith(0x3B, 0xC0, dst, src); -} - - -void Assembler::cmpl(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x3B); - emit_operand(dst, src); -} - - -void Assembler::decl(Register dst) { - // Don't use it directly. Use MacroAssembler::decrement() instead. - emit_byte(0x48 | dst->encoding()); -} - - -void Assembler::decl(Address dst) { - // Don't use it directly. Use MacroAssembler::decrement() instead. - InstructionMark im(this); - emit_byte(0xFF); - emit_operand(rcx, dst); -} - - -void Assembler::idivl(Register src) { - emit_byte(0xF7); - emit_byte(0xF8 | src->encoding()); -} - - -void Assembler::cdql() { - emit_byte(0x99); -} - - -void Assembler::imull(Register dst, Register src) { - emit_byte(0x0F); - emit_byte(0xAF); - emit_byte(0xC0 | dst->encoding() << 3 | src->encoding()); -} - - -void Assembler::imull(Register dst, Register src, int value) { - if (is8bit(value)) { - emit_byte(0x6B); - emit_byte(0xC0 | dst->encoding() << 3 | src->encoding()); - emit_byte(value); - } else { - emit_byte(0x69); - emit_byte(0xC0 | dst->encoding() << 3 | src->encoding()); - emit_long(value); - } -} - - -void Assembler::incl(Register dst) { - // Don't use it directly. Use MacroAssembler::increment() instead. - emit_byte(0x40 | dst->encoding()); -} - - -void Assembler::incl(Address dst) { - // Don't use it directly. Use MacroAssembler::increment() instead. - InstructionMark im(this); - emit_byte(0xFF); - emit_operand(rax, dst); -} - - -void Assembler::leal(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x8D); - emit_operand(dst, src); -} - -void Assembler::mull(Address src) { - InstructionMark im(this); - emit_byte(0xF7); - emit_operand(rsp, src); -} - - -void Assembler::mull(Register src) { - emit_byte(0xF7); - emit_byte(0xE0 | src->encoding()); -} - - -void Assembler::negl(Register dst) { - emit_byte(0xF7); - emit_byte(0xD8 | dst->encoding()); -} - - -void Assembler::notl(Register dst) { - emit_byte(0xF7); - emit_byte(0xD0 | dst->encoding()); -} - - -void Assembler::orl(Address dst, int imm32) { - InstructionMark im(this); - emit_byte(0x81); - emit_operand(rcx, dst); - emit_long(imm32); -} - -void Assembler::orl(Register dst, int imm32) { - emit_arith(0x81, 0xC8, dst, imm32); -} - - -void Assembler::orl(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x0B); - emit_operand(dst, src); -} - - -void Assembler::orl(Register dst, Register src) { - emit_arith(0x0B, 0xC0, dst, src); -} - - -void Assembler::rcll(Register dst, int imm8) { - assert(isShiftCount(imm8), "illegal shift count"); - if (imm8 == 1) { - emit_byte(0xD1); - emit_byte(0xD0 | dst->encoding()); - } else { - emit_byte(0xC1); - emit_byte(0xD0 | dst->encoding()); - emit_byte(imm8); - } -} - - -void Assembler::sarl(Register dst, int imm8) { - assert(isShiftCount(imm8), "illegal shift count"); - if (imm8 == 1) { - emit_byte(0xD1); - emit_byte(0xF8 | dst->encoding()); - } else { - emit_byte(0xC1); - emit_byte(0xF8 | dst->encoding()); - emit_byte(imm8); - } -} - - -void Assembler::sarl(Register dst) { - emit_byte(0xD3); - emit_byte(0xF8 | dst->encoding()); -} - - -void Assembler::sbbl(Address dst, int imm32) { - InstructionMark im(this); - emit_arith_operand(0x81,rbx,dst,imm32); -} - - -void Assembler::sbbl(Register dst, int imm32) { - emit_arith(0x81, 0xD8, dst, imm32); -} - - -void Assembler::sbbl(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x1B); - emit_operand(dst, src); -} - - -void Assembler::sbbl(Register dst, Register src) { - emit_arith(0x1B, 0xC0, dst, src); -} - - -void Assembler::shldl(Register dst, Register src) { - emit_byte(0x0F); - emit_byte(0xA5); - emit_byte(0xC0 | src->encoding() << 3 | dst->encoding()); -} - - -void Assembler::shll(Register dst, int imm8) { - assert(isShiftCount(imm8), "illegal shift count"); - if (imm8 == 1 ) { - emit_byte(0xD1); - emit_byte(0xE0 | dst->encoding()); - } else { - emit_byte(0xC1); - emit_byte(0xE0 | dst->encoding()); - emit_byte(imm8); - } -} - - -void Assembler::shll(Register dst) { - emit_byte(0xD3); - emit_byte(0xE0 | dst->encoding()); -} - - -void Assembler::shrdl(Register dst, Register src) { - emit_byte(0x0F); - emit_byte(0xAD); - emit_byte(0xC0 | src->encoding() << 3 | dst->encoding()); -} - - -void Assembler::shrl(Register dst, int imm8) { - assert(isShiftCount(imm8), "illegal shift count"); - emit_byte(0xC1); - emit_byte(0xE8 | dst->encoding()); - emit_byte(imm8); -} - - -void Assembler::shrl(Register dst) { - emit_byte(0xD3); - emit_byte(0xE8 | dst->encoding()); -} - - -void Assembler::subl(Address dst, int imm32) { - if (is8bit(imm32)) { - InstructionMark im(this); - emit_byte(0x83); - emit_operand(rbp, dst); - emit_byte(imm32 & 0xFF); - } else { - InstructionMark im(this); - emit_byte(0x81); - emit_operand(rbp, dst); - emit_long(imm32); - } -} - - -void Assembler::subl(Register dst, int imm32) { - emit_arith(0x81, 0xE8, dst, imm32); -} - - -void Assembler::subl(Address dst, Register src) { - InstructionMark im(this); - emit_byte(0x29); - emit_operand(src, dst); -} - - -void Assembler::subl(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x2B); - emit_operand(dst, src); -} - - -void Assembler::subl(Register dst, Register src) { - emit_arith(0x2B, 0xC0, dst, src); -} - - -void Assembler::testb(Register dst, int imm8) { - assert(dst->has_byte_register(), "must have byte register"); - emit_arith_b(0xF6, 0xC0, dst, imm8); -} - - -void Assembler::testl(Register dst, int imm32) { - // not using emit_arith because test - // doesn't support sign-extension of - // 8bit operands - if (dst->encoding() == 0) { - emit_byte(0xA9); - } else { - emit_byte(0xF7); - emit_byte(0xC0 | dst->encoding()); - } - emit_long(imm32); -} - - -void Assembler::testl(Register dst, Register src) { - emit_arith(0x85, 0xC0, dst, src); -} - -void Assembler::testl(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x85); - emit_operand(dst, src); -} - -void Assembler::xaddl(Address dst, Register src) { - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0xC1); - emit_operand(src, dst); -} - -void Assembler::xorl(Register dst, int imm32) { - emit_arith(0x81, 0xF0, dst, imm32); -} - - -void Assembler::xorl(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x33); - emit_operand(dst, src); -} - - -void Assembler::xorl(Register dst, Register src) { - emit_arith(0x33, 0xC0, dst, src); -} - - -void Assembler::bswap(Register reg) { - emit_byte(0x0F); - emit_byte(0xC8 | reg->encoding()); -} - - -void Assembler::lock() { - if (Atomics & 1) { - // Emit either nothing, a NOP, or a NOP: prefix - emit_byte(0x90) ; - } else { - emit_byte(0xF0); - } -} - - -void Assembler::xchg(Register reg, Address adr) { - InstructionMark im(this); - emit_byte(0x87); - emit_operand(reg, adr); -} - - -void Assembler::xchgl(Register dst, Register src) { - emit_byte(0x87); - emit_byte(0xc0 | dst->encoding() << 3 | src->encoding()); -} - - -// The 32-bit cmpxchg compares the value at adr with the contents of rax, -// and stores reg into adr if so; otherwise, the value at adr is loaded into rax,. -// The ZF is set if the compared values were equal, and cleared otherwise. -void Assembler::cmpxchg(Register reg, Address adr) { - if (Atomics & 2) { - // caveat: no instructionmark, so this isn't relocatable. - // Emit a synthetic, non-atomic, CAS equivalent. - // Beware. The synthetic form sets all ICCs, not just ZF. - // cmpxchg r,[m] is equivalent to rax, = CAS (m, rax, r) - cmpl (rax, adr) ; - movl (rax, adr) ; - if (reg != rax) { - Label L ; - jcc (Assembler::notEqual, L) ; - movl (adr, reg) ; - bind (L) ; - } - } else { - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0xB1); - emit_operand(reg, adr); - } -} - -// The 64-bit cmpxchg compares the value at adr with the contents of rdx:rax, -// and stores rcx:rbx into adr if so; otherwise, the value at adr is loaded -// into rdx:rax. The ZF is set if the compared values were equal, and cleared otherwise. -void Assembler::cmpxchg8(Address adr) { - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0xc7); - emit_operand(rcx, adr); -} - -void Assembler::hlt() { - emit_byte(0xF4); -} - - -void Assembler::addr_nop_4() { - // 4 bytes: NOP DWORD PTR [EAX+0] - emit_byte(0x0F); - emit_byte(0x1F); - emit_byte(0x40); // emit_rm(cbuf, 0x1, EAX_enc, EAX_enc); - emit_byte(0); // 8-bits offset (1 byte) -} - -void Assembler::addr_nop_5() { - // 5 bytes: NOP DWORD PTR [EAX+EAX*0+0] 8-bits offset - emit_byte(0x0F); - emit_byte(0x1F); - emit_byte(0x44); // emit_rm(cbuf, 0x1, EAX_enc, 0x4); - emit_byte(0x00); // emit_rm(cbuf, 0x0, EAX_enc, EAX_enc); - emit_byte(0); // 8-bits offset (1 byte) -} - -void Assembler::addr_nop_7() { - // 7 bytes: NOP DWORD PTR [EAX+0] 32-bits offset - emit_byte(0x0F); - emit_byte(0x1F); - emit_byte(0x80); // emit_rm(cbuf, 0x2, EAX_enc, EAX_enc); - emit_long(0); // 32-bits offset (4 bytes) -} - -void Assembler::addr_nop_8() { - // 8 bytes: NOP DWORD PTR [EAX+EAX*0+0] 32-bits offset - emit_byte(0x0F); - emit_byte(0x1F); - emit_byte(0x84); // emit_rm(cbuf, 0x2, EAX_enc, 0x4); - emit_byte(0x00); // emit_rm(cbuf, 0x0, EAX_enc, EAX_enc); - emit_long(0); // 32-bits offset (4 bytes) -} - -void Assembler::nop(int i) { - assert(i > 0, " "); - if (UseAddressNop && VM_Version::is_intel()) { - // - // Using multi-bytes nops "0x0F 0x1F [address]" for Intel - // 1: 0x90 - // 2: 0x66 0x90 - // 3: 0x66 0x66 0x90 (don't use "0x0F 0x1F 0x00" - need patching safe padding) - // 4: 0x0F 0x1F 0x40 0x00 - // 5: 0x0F 0x1F 0x44 0x00 0x00 - // 6: 0x66 0x0F 0x1F 0x44 0x00 0x00 - // 7: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 - // 8: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 - // 9: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 - // 10: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 - // 11: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 - - // The rest coding is Intel specific - don't use consecutive address nops - - // 12: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90 - // 13: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90 - // 14: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90 - // 15: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90 - - while(i >= 15) { - // For Intel don't generate consecutive addess nops (mix with regular nops) - i -= 15; - emit_byte(0x66); // size prefix - emit_byte(0x66); // size prefix - emit_byte(0x66); // size prefix - addr_nop_8(); - emit_byte(0x66); // size prefix - emit_byte(0x66); // size prefix - emit_byte(0x66); // size prefix - emit_byte(0x90); // nop - } - switch (i) { - case 14: - emit_byte(0x66); // size prefix - case 13: - emit_byte(0x66); // size prefix - case 12: - addr_nop_8(); - emit_byte(0x66); // size prefix - emit_byte(0x66); // size prefix - emit_byte(0x66); // size prefix - emit_byte(0x90); // nop - break; - case 11: - emit_byte(0x66); // size prefix - case 10: - emit_byte(0x66); // size prefix - case 9: - emit_byte(0x66); // size prefix - case 8: - addr_nop_8(); - break; - case 7: - addr_nop_7(); - break; - case 6: - emit_byte(0x66); // size prefix - case 5: - addr_nop_5(); - break; - case 4: - addr_nop_4(); - break; - case 3: - // Don't use "0x0F 0x1F 0x00" - need patching safe padding - emit_byte(0x66); // size prefix - case 2: - emit_byte(0x66); // size prefix - case 1: - emit_byte(0x90); // nop - break; - default: - assert(i == 0, " "); - } - return; - } - if (UseAddressNop && VM_Version::is_amd()) { - // - // Using multi-bytes nops "0x0F 0x1F [address]" for AMD. - // 1: 0x90 - // 2: 0x66 0x90 - // 3: 0x66 0x66 0x90 (don't use "0x0F 0x1F 0x00" - need patching safe padding) - // 4: 0x0F 0x1F 0x40 0x00 - // 5: 0x0F 0x1F 0x44 0x00 0x00 - // 6: 0x66 0x0F 0x1F 0x44 0x00 0x00 - // 7: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 - // 8: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 - // 9: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 - // 10: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 - // 11: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 - - // The rest coding is AMD specific - use consecutive address nops - - // 12: 0x66 0x0F 0x1F 0x44 0x00 0x00 0x66 0x0F 0x1F 0x44 0x00 0x00 - // 13: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 0x66 0x0F 0x1F 0x44 0x00 0x00 - // 14: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 - // 15: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 - // 16: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 - // Size prefixes (0x66) are added for larger sizes - - while(i >= 22) { - i -= 11; - emit_byte(0x66); // size prefix - emit_byte(0x66); // size prefix - emit_byte(0x66); // size prefix - addr_nop_8(); - } - // Generate first nop for size between 21-12 - switch (i) { - case 21: - i -= 1; - emit_byte(0x66); // size prefix - case 20: - case 19: - i -= 1; - emit_byte(0x66); // size prefix - case 18: - case 17: - i -= 1; - emit_byte(0x66); // size prefix - case 16: - case 15: - i -= 8; - addr_nop_8(); - break; - case 14: - case 13: - i -= 7; - addr_nop_7(); - break; - case 12: - i -= 6; - emit_byte(0x66); // size prefix - addr_nop_5(); - break; - default: - assert(i < 12, " "); - } - - // Generate second nop for size between 11-1 - switch (i) { - case 11: - emit_byte(0x66); // size prefix - case 10: - emit_byte(0x66); // size prefix - case 9: - emit_byte(0x66); // size prefix - case 8: - addr_nop_8(); - break; - case 7: - addr_nop_7(); - break; - case 6: - emit_byte(0x66); // size prefix - case 5: - addr_nop_5(); - break; - case 4: - addr_nop_4(); - break; - case 3: - // Don't use "0x0F 0x1F 0x00" - need patching safe padding - emit_byte(0x66); // size prefix - case 2: - emit_byte(0x66); // size prefix - case 1: - emit_byte(0x90); // nop - break; - default: - assert(i == 0, " "); - } - return; - } - - // Using nops with size prefixes "0x66 0x90". - // From AMD Optimization Guide: - // 1: 0x90 - // 2: 0x66 0x90 - // 3: 0x66 0x66 0x90 - // 4: 0x66 0x66 0x66 0x90 - // 5: 0x66 0x66 0x90 0x66 0x90 - // 6: 0x66 0x66 0x90 0x66 0x66 0x90 - // 7: 0x66 0x66 0x66 0x90 0x66 0x66 0x90 - // 8: 0x66 0x66 0x66 0x90 0x66 0x66 0x66 0x90 - // 9: 0x66 0x66 0x90 0x66 0x66 0x90 0x66 0x66 0x90 - // 10: 0x66 0x66 0x66 0x90 0x66 0x66 0x90 0x66 0x66 0x90 - // - while(i > 12) { - i -= 4; - emit_byte(0x66); // size prefix - emit_byte(0x66); - emit_byte(0x66); - emit_byte(0x90); // nop - } - // 1 - 12 nops - if(i > 8) { - if(i > 9) { - i -= 1; - emit_byte(0x66); - } - i -= 3; - emit_byte(0x66); - emit_byte(0x66); - emit_byte(0x90); - } - // 1 - 8 nops - if(i > 4) { - if(i > 6) { - i -= 1; - emit_byte(0x66); - } - i -= 3; - emit_byte(0x66); - emit_byte(0x66); - emit_byte(0x90); - } - switch (i) { - case 4: - emit_byte(0x66); - case 3: - emit_byte(0x66); - case 2: - emit_byte(0x66); - case 1: - emit_byte(0x90); - break; - default: - assert(i == 0, " "); - } -} - -void Assembler::ret(int imm16) { - if (imm16 == 0) { - emit_byte(0xC3); - } else { - emit_byte(0xC2); - emit_word(imm16); - } -} - - -void Assembler::set_byte_if_not_zero(Register dst) { - emit_byte(0x0F); - emit_byte(0x95); - emit_byte(0xE0 | dst->encoding()); -} - - -// copies a single word from [esi] to [edi] -void Assembler::smovl() { - emit_byte(0xA5); -} - -// copies data from [esi] to [edi] using rcx double words (m32) -void Assembler::rep_movl() { - emit_byte(0xF3); - emit_byte(0xA5); -} - - -// sets rcx double words (m32) with rax, value at [edi] -void Assembler::rep_set() { - emit_byte(0xF3); - emit_byte(0xAB); -} - -// scans rcx double words (m32) at [edi] for occurance of rax, -void Assembler::repne_scan() { - emit_byte(0xF2); - emit_byte(0xAF); -} - - -void Assembler::setb(Condition cc, Register dst) { - assert(0 <= cc && cc < 16, "illegal cc"); - emit_byte(0x0F); - emit_byte(0x90 | cc); - emit_byte(0xC0 | dst->encoding()); -} - -void Assembler::cld() { - emit_byte(0xfc); -} - -void Assembler::std() { - emit_byte(0xfd); -} - -void Assembler::emit_raw (unsigned char b) { - emit_byte (b) ; -} - -// Serializes memory. -void Assembler::membar() { - // Memory barriers are only needed on multiprocessors - if (os::is_MP()) { - if( VM_Version::supports_sse2() ) { - emit_byte( 0x0F ); // MFENCE; faster blows no regs - emit_byte( 0xAE ); - emit_byte( 0xF0 ); - } else { - // All usable chips support "locked" instructions which suffice - // as barriers, and are much faster than the alternative of - // using cpuid instruction. We use here a locked add [esp],0. - // This is conveniently otherwise a no-op except for blowing - // flags (which we save and restore.) - pushfd(); // Save eflags register - lock(); - addl(Address(rsp, 0), 0);// Assert the lock# signal here - popfd(); // Restore eflags register - } - } -} - -// Identify processor type and features -void Assembler::cpuid() { - // Note: we can't assert VM_Version::supports_cpuid() here - // because this instruction is used in the processor - // identification code. - emit_byte( 0x0F ); - emit_byte( 0xA2 ); -} - -void Assembler::call(Label& L, relocInfo::relocType rtype) { - if (L.is_bound()) { - const int long_size = 5; - int offs = target(L) - pc(); - assert(offs <= 0, "assembler error"); - InstructionMark im(this); - // 1110 1000 #32-bit disp - emit_byte(0xE8); - emit_data(offs - long_size, rtype, 0); - } else { - InstructionMark im(this); - // 1110 1000 #32-bit disp - L.add_patch_at(code(), locator()); - emit_byte(0xE8); - emit_data(int(0), rtype, 0); - } -} - -void Assembler::call(Register dst) { - emit_byte(0xFF); - emit_byte(0xD0 | dst->encoding()); -} - - -void Assembler::call(Address adr) { - InstructionMark im(this); - relocInfo::relocType rtype = adr.reloc(); - if (rtype != relocInfo::runtime_call_type) { - emit_byte(0xFF); - emit_operand(rdx, adr); - } else { - assert(false, "ack"); - } - -} - -void Assembler::call_literal(address dest, RelocationHolder const& rspec) { - InstructionMark im(this); - emit_byte(0xE8); - intptr_t disp = dest - (_code_pos + sizeof(int32_t)); - assert(dest != NULL, "must have a target"); - emit_data(disp, rspec, call32_operand); - -} - -void Assembler::jmp(Register entry) { - emit_byte(0xFF); - emit_byte(0xE0 | entry->encoding()); -} - - -void Assembler::jmp(Address adr) { - InstructionMark im(this); - emit_byte(0xFF); - emit_operand(rsp, adr); -} - -void Assembler::jmp_literal(address dest, RelocationHolder const& rspec) { - InstructionMark im(this); - emit_byte(0xE9); - assert(dest != NULL, "must have a target"); - intptr_t disp = dest - (_code_pos + sizeof(int32_t)); - emit_data(disp, rspec.reloc(), call32_operand); -} - -void Assembler::jmp(Label& L, relocInfo::relocType rtype) { - if (L.is_bound()) { - address entry = target(L); - assert(entry != NULL, "jmp most probably wrong"); - InstructionMark im(this); - const int short_size = 2; - const int long_size = 5; - intptr_t offs = entry - _code_pos; - if (rtype == relocInfo::none && is8bit(offs - short_size)) { - emit_byte(0xEB); - emit_byte((offs - short_size) & 0xFF); - } else { - emit_byte(0xE9); - emit_long(offs - long_size); - } - } else { - // By default, forward jumps are always 32-bit displacements, since - // we can't yet know where the label will be bound. If you're sure that - // the forward jump will not run beyond 256 bytes, use jmpb to - // force an 8-bit displacement. - InstructionMark im(this); - relocate(rtype); - L.add_patch_at(code(), locator()); - emit_byte(0xE9); - emit_long(0); - } -} - -void Assembler::jmpb(Label& L) { - if (L.is_bound()) { - const int short_size = 2; - address entry = target(L); - assert(is8bit((entry - _code_pos) + short_size), - "Dispacement too large for a short jmp"); - assert(entry != NULL, "jmp most probably wrong"); - intptr_t offs = entry - _code_pos; - emit_byte(0xEB); - emit_byte((offs - short_size) & 0xFF); - } else { - InstructionMark im(this); - L.add_patch_at(code(), locator()); - emit_byte(0xEB); - emit_byte(0); - } -} - -void Assembler::jcc(Condition cc, Label& L, relocInfo::relocType rtype) { - InstructionMark im(this); - relocate(rtype); - assert((0 <= cc) && (cc < 16), "illegal cc"); - if (L.is_bound()) { - address dst = target(L); - assert(dst != NULL, "jcc most probably wrong"); - - const int short_size = 2; - const int long_size = 6; - int offs = (int)dst - ((int)_code_pos); - if (rtype == relocInfo::none && is8bit(offs - short_size)) { - // 0111 tttn #8-bit disp - emit_byte(0x70 | cc); - emit_byte((offs - short_size) & 0xFF); - } else { - // 0000 1111 1000 tttn #32-bit disp - emit_byte(0x0F); - emit_byte(0x80 | cc); - emit_long(offs - long_size); - } - } else { - // Note: could eliminate cond. jumps to this jump if condition - // is the same however, seems to be rather unlikely case. - // Note: use jccb() if label to be bound is very close to get - // an 8-bit displacement - L.add_patch_at(code(), locator()); - emit_byte(0x0F); - emit_byte(0x80 | cc); - emit_long(0); - } -} - -void Assembler::jccb(Condition cc, Label& L) { - if (L.is_bound()) { - const int short_size = 2; - address entry = target(L); - assert(is8bit((intptr_t)entry - ((intptr_t)_code_pos + short_size)), - "Dispacement too large for a short jmp"); - intptr_t offs = (intptr_t)entry - (intptr_t)_code_pos; - // 0111 tttn #8-bit disp - emit_byte(0x70 | cc); - emit_byte((offs - short_size) & 0xFF); - jcc(cc, L); - } else { - InstructionMark im(this); - L.add_patch_at(code(), locator()); - emit_byte(0x70 | cc); - emit_byte(0); - } -} - -// FPU instructions - -void Assembler::fld1() { - emit_byte(0xD9); - emit_byte(0xE8); -} - - -void Assembler::fldz() { - emit_byte(0xD9); - emit_byte(0xEE); -} - - -void Assembler::fld_s(Address adr) { - InstructionMark im(this); - emit_byte(0xD9); - emit_operand(rax, adr); -} - - -void Assembler::fld_s (int index) { - emit_farith(0xD9, 0xC0, index); -} - - -void Assembler::fld_d(Address adr) { - InstructionMark im(this); - emit_byte(0xDD); - emit_operand(rax, adr); -} - - -void Assembler::fld_x(Address adr) { - InstructionMark im(this); - emit_byte(0xDB); - emit_operand(rbp, adr); -} - - -void Assembler::fst_s(Address adr) { - InstructionMark im(this); - emit_byte(0xD9); - emit_operand(rdx, adr); -} - - -void Assembler::fst_d(Address adr) { - InstructionMark im(this); - emit_byte(0xDD); - emit_operand(rdx, adr); -} - - -void Assembler::fstp_s(Address adr) { - InstructionMark im(this); - emit_byte(0xD9); - emit_operand(rbx, adr); -} - - -void Assembler::fstp_d(Address adr) { - InstructionMark im(this); - emit_byte(0xDD); - emit_operand(rbx, adr); -} - - -void Assembler::fstp_x(Address adr) { - InstructionMark im(this); - emit_byte(0xDB); - emit_operand(rdi, adr); -} - - -void Assembler::fstp_d(int index) { - emit_farith(0xDD, 0xD8, index); -} - - -void Assembler::fild_s(Address adr) { - InstructionMark im(this); - emit_byte(0xDB); - emit_operand(rax, adr); -} - - -void Assembler::fild_d(Address adr) { - InstructionMark im(this); - emit_byte(0xDF); - emit_operand(rbp, adr); -} - - -void Assembler::fistp_s(Address adr) { - InstructionMark im(this); - emit_byte(0xDB); - emit_operand(rbx, adr); -} - - -void Assembler::fistp_d(Address adr) { - InstructionMark im(this); - emit_byte(0xDF); - emit_operand(rdi, adr); -} - - -void Assembler::fist_s(Address adr) { - InstructionMark im(this); - emit_byte(0xDB); - emit_operand(rdx, adr); -} - - -void Assembler::fabs() { - emit_byte(0xD9); - emit_byte(0xE1); -} - - -void Assembler::fldln2() { - emit_byte(0xD9); - emit_byte(0xED); -} - -void Assembler::fyl2x() { - emit_byte(0xD9); - emit_byte(0xF1); -} - - -void Assembler::fldlg2() { - emit_byte(0xD9); - emit_byte(0xEC); -} - - -void Assembler::flog() { - fldln2(); - fxch(); - fyl2x(); -} - - -void Assembler::flog10() { - fldlg2(); - fxch(); - fyl2x(); -} - - -void Assembler::fsin() { - emit_byte(0xD9); - emit_byte(0xFE); -} - - -void Assembler::fcos() { - emit_byte(0xD9); - emit_byte(0xFF); -} - -void Assembler::ftan() { - emit_byte(0xD9); - emit_byte(0xF2); - emit_byte(0xDD); - emit_byte(0xD8); -} - -void Assembler::fsqrt() { - emit_byte(0xD9); - emit_byte(0xFA); -} - - -void Assembler::fchs() { - emit_byte(0xD9); - emit_byte(0xE0); -} - - -void Assembler::fadd_s(Address src) { - InstructionMark im(this); - emit_byte(0xD8); - emit_operand(rax, src); -} - - -void Assembler::fadd_d(Address src) { - InstructionMark im(this); - emit_byte(0xDC); - emit_operand(rax, src); -} - - -void Assembler::fadd(int i) { - emit_farith(0xD8, 0xC0, i); -} - - -void Assembler::fadda(int i) { - emit_farith(0xDC, 0xC0, i); -} - - -void Assembler::fsub_d(Address src) { - InstructionMark im(this); - emit_byte(0xDC); - emit_operand(rsp, src); -} - - -void Assembler::fsub_s(Address src) { - InstructionMark im(this); - emit_byte(0xD8); - emit_operand(rsp, src); -} - - -void Assembler::fsubr_s(Address src) { - InstructionMark im(this); - emit_byte(0xD8); - emit_operand(rbp, src); -} - - -void Assembler::fsubr_d(Address src) { - InstructionMark im(this); - emit_byte(0xDC); - emit_operand(rbp, src); -} - - -void Assembler::fmul_s(Address src) { - InstructionMark im(this); - emit_byte(0xD8); - emit_operand(rcx, src); -} - - -void Assembler::fmul_d(Address src) { - InstructionMark im(this); - emit_byte(0xDC); - emit_operand(rcx, src); -} - - -void Assembler::fmul(int i) { - emit_farith(0xD8, 0xC8, i); -} - - -void Assembler::fmula(int i) { - emit_farith(0xDC, 0xC8, i); -} - - -void Assembler::fdiv_s(Address src) { - InstructionMark im(this); - emit_byte(0xD8); - emit_operand(rsi, src); -} - - -void Assembler::fdiv_d(Address src) { - InstructionMark im(this); - emit_byte(0xDC); - emit_operand(rsi, src); -} - - -void Assembler::fdivr_s(Address src) { - InstructionMark im(this); - emit_byte(0xD8); - emit_operand(rdi, src); -} - - -void Assembler::fdivr_d(Address src) { - InstructionMark im(this); - emit_byte(0xDC); - emit_operand(rdi, src); -} - - -void Assembler::fsub(int i) { - emit_farith(0xD8, 0xE0, i); -} - - -void Assembler::fsuba(int i) { - emit_farith(0xDC, 0xE8, i); -} - - -void Assembler::fsubr(int i) { - emit_farith(0xD8, 0xE8, i); -} - - -void Assembler::fsubra(int i) { - emit_farith(0xDC, 0xE0, i); -} - - -void Assembler::fdiv(int i) { - emit_farith(0xD8, 0xF0, i); -} - - -void Assembler::fdiva(int i) { - emit_farith(0xDC, 0xF8, i); -} - - -void Assembler::fdivr(int i) { - emit_farith(0xD8, 0xF8, i); -} - - -void Assembler::fdivra(int i) { - emit_farith(0xDC, 0xF0, i); -} - - -// Note: The Intel manual (Pentium Processor User's Manual, Vol.3, 1994) -// is erroneous for some of the floating-point instructions below. - -void Assembler::fdivp(int i) { - emit_farith(0xDE, 0xF8, i); // ST(0) <- ST(0) / ST(1) and pop (Intel manual wrong) -} - - -void Assembler::fdivrp(int i) { - emit_farith(0xDE, 0xF0, i); // ST(0) <- ST(1) / ST(0) and pop (Intel manual wrong) -} - - -void Assembler::fsubp(int i) { - emit_farith(0xDE, 0xE8, i); // ST(0) <- ST(0) - ST(1) and pop (Intel manual wrong) -} - - -void Assembler::fsubrp(int i) { - emit_farith(0xDE, 0xE0, i); // ST(0) <- ST(1) - ST(0) and pop (Intel manual wrong) -} - - -void Assembler::faddp(int i) { - emit_farith(0xDE, 0xC0, i); -} - - -void Assembler::fmulp(int i) { - emit_farith(0xDE, 0xC8, i); -} - - -void Assembler::fprem() { - emit_byte(0xD9); - emit_byte(0xF8); -} - - -void Assembler::fprem1() { - emit_byte(0xD9); - emit_byte(0xF5); -} - - -void Assembler::fxch(int i) { - emit_farith(0xD9, 0xC8, i); -} - - -void Assembler::fincstp() { - emit_byte(0xD9); - emit_byte(0xF7); -} - - -void Assembler::fdecstp() { - emit_byte(0xD9); - emit_byte(0xF6); -} - - -void Assembler::ffree(int i) { - emit_farith(0xDD, 0xC0, i); -} - - -void Assembler::fcomp_s(Address src) { - InstructionMark im(this); - emit_byte(0xD8); - emit_operand(rbx, src); -} - - -void Assembler::fcomp_d(Address src) { - InstructionMark im(this); - emit_byte(0xDC); - emit_operand(rbx, src); -} - - -void Assembler::fcom(int i) { - emit_farith(0xD8, 0xD0, i); -} - - -void Assembler::fcomp(int i) { - emit_farith(0xD8, 0xD8, i); -} - - -void Assembler::fcompp() { - emit_byte(0xDE); - emit_byte(0xD9); -} - - -void Assembler::fucomi(int i) { - // make sure the instruction is supported (introduced for P6, together with cmov) - guarantee(VM_Version::supports_cmov(), "illegal instruction"); - emit_farith(0xDB, 0xE8, i); -} - - -void Assembler::fucomip(int i) { - // make sure the instruction is supported (introduced for P6, together with cmov) - guarantee(VM_Version::supports_cmov(), "illegal instruction"); - emit_farith(0xDF, 0xE8, i); -} - - -void Assembler::ftst() { - emit_byte(0xD9); - emit_byte(0xE4); -} - - -void Assembler::fnstsw_ax() { - emit_byte(0xdF); - emit_byte(0xE0); -} - - -void Assembler::fwait() { - emit_byte(0x9B); -} - - -void Assembler::finit() { - emit_byte(0x9B); - emit_byte(0xDB); - emit_byte(0xE3); -} - - -void Assembler::fldcw(Address src) { - InstructionMark im(this); - emit_byte(0xd9); - emit_operand(rbp, src); -} - - -void Assembler::fnstcw(Address src) { - InstructionMark im(this); - emit_byte(0x9B); - emit_byte(0xD9); - emit_operand(rdi, src); -} - -void Assembler::fnsave(Address dst) { - InstructionMark im(this); - emit_byte(0xDD); - emit_operand(rsi, dst); -} - - -void Assembler::frstor(Address src) { - InstructionMark im(this); - emit_byte(0xDD); - emit_operand(rsp, src); -} - - -void Assembler::fldenv(Address src) { - InstructionMark im(this); - emit_byte(0xD9); - emit_operand(rsp, src); -} - - -void Assembler::sahf() { - emit_byte(0x9E); -} - -// MMX operations -void Assembler::emit_operand(MMXRegister reg, Address adr) { - emit_operand((Register)reg, adr._base, adr._index, adr._scale, adr._disp, adr._rspec); -} - -void Assembler::movq( MMXRegister dst, Address src ) { - assert( VM_Version::supports_mmx(), "" ); - emit_byte(0x0F); - emit_byte(0x6F); - emit_operand(dst,src); -} - -void Assembler::movq( Address dst, MMXRegister src ) { - assert( VM_Version::supports_mmx(), "" ); - emit_byte(0x0F); - emit_byte(0x7F); - emit_operand(src,dst); -} - -void Assembler::emms() { - emit_byte(0x0F); - emit_byte(0x77); -} - - - - -// SSE and SSE2 instructions -inline void Assembler::emit_sse_operand(XMMRegister reg, Address adr) { - assert(((Register)reg)->encoding() == reg->encoding(), "otherwise typecast is invalid"); - emit_operand((Register)reg, adr._base, adr._index, adr._scale, adr._disp, adr._rspec); -} -inline void Assembler::emit_sse_operand(Register reg, Address adr) { - emit_operand(reg, adr._base, adr._index, adr._scale, adr._disp, adr._rspec); -} - -inline void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) { - emit_byte(0xC0 | dst->encoding() << 3 | src->encoding()); -} -inline void Assembler::emit_sse_operand(XMMRegister dst, Register src) { - emit_byte(0xC0 | dst->encoding() << 3 | src->encoding()); -} -inline void Assembler::emit_sse_operand(Register dst, XMMRegister src) { - emit_byte(0xC0 | dst->encoding() << 3 | src->encoding()); -} - - -// Macro for creation of SSE2 instructions -// The SSE2 instricution set is highly regular, so this macro saves -// a lot of cut&paste -// Each macro expansion creates two methods (same name with different -// parameter list) -// -// Macro parameters: -// * name: name of the created methods -// * sse_version: either sse or sse2 for the assertion if instruction supported by processor -// * prefix: first opcode byte of the instruction (or 0 if no prefix byte) -// * opcode: last opcode byte of the instruction -// * conversion instruction have parameters of type Register instead of XMMRegister, -// so this can also configured with macro parameters -#define emit_sse_instruction(name, sse_version, prefix, opcode, dst_register_type, src_register_type) \ - \ - void Assembler:: name (dst_register_type dst, Address src) { \ - assert(VM_Version::supports_##sse_version(), ""); \ - \ - InstructionMark im(this); \ - if (prefix != 0) emit_byte(prefix); \ - emit_byte(0x0F); \ - emit_byte(opcode); \ - emit_sse_operand(dst, src); \ - } \ - \ - void Assembler:: name (dst_register_type dst, src_register_type src) { \ - assert(VM_Version::supports_##sse_version(), ""); \ - \ - if (prefix != 0) emit_byte(prefix); \ - emit_byte(0x0F); \ - emit_byte(opcode); \ - emit_sse_operand(dst, src); \ - } \ - -emit_sse_instruction(addss, sse, 0xF3, 0x58, XMMRegister, XMMRegister); -emit_sse_instruction(addsd, sse2, 0xF2, 0x58, XMMRegister, XMMRegister) -emit_sse_instruction(subss, sse, 0xF3, 0x5C, XMMRegister, XMMRegister) -emit_sse_instruction(subsd, sse2, 0xF2, 0x5C, XMMRegister, XMMRegister) -emit_sse_instruction(mulss, sse, 0xF3, 0x59, XMMRegister, XMMRegister) -emit_sse_instruction(mulsd, sse2, 0xF2, 0x59, XMMRegister, XMMRegister) -emit_sse_instruction(divss, sse, 0xF3, 0x5E, XMMRegister, XMMRegister) -emit_sse_instruction(divsd, sse2, 0xF2, 0x5E, XMMRegister, XMMRegister) -emit_sse_instruction(sqrtss, sse, 0xF3, 0x51, XMMRegister, XMMRegister) -emit_sse_instruction(sqrtsd, sse2, 0xF2, 0x51, XMMRegister, XMMRegister) - -emit_sse_instruction(pxor, sse2, 0x66, 0xEF, XMMRegister, XMMRegister) - -emit_sse_instruction(comiss, sse, 0, 0x2F, XMMRegister, XMMRegister) -emit_sse_instruction(comisd, sse2, 0x66, 0x2F, XMMRegister, XMMRegister) -emit_sse_instruction(ucomiss, sse, 0, 0x2E, XMMRegister, XMMRegister) -emit_sse_instruction(ucomisd, sse2, 0x66, 0x2E, XMMRegister, XMMRegister) - -emit_sse_instruction(cvtss2sd, sse2, 0xF3, 0x5A, XMMRegister, XMMRegister); -emit_sse_instruction(cvtsd2ss, sse2, 0xF2, 0x5A, XMMRegister, XMMRegister) -emit_sse_instruction(cvtsi2ss, sse, 0xF3, 0x2A, XMMRegister, Register); -emit_sse_instruction(cvtsi2sd, sse2, 0xF2, 0x2A, XMMRegister, Register) -emit_sse_instruction(cvtss2si, sse, 0xF3, 0x2D, Register, XMMRegister); -emit_sse_instruction(cvtsd2si, sse2, 0xF2, 0x2D, Register, XMMRegister) -emit_sse_instruction(cvttss2si, sse, 0xF3, 0x2C, Register, XMMRegister); -emit_sse_instruction(cvttsd2si, sse2, 0xF2, 0x2C, Register, XMMRegister) - -emit_sse_instruction(movss, sse, 0xF3, 0x10, XMMRegister, XMMRegister) -emit_sse_instruction(movsd, sse2, 0xF2, 0x10, XMMRegister, XMMRegister) - -emit_sse_instruction(movq, sse2, 0xF3, 0x7E, XMMRegister, XMMRegister); -emit_sse_instruction(movd, sse2, 0x66, 0x6E, XMMRegister, Register); -emit_sse_instruction(movdqa, sse2, 0x66, 0x6F, XMMRegister, XMMRegister); - -emit_sse_instruction(punpcklbw, sse2, 0x66, 0x60, XMMRegister, XMMRegister); - - -// Instruction not covered by macro -void Assembler::movq(Address dst, XMMRegister src) { - assert(VM_Version::supports_sse2(), ""); - - InstructionMark im(this); - emit_byte(0x66); - emit_byte(0x0F); - emit_byte(0xD6); - emit_sse_operand(src, dst); -} - -void Assembler::movd(Address dst, XMMRegister src) { - assert(VM_Version::supports_sse2(), ""); - - InstructionMark im(this); - emit_byte(0x66); - emit_byte(0x0F); - emit_byte(0x7E); - emit_sse_operand(src, dst); -} - -void Assembler::movd(Register dst, XMMRegister src) { - assert(VM_Version::supports_sse2(), ""); - - emit_byte(0x66); - emit_byte(0x0F); - emit_byte(0x7E); - emit_sse_operand(src, dst); -} - -void Assembler::movdqa(Address dst, XMMRegister src) { - assert(VM_Version::supports_sse2(), ""); - - InstructionMark im(this); - emit_byte(0x66); - emit_byte(0x0F); - emit_byte(0x7F); - emit_sse_operand(src, dst); -} - -void Assembler::pshufd(XMMRegister dst, XMMRegister src, int mode) { - assert(isByte(mode), "invalid value"); - assert(VM_Version::supports_sse2(), ""); - - emit_byte(0x66); - emit_byte(0x0F); - emit_byte(0x70); - emit_sse_operand(dst, src); - emit_byte(mode & 0xFF); -} - -void Assembler::pshufd(XMMRegister dst, Address src, int mode) { - assert(isByte(mode), "invalid value"); - assert(VM_Version::supports_sse2(), ""); - - InstructionMark im(this); - emit_byte(0x66); - emit_byte(0x0F); - emit_byte(0x70); - emit_sse_operand(dst, src); - emit_byte(mode & 0xFF); -} - -void Assembler::pshuflw(XMMRegister dst, XMMRegister src, int mode) { - assert(isByte(mode), "invalid value"); - assert(VM_Version::supports_sse2(), ""); - - emit_byte(0xF2); - emit_byte(0x0F); - emit_byte(0x70); - emit_sse_operand(dst, src); - emit_byte(mode & 0xFF); -} - -void Assembler::pshuflw(XMMRegister dst, Address src, int mode) { - assert(isByte(mode), "invalid value"); - assert(VM_Version::supports_sse2(), ""); - - InstructionMark im(this); - emit_byte(0xF2); - emit_byte(0x0F); - emit_byte(0x70); - emit_sse_operand(dst, src); - emit_byte(mode & 0xFF); -} - -void Assembler::psrlq(XMMRegister dst, int shift) { - assert(VM_Version::supports_sse2(), ""); - - emit_byte(0x66); - emit_byte(0x0F); - emit_byte(0x73); - emit_sse_operand(xmm2, dst); - emit_byte(shift); -} - -void Assembler::movss( Address dst, XMMRegister src ) { - assert(VM_Version::supports_sse(), ""); - - InstructionMark im(this); - emit_byte(0xF3); // single - emit_byte(0x0F); - emit_byte(0x11); // store - emit_sse_operand(src, dst); -} - -void Assembler::movsd( Address dst, XMMRegister src ) { - assert(VM_Version::supports_sse2(), ""); - - InstructionMark im(this); - emit_byte(0xF2); // double - emit_byte(0x0F); - emit_byte(0x11); // store - emit_sse_operand(src,dst); -} - -// New cpus require to use movaps and movapd to avoid partial register stall -// when moving between registers. -void Assembler::movaps(XMMRegister dst, XMMRegister src) { - assert(VM_Version::supports_sse(), ""); - - emit_byte(0x0F); - emit_byte(0x28); - emit_sse_operand(dst, src); -} -void Assembler::movapd(XMMRegister dst, XMMRegister src) { - assert(VM_Version::supports_sse2(), ""); - - emit_byte(0x66); - emit_byte(0x0F); - emit_byte(0x28); - emit_sse_operand(dst, src); -} - -// New cpus require to use movsd and movss to avoid partial register stall -// when loading from memory. But for old Opteron use movlpd instead of movsd. -// The selection is done in MacroAssembler::movdbl() and movflt(). -void Assembler::movlpd(XMMRegister dst, Address src) { - assert(VM_Version::supports_sse(), ""); - - InstructionMark im(this); - emit_byte(0x66); - emit_byte(0x0F); - emit_byte(0x12); - emit_sse_operand(dst, src); -} - -void Assembler::cvtdq2pd(XMMRegister dst, XMMRegister src) { - assert(VM_Version::supports_sse2(), ""); - - emit_byte(0xF3); - emit_byte(0x0F); - emit_byte(0xE6); - emit_sse_operand(dst, src); -} - -void Assembler::cvtdq2ps(XMMRegister dst, XMMRegister src) { - assert(VM_Version::supports_sse2(), ""); - - emit_byte(0x0F); - emit_byte(0x5B); - emit_sse_operand(dst, src); -} - -emit_sse_instruction(andps, sse, 0, 0x54, XMMRegister, XMMRegister); -emit_sse_instruction(andpd, sse2, 0x66, 0x54, XMMRegister, XMMRegister); -emit_sse_instruction(andnps, sse, 0, 0x55, XMMRegister, XMMRegister); -emit_sse_instruction(andnpd, sse2, 0x66, 0x55, XMMRegister, XMMRegister); -emit_sse_instruction(orps, sse, 0, 0x56, XMMRegister, XMMRegister); -emit_sse_instruction(orpd, sse2, 0x66, 0x56, XMMRegister, XMMRegister); -emit_sse_instruction(xorps, sse, 0, 0x57, XMMRegister, XMMRegister); -emit_sse_instruction(xorpd, sse2, 0x66, 0x57, XMMRegister, XMMRegister); - - -void Assembler::ldmxcsr( Address src) { - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0xAE); - emit_operand(rdx /* 2 */, src); -} - -void Assembler::stmxcsr( Address dst) { - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0xAE); - emit_operand(rbx /* 3 */, dst); -} - -// Implementation of MacroAssembler - -Address MacroAssembler::as_Address(AddressLiteral adr) { - // amd64 always does this as a pc-rel - // we can be absolute or disp based on the instruction type - // jmp/call are displacements others are absolute - assert(!adr.is_lval(), "must be rval"); - - return Address(adr.target(), adr.rspec()); -} - -Address MacroAssembler::as_Address(ArrayAddress adr) { - return Address::make_array(adr); -} - -void MacroAssembler::fat_nop() { - // A 5 byte nop that is safe for patching (see patch_verified_entry) - emit_byte(0x26); // es: - emit_byte(0x2e); // cs: - emit_byte(0x64); // fs: - emit_byte(0x65); // gs: - emit_byte(0x90); -} - -// 32bit can do a case table jump in one instruction but we no longer allow the base -// to be installed in the Address class -void MacroAssembler::jump(ArrayAddress entry) { - jmp(as_Address(entry)); -} - -void MacroAssembler::jump(AddressLiteral dst) { - jmp_literal(dst.target(), dst.rspec()); -} - -void MacroAssembler::jump_cc(Condition cc, AddressLiteral dst) { - assert((0 <= cc) && (cc < 16), "illegal cc"); - - InstructionMark im(this); - - relocInfo::relocType rtype = dst.reloc(); - relocate(rtype); - const int short_size = 2; - const int long_size = 6; - int offs = (int)dst.target() - ((int)_code_pos); - if (rtype == relocInfo::none && is8bit(offs - short_size)) { - // 0111 tttn #8-bit disp - emit_byte(0x70 | cc); - emit_byte((offs - short_size) & 0xFF); - } else { - // 0000 1111 1000 tttn #32-bit disp - emit_byte(0x0F); - emit_byte(0x80 | cc); - emit_long(offs - long_size); - } -} - -// Calls -void MacroAssembler::call(Label& L, relocInfo::relocType rtype) { - Assembler::call(L, rtype); -} - -void MacroAssembler::call(Register entry) { - Assembler::call(entry); -} - -void MacroAssembler::call(AddressLiteral entry) { - Assembler::call_literal(entry.target(), entry.rspec()); -} - - -void MacroAssembler::cmp8(AddressLiteral src1, int8_t imm) { - Assembler::cmpb(as_Address(src1), imm); -} - -void MacroAssembler::cmp32(AddressLiteral src1, int32_t imm) { - Assembler::cmpl(as_Address(src1), imm); -} - -void MacroAssembler::cmp32(Register src1, AddressLiteral src2) { - if (src2.is_lval()) { - cmp_literal32(src1, (int32_t) src2.target(), src2.rspec()); - } else { - Assembler::cmpl(src1, as_Address(src2)); - } -} - -void MacroAssembler::cmp32(Register src1, int32_t imm) { - Assembler::cmpl(src1, imm); -} - -void MacroAssembler::cmp32(Register src1, Address src2) { - Assembler::cmpl(src1, src2); -} - -void MacroAssembler::cmpoop(Address src1, jobject obj) { - cmp_literal32(src1, (int32_t)obj, oop_Relocation::spec_for_immediate()); -} - -void MacroAssembler::cmpoop(Register src1, jobject obj) { - cmp_literal32(src1, (int32_t)obj, oop_Relocation::spec_for_immediate()); -} - -void MacroAssembler::cmpptr(Register src1, AddressLiteral src2) { - if (src2.is_lval()) { - // compare the effect address of src2 to src1 - cmp_literal32(src1, (int32_t)src2.target(), src2.rspec()); - } else { - Assembler::cmpl(src1, as_Address(src2)); - } -} - -void MacroAssembler::cmpptr(Address src1, AddressLiteral src2) { - assert(src2.is_lval(), "not a mem-mem compare"); - cmp_literal32(src1, (int32_t) src2.target(), src2.rspec()); -} - - -void MacroAssembler::cmpxchgptr(Register reg, AddressLiteral adr) { - cmpxchg(reg, as_Address(adr)); -} - -void MacroAssembler::increment(AddressLiteral dst) { - increment(as_Address(dst)); -} - -void MacroAssembler::increment(ArrayAddress dst) { - increment(as_Address(dst)); -} - -void MacroAssembler::lea(Register dst, AddressLiteral adr) { - // leal(dst, as_Address(adr)); - // see note in movl as to why we musr use a move - mov_literal32(dst, (int32_t) adr.target(), adr.rspec()); -} - -void MacroAssembler::lea(Address dst, AddressLiteral adr) { - // leal(dst, as_Address(adr)); - // see note in movl as to why we musr use a move - mov_literal32(dst, (int32_t) adr.target(), adr.rspec()); -} - -void MacroAssembler::mov32(AddressLiteral dst, Register src) { - Assembler::movl(as_Address(dst), src); -} - -void MacroAssembler::mov32(Register dst, AddressLiteral src) { - Assembler::movl(dst, as_Address(src)); -} - -void MacroAssembler::movbyte(ArrayAddress dst, int src) { - movb(as_Address(dst), src); -} - -void MacroAssembler::movoop(Address dst, jobject obj) { - mov_literal32(dst, (int32_t)obj, oop_Relocation::spec_for_immediate()); -} - -void MacroAssembler::movoop(Register dst, jobject obj) { - mov_literal32(dst, (int32_t)obj, oop_Relocation::spec_for_immediate()); -} - -void MacroAssembler::movptr(Register dst, AddressLiteral src) { - if (src.is_lval()) { - // essentially an lea - mov_literal32(dst, (int32_t) src.target(), src.rspec()); - } else { - // mov 32bits from an absolute address - movl(dst, as_Address(src)); - } -} - -void MacroAssembler::movptr(ArrayAddress dst, Register src) { - movl(as_Address(dst), src); -} - -void MacroAssembler::movptr(Register dst, ArrayAddress src) { - movl(dst, as_Address(src)); -} - -void MacroAssembler::movflt(XMMRegister dst, AddressLiteral src) { - movss(dst, as_Address(src)); -} - -void MacroAssembler::movdbl(XMMRegister dst, AddressLiteral src) { - if (UseXmmLoadAndClearUpper) { movsd (dst, as_Address(src)); return; } - else { movlpd(dst, as_Address(src)); return; } -} - -void Assembler::pushoop(jobject obj) { - push_literal32((int32_t)obj, oop_Relocation::spec_for_immediate()); -} - - -void MacroAssembler::pushptr(AddressLiteral src) { - if (src.is_lval()) { - push_literal32((int32_t)src.target(), src.rspec()); - } else { - pushl(as_Address(src)); - } -} - -void MacroAssembler::test32(Register src1, AddressLiteral src2) { - // src2 must be rval - testl(src1, as_Address(src2)); -} - -// FPU - -void MacroAssembler::fld_x(AddressLiteral src) { - Assembler::fld_x(as_Address(src)); -} - -void MacroAssembler::fld_d(AddressLiteral src) { - fld_d(as_Address(src)); -} - -void MacroAssembler::fld_s(AddressLiteral src) { - fld_s(as_Address(src)); -} - -void MacroAssembler::fldcw(AddressLiteral src) { - Assembler::fldcw(as_Address(src)); -} - -void MacroAssembler::ldmxcsr(AddressLiteral src) { - Assembler::ldmxcsr(as_Address(src)); -} - -// SSE - -void MacroAssembler::andpd(XMMRegister dst, AddressLiteral src) { - andpd(dst, as_Address(src)); -} - -void MacroAssembler::comisd(XMMRegister dst, AddressLiteral src) { - comisd(dst, as_Address(src)); -} - -void MacroAssembler::comiss(XMMRegister dst, AddressLiteral src) { - comiss(dst, as_Address(src)); -} - -void MacroAssembler::movsd(XMMRegister dst, AddressLiteral src) { - movsd(dst, as_Address(src)); -} - -void MacroAssembler::movss(XMMRegister dst, AddressLiteral src) { - movss(dst, as_Address(src)); -} - -void MacroAssembler::xorpd(XMMRegister dst, AddressLiteral src) { - xorpd(dst, as_Address(src)); -} - -void MacroAssembler::xorps(XMMRegister dst, AddressLiteral src) { - xorps(dst, as_Address(src)); -} - -void MacroAssembler::ucomisd(XMMRegister dst, AddressLiteral src) { - ucomisd(dst, as_Address(src)); -} - -void MacroAssembler::ucomiss(XMMRegister dst, AddressLiteral src) { - ucomiss(dst, as_Address(src)); -} - -void MacroAssembler::null_check(Register reg, int offset) { - if (needs_explicit_null_check(offset)) { - // provoke OS NULL exception if reg = NULL by - // accessing M[reg] w/o changing any (non-CC) registers - cmpl(rax, Address(reg, 0)); - // Note: should probably use testl(rax, Address(reg, 0)); - // may be shorter code (however, this version of - // testl needs to be implemented first) - } else { - // nothing to do, (later) access of M[reg + offset] - // will provoke OS NULL exception if reg = NULL - } -} - - -int MacroAssembler::load_unsigned_byte(Register dst, Address src) { - // According to Intel Doc. AP-526, "Zero-Extension of Short", p.16, - // and "3.9 Partial Register Penalties", p. 22). - int off; - if (VM_Version::is_P6() || src.uses(dst)) { - off = offset(); - movzxb(dst, src); - } else { - xorl(dst, dst); - off = offset(); - movb(dst, src); - } - return off; -} - - -int MacroAssembler::load_unsigned_word(Register dst, Address src) { - // According to Intel Doc. AP-526, "Zero-Extension of Short", p.16, - // and "3.9 Partial Register Penalties", p. 22). - int off; - if (VM_Version::is_P6() || src.uses(dst)) { - off = offset(); - movzxw(dst, src); - } else { - xorl(dst, dst); - off = offset(); - movw(dst, src); - } - return off; -} - - -int MacroAssembler::load_signed_byte(Register dst, Address src) { - int off; - if (VM_Version::is_P6()) { - off = offset(); - movsxb(dst, src); - } else { - off = load_unsigned_byte(dst, src); - shll(dst, 24); - sarl(dst, 24); - } - return off; -} - - -int MacroAssembler::load_signed_word(Register dst, Address src) { - int off; - if (VM_Version::is_P6()) { - off = offset(); - movsxw(dst, src); - } else { - off = load_unsigned_word(dst, src); - shll(dst, 16); - sarl(dst, 16); - } - return off; -} - - -void MacroAssembler::extend_sign(Register hi, Register lo) { - // According to Intel Doc. AP-526, "Integer Divide", p.18. - if (VM_Version::is_P6() && hi == rdx && lo == rax) { - cdql(); - } else { - movl(hi, lo); - sarl(hi, 31); - } -} - - -void MacroAssembler::increment(Register reg, int value) { - if (value == min_jint) {addl(reg, value); return; } - if (value < 0) { decrement(reg, -value); return; } - if (value == 0) { ; return; } - if (value == 1 && UseIncDec) { incl(reg); return; } - /* else */ { addl(reg, value) ; return; } -} - -void MacroAssembler::increment(Address dst, int value) { - if (value == min_jint) {addl(dst, value); return; } - if (value < 0) { decrement(dst, -value); return; } - if (value == 0) { ; return; } - if (value == 1 && UseIncDec) { incl(dst); return; } - /* else */ { addl(dst, value) ; return; } -} - -void MacroAssembler::decrement(Register reg, int value) { - if (value == min_jint) {subl(reg, value); return; } - if (value < 0) { increment(reg, -value); return; } - if (value == 0) { ; return; } - if (value == 1 && UseIncDec) { decl(reg); return; } - /* else */ { subl(reg, value) ; return; } -} - -void MacroAssembler::decrement(Address dst, int value) { - if (value == min_jint) {subl(dst, value); return; } - if (value < 0) { increment(dst, -value); return; } - if (value == 0) { ; return; } - if (value == 1 && UseIncDec) { decl(dst); return; } - /* else */ { subl(dst, value) ; return; } -} - -void MacroAssembler::align(int modulus) { - if (offset() % modulus != 0) nop(modulus - (offset() % modulus)); -} - - -void MacroAssembler::enter() { - pushl(rbp); - movl(rbp, rsp); -} - - -void MacroAssembler::leave() { - movl(rsp, rbp); - popl(rbp); -} - -void MacroAssembler::set_last_Java_frame(Register java_thread, - Register last_java_sp, - Register last_java_fp, - address last_java_pc) { - // determine java_thread register - if (!java_thread->is_valid()) { - java_thread = rdi; - get_thread(java_thread); - } - // determine last_java_sp register - if (!last_java_sp->is_valid()) { - last_java_sp = rsp; - } - - // last_java_fp is optional - - if (last_java_fp->is_valid()) { - movl(Address(java_thread, JavaThread::last_Java_fp_offset()), last_java_fp); - } - - // last_java_pc is optional - - if (last_java_pc != NULL) { - lea(Address(java_thread, - JavaThread::frame_anchor_offset() + JavaFrameAnchor::last_Java_pc_offset()), - InternalAddress(last_java_pc)); - - } - movl(Address(java_thread, JavaThread::last_Java_sp_offset()), last_java_sp); -} - -void MacroAssembler::reset_last_Java_frame(Register java_thread, bool clear_fp, bool clear_pc) { - // determine java_thread register - if (!java_thread->is_valid()) { - java_thread = rdi; - get_thread(java_thread); - } - // we must set sp to zero to clear frame - movl(Address(java_thread, JavaThread::last_Java_sp_offset()), 0); - if (clear_fp) { - movl(Address(java_thread, JavaThread::last_Java_fp_offset()), 0); - } - - if (clear_pc) - movl(Address(java_thread, JavaThread::last_Java_pc_offset()), 0); - -} - - - -// Implementation of call_VM versions - -void MacroAssembler::call_VM_leaf_base( - address entry_point, - int number_of_arguments -) { - call(RuntimeAddress(entry_point)); - increment(rsp, number_of_arguments * wordSize); -} - - -void MacroAssembler::call_VM_base( - Register oop_result, - Register java_thread, - Register last_java_sp, - address entry_point, - int number_of_arguments, - bool check_exceptions -) { - // determine java_thread register - if (!java_thread->is_valid()) { - java_thread = rdi; - get_thread(java_thread); - } - // determine last_java_sp register - if (!last_java_sp->is_valid()) { - last_java_sp = rsp; - } - // debugging support - assert(number_of_arguments >= 0 , "cannot have negative number of arguments"); - assert(java_thread != oop_result , "cannot use the same register for java_thread & oop_result"); - assert(java_thread != last_java_sp, "cannot use the same register for java_thread & last_java_sp"); - // push java thread (becomes first argument of C function) - pushl(java_thread); - // set last Java frame before call - assert(last_java_sp != rbp, "this code doesn't work for last_java_sp == rbp, which currently can't portably work anyway since C2 doesn't save rbp,"); - // Only interpreter should have to set fp - set_last_Java_frame(java_thread, last_java_sp, rbp, NULL); - // do the call - call(RuntimeAddress(entry_point)); - // restore the thread (cannot use the pushed argument since arguments - // may be overwritten by C code generated by an optimizing compiler); - // however can use the register value directly if it is callee saved. - if (java_thread == rdi || java_thread == rsi) { - // rdi & rsi are callee saved -> nothing to do -#ifdef ASSERT - guarantee(java_thread != rax, "change this code"); - pushl(rax); - { Label L; - get_thread(rax); - cmpl(java_thread, rax); - jcc(Assembler::equal, L); - stop("MacroAssembler::call_VM_base: rdi not callee saved?"); - bind(L); - } - popl(rax); -#endif - } else { - get_thread(java_thread); - } - // reset last Java frame - // Only interpreter should have to clear fp - reset_last_Java_frame(java_thread, true, false); - // discard thread and arguments - addl(rsp, (1 + number_of_arguments)*wordSize); - -#ifndef CC_INTERP - // C++ interp handles this in the interpreter - check_and_handle_popframe(java_thread); - check_and_handle_earlyret(java_thread); -#endif /* CC_INTERP */ - - if (check_exceptions) { - // check for pending exceptions (java_thread is set upon return) - cmpl(Address(java_thread, Thread::pending_exception_offset()), NULL_WORD); - jump_cc(Assembler::notEqual, - RuntimeAddress(StubRoutines::forward_exception_entry())); - } - - // get oop result if there is one and reset the value in the thread - if (oop_result->is_valid()) { - movl(oop_result, Address(java_thread, JavaThread::vm_result_offset())); - movl(Address(java_thread, JavaThread::vm_result_offset()), NULL_WORD); - verify_oop(oop_result); - } -} - - -void MacroAssembler::check_and_handle_popframe(Register java_thread) { -} - -void MacroAssembler::check_and_handle_earlyret(Register java_thread) { -} - -void MacroAssembler::call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions) { - leal(rax, Address(rsp, (1 + number_of_arguments) * wordSize)); - call_VM_base(oop_result, noreg, rax, entry_point, number_of_arguments, check_exceptions); -} - - -void MacroAssembler::call_VM(Register oop_result, address entry_point, bool check_exceptions) { - Label C, E; - call(C, relocInfo::none); - jmp(E); - - bind(C); - call_VM_helper(oop_result, entry_point, 0, check_exceptions); - ret(0); - - bind(E); -} - - -void MacroAssembler::call_VM(Register oop_result, address entry_point, Register arg_1, bool check_exceptions) { - Label C, E; - call(C, relocInfo::none); - jmp(E); - - bind(C); - pushl(arg_1); - call_VM_helper(oop_result, entry_point, 1, check_exceptions); - ret(0); - - bind(E); -} - - -void MacroAssembler::call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, bool check_exceptions) { - Label C, E; - call(C, relocInfo::none); - jmp(E); - - bind(C); - pushl(arg_2); - pushl(arg_1); - call_VM_helper(oop_result, entry_point, 2, check_exceptions); - ret(0); - - bind(E); -} - - -void MacroAssembler::call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, Register arg_3, bool check_exceptions) { - Label C, E; - call(C, relocInfo::none); - jmp(E); - - bind(C); - pushl(arg_3); - pushl(arg_2); - pushl(arg_1); - call_VM_helper(oop_result, entry_point, 3, check_exceptions); - ret(0); - - bind(E); -} - - -void MacroAssembler::call_VM(Register oop_result, Register last_java_sp, address entry_point, int number_of_arguments, bool check_exceptions) { - call_VM_base(oop_result, noreg, last_java_sp, entry_point, number_of_arguments, check_exceptions); -} - - -void MacroAssembler::call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, bool check_exceptions) { - pushl(arg_1); - call_VM(oop_result, last_java_sp, entry_point, 1, check_exceptions); -} - - -void MacroAssembler::call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, bool check_exceptions) { - pushl(arg_2); - pushl(arg_1); - call_VM(oop_result, last_java_sp, entry_point, 2, check_exceptions); -} - - -void MacroAssembler::call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, Register arg_3, bool check_exceptions) { - pushl(arg_3); - pushl(arg_2); - pushl(arg_1); - call_VM(oop_result, last_java_sp, entry_point, 3, check_exceptions); -} - - -void MacroAssembler::call_VM_leaf(address entry_point, int number_of_arguments) { - call_VM_leaf_base(entry_point, number_of_arguments); -} - - -void MacroAssembler::call_VM_leaf(address entry_point, Register arg_1) { - pushl(arg_1); - call_VM_leaf(entry_point, 1); -} - - -void MacroAssembler::call_VM_leaf(address entry_point, Register arg_1, Register arg_2) { - pushl(arg_2); - pushl(arg_1); - call_VM_leaf(entry_point, 2); -} - - -void MacroAssembler::call_VM_leaf(address entry_point, Register arg_1, Register arg_2, Register arg_3) { - pushl(arg_3); - pushl(arg_2); - pushl(arg_1); - call_VM_leaf(entry_point, 3); -} - - -// Calls to C land -// -// When entering C land, the rbp, & rsp of the last Java frame have to be recorded -// in the (thread-local) JavaThread object. When leaving C land, the last Java fp -// has to be reset to 0. This is required to allow proper stack traversal. - -void MacroAssembler::store_check(Register obj) { - // Does a store check for the oop in register obj. The content of - // register obj is destroyed afterwards. - store_check_part_1(obj); - store_check_part_2(obj); -} - - -void MacroAssembler::store_check(Register obj, Address dst) { - store_check(obj); -} - - -// split the store check operation so that other instructions can be scheduled inbetween -void MacroAssembler::store_check_part_1(Register obj) { - BarrierSet* bs = Universe::heap()->barrier_set(); - assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind"); - shrl(obj, CardTableModRefBS::card_shift); -} - - -void MacroAssembler::store_check_part_2(Register obj) { - BarrierSet* bs = Universe::heap()->barrier_set(); - assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind"); - CardTableModRefBS* ct = (CardTableModRefBS*)bs; - assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); - - // The calculation for byte_map_base is as follows: - // byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift); - // So this essentially converts an address to a displacement and - // it will never need to be relocated. On 64bit however the value may be too - // large for a 32bit displacement - - intptr_t disp = (intptr_t) ct->byte_map_base; - Address cardtable(noreg, obj, Address::times_1, disp); - movb(cardtable, 0); -} - - -void MacroAssembler::c2bool(Register x) { - // implements x == 0 ? 0 : 1 - // note: must only look at least-significant byte of x - // since C-style booleans are stored in one byte - // only! (was bug) - andl(x, 0xFF); - setb(Assembler::notZero, x); -} - - -int MacroAssembler::corrected_idivl(Register reg) { - // Full implementation of Java idiv and irem; checks for - // special case as described in JVM spec., p.243 & p.271. - // The function returns the (pc) offset of the idivl - // instruction - may be needed for implicit exceptions. - // - // normal case special case - // - // input : rax,: dividend min_int - // reg: divisor (may not be rax,/rdx) -1 - // - // output: rax,: quotient (= rax, idiv reg) min_int - // rdx: remainder (= rax, irem reg) 0 - assert(reg != rax && reg != rdx, "reg cannot be rax, or rdx register"); - const int min_int = 0x80000000; - Label normal_case, special_case; - - // check for special case - cmpl(rax, min_int); - jcc(Assembler::notEqual, normal_case); - xorl(rdx, rdx); // prepare rdx for possible special case (where remainder = 0) - cmpl(reg, -1); - jcc(Assembler::equal, special_case); - - // handle normal case - bind(normal_case); - cdql(); - int idivl_offset = offset(); - idivl(reg); - - // normal and special case exit - bind(special_case); - - return idivl_offset; -} - - -void MacroAssembler::lneg(Register hi, Register lo) { - negl(lo); - adcl(hi, 0); - negl(hi); -} - - -void MacroAssembler::lmul(int x_rsp_offset, int y_rsp_offset) { - // Multiplication of two Java long values stored on the stack - // as illustrated below. Result is in rdx:rax. - // - // rsp ---> [ ?? ] \ \ - // .... | y_rsp_offset | - // [ y_lo ] / (in bytes) | x_rsp_offset - // [ y_hi ] | (in bytes) - // .... | - // [ x_lo ] / - // [ x_hi ] - // .... - // - // Basic idea: lo(result) = lo(x_lo * y_lo) - // hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) + lo(x_lo * y_hi) - Address x_hi(rsp, x_rsp_offset + wordSize); Address x_lo(rsp, x_rsp_offset); - Address y_hi(rsp, y_rsp_offset + wordSize); Address y_lo(rsp, y_rsp_offset); - Label quick; - // load x_hi, y_hi and check if quick - // multiplication is possible - movl(rbx, x_hi); - movl(rcx, y_hi); - movl(rax, rbx); - orl(rbx, rcx); // rbx, = 0 <=> x_hi = 0 and y_hi = 0 - jcc(Assembler::zero, quick); // if rbx, = 0 do quick multiply - // do full multiplication - // 1st step - mull(y_lo); // x_hi * y_lo - movl(rbx, rax); // save lo(x_hi * y_lo) in rbx, - // 2nd step - movl(rax, x_lo); - mull(rcx); // x_lo * y_hi - addl(rbx, rax); // add lo(x_lo * y_hi) to rbx, - // 3rd step - bind(quick); // note: rbx, = 0 if quick multiply! - movl(rax, x_lo); - mull(y_lo); // x_lo * y_lo - addl(rdx, rbx); // correct hi(x_lo * y_lo) -} - - -void MacroAssembler::lshl(Register hi, Register lo) { - // Java shift left long support (semantics as described in JVM spec., p.305) - // (basic idea for shift counts s >= n: x << s == (x << n) << (s - n)) - // shift value is in rcx ! - assert(hi != rcx, "must not use rcx"); - assert(lo != rcx, "must not use rcx"); - const Register s = rcx; // shift count - const int n = BitsPerWord; - Label L; - andl(s, 0x3f); // s := s & 0x3f (s < 0x40) - cmpl(s, n); // if (s < n) - jcc(Assembler::less, L); // else (s >= n) - movl(hi, lo); // x := x << n - xorl(lo, lo); - // Note: subl(s, n) is not needed since the Intel shift instructions work rcx mod n! - bind(L); // s (mod n) < n - shldl(hi, lo); // x := x << s - shll(lo); -} - - -void MacroAssembler::lshr(Register hi, Register lo, bool sign_extension) { - // Java shift right long support (semantics as described in JVM spec., p.306 & p.310) - // (basic idea for shift counts s >= n: x >> s == (x >> n) >> (s - n)) - assert(hi != rcx, "must not use rcx"); - assert(lo != rcx, "must not use rcx"); - const Register s = rcx; // shift count - const int n = BitsPerWord; - Label L; - andl(s, 0x3f); // s := s & 0x3f (s < 0x40) - cmpl(s, n); // if (s < n) - jcc(Assembler::less, L); // else (s >= n) - movl(lo, hi); // x := x >> n - if (sign_extension) sarl(hi, 31); - else xorl(hi, hi); - // Note: subl(s, n) is not needed since the Intel shift instructions work rcx mod n! - bind(L); // s (mod n) < n - shrdl(lo, hi); // x := x >> s - if (sign_extension) sarl(hi); - else shrl(hi); -} - - -// Note: y_lo will be destroyed -void MacroAssembler::lcmp2int(Register x_hi, Register x_lo, Register y_hi, Register y_lo) { - // Long compare for Java (semantics as described in JVM spec.) - Label high, low, done; - - cmpl(x_hi, y_hi); - jcc(Assembler::less, low); - jcc(Assembler::greater, high); - // x_hi is the return register - xorl(x_hi, x_hi); - cmpl(x_lo, y_lo); - jcc(Assembler::below, low); - jcc(Assembler::equal, done); - - bind(high); - xorl(x_hi, x_hi); - increment(x_hi); - jmp(done); - - bind(low); - xorl(x_hi, x_hi); - decrement(x_hi); - - bind(done); -} - - -void MacroAssembler::save_rax(Register tmp) { - if (tmp == noreg) pushl(rax); - else if (tmp != rax) movl(tmp, rax); -} - - -void MacroAssembler::restore_rax(Register tmp) { - if (tmp == noreg) popl(rax); - else if (tmp != rax) movl(rax, tmp); -} - - -void MacroAssembler::fremr(Register tmp) { - save_rax(tmp); - { Label L; - bind(L); - fprem(); - fwait(); fnstsw_ax(); - sahf(); - jcc(Assembler::parity, L); - } - restore_rax(tmp); - // Result is in ST0. - // Note: fxch & fpop to get rid of ST1 - // (otherwise FPU stack could overflow eventually) - fxch(1); - fpop(); -} - - -static const double pi_4 = 0.7853981633974483; - -void MacroAssembler::trigfunc(char trig, int num_fpu_regs_in_use) { - // A hand-coded argument reduction for values in fabs(pi/4, pi/2) - // was attempted in this code; unfortunately it appears that the - // switch to 80-bit precision and back causes this to be - // unprofitable compared with simply performing a runtime call if - // the argument is out of the (-pi/4, pi/4) range. - - Register tmp = noreg; - if (!VM_Version::supports_cmov()) { - // fcmp needs a temporary so preserve rbx, - tmp = rbx; - pushl(tmp); - } - - Label slow_case, done; - - // x ?<= pi/4 - fld_d(ExternalAddress((address)&pi_4)); - fld_s(1); // Stack: X PI/4 X - fabs(); // Stack: |X| PI/4 X - fcmp(tmp); - jcc(Assembler::above, slow_case); - - // fastest case: -pi/4 <= x <= pi/4 - switch(trig) { - case 's': - fsin(); - break; - case 'c': - fcos(); - break; - case 't': - ftan(); - break; - default: - assert(false, "bad intrinsic"); - break; - } - jmp(done); - - // slow case: runtime call - bind(slow_case); - // Preserve registers across runtime call - pushad(); - int incoming_argument_and_return_value_offset = -1; - if (num_fpu_regs_in_use > 1) { - // Must preserve all other FPU regs (could alternatively convert - // SharedRuntime::dsin and dcos into assembly routines known not to trash - // FPU state, but can not trust C compiler) - NEEDS_CLEANUP; - // NOTE that in this case we also push the incoming argument to - // the stack and restore it later; we also use this stack slot to - // hold the return value from dsin or dcos. - for (int i = 0; i < num_fpu_regs_in_use; i++) { - subl(rsp, wordSize*2); - fstp_d(Address(rsp, 0)); - } - incoming_argument_and_return_value_offset = 2*wordSize*(num_fpu_regs_in_use-1); - fld_d(Address(rsp, incoming_argument_and_return_value_offset)); - } - subl(rsp, wordSize*2); - fstp_d(Address(rsp, 0)); - // NOTE: we must not use call_VM_leaf here because that requires a - // complete interpreter frame in debug mode -- same bug as 4387334 - NEEDS_CLEANUP; - // Need to add stack banging before this runtime call if it needs to - // be taken; however, there is no generic stack banging routine at - // the MacroAssembler level - switch(trig) { - case 's': - { - call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dsin))); - } - break; - case 'c': - { - call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dcos))); - } - break; - case 't': - { - call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtan))); - } - break; - default: - assert(false, "bad intrinsic"); - break; - } - addl(rsp, wordSize * 2); - if (num_fpu_regs_in_use > 1) { - // Must save return value to stack and then restore entire FPU stack - fstp_d(Address(rsp, incoming_argument_and_return_value_offset)); - for (int i = 0; i < num_fpu_regs_in_use; i++) { - fld_d(Address(rsp, 0)); - addl(rsp, wordSize*2); - } - } - popad(); - - // Come here with result in F-TOS - bind(done); - - if (tmp != noreg) { - popl(tmp); - } -} - -void MacroAssembler::jC2(Register tmp, Label& L) { - // set parity bit if FPU flag C2 is set (via rax) - save_rax(tmp); - fwait(); fnstsw_ax(); - sahf(); - restore_rax(tmp); - // branch - jcc(Assembler::parity, L); -} - - -void MacroAssembler::jnC2(Register tmp, Label& L) { - // set parity bit if FPU flag C2 is set (via rax) - save_rax(tmp); - fwait(); fnstsw_ax(); - sahf(); - restore_rax(tmp); - // branch - jcc(Assembler::noParity, L); -} - - -void MacroAssembler::fcmp(Register tmp) { - fcmp(tmp, 1, true, true); -} - - -void MacroAssembler::fcmp(Register tmp, int index, bool pop_left, bool pop_right) { - assert(!pop_right || pop_left, "usage error"); - if (VM_Version::supports_cmov()) { - assert(tmp == noreg, "unneeded temp"); - if (pop_left) { - fucomip(index); - } else { - fucomi(index); - } - if (pop_right) { - fpop(); - } - } else { - assert(tmp != noreg, "need temp"); - if (pop_left) { - if (pop_right) { - fcompp(); - } else { - fcomp(index); - } - } else { - fcom(index); - } - // convert FPU condition into eflags condition via rax, - save_rax(tmp); - fwait(); fnstsw_ax(); - sahf(); - restore_rax(tmp); - } - // condition codes set as follows: - // - // CF (corresponds to C0) if x < y - // PF (corresponds to C2) if unordered - // ZF (corresponds to C3) if x = y -} - - -void MacroAssembler::fcmp2int(Register dst, bool unordered_is_less) { - fcmp2int(dst, unordered_is_less, 1, true, true); -} - - -void MacroAssembler::fcmp2int(Register dst, bool unordered_is_less, int index, bool pop_left, bool pop_right) { - fcmp(VM_Version::supports_cmov() ? noreg : dst, index, pop_left, pop_right); - Label L; - if (unordered_is_less) { - movl(dst, -1); - jcc(Assembler::parity, L); - jcc(Assembler::below , L); - movl(dst, 0); - jcc(Assembler::equal , L); - increment(dst); - } else { // unordered is greater - movl(dst, 1); - jcc(Assembler::parity, L); - jcc(Assembler::above , L); - movl(dst, 0); - jcc(Assembler::equal , L); - decrement(dst); - } - bind(L); -} - -void MacroAssembler::cmpss2int(XMMRegister opr1, XMMRegister opr2, Register dst, bool unordered_is_less) { - ucomiss(opr1, opr2); - - Label L; - if (unordered_is_less) { - movl(dst, -1); - jcc(Assembler::parity, L); - jcc(Assembler::below , L); - movl(dst, 0); - jcc(Assembler::equal , L); - increment(dst); - } else { // unordered is greater - movl(dst, 1); - jcc(Assembler::parity, L); - jcc(Assembler::above , L); - movl(dst, 0); - jcc(Assembler::equal , L); - decrement(dst); - } - bind(L); -} - -void MacroAssembler::cmpsd2int(XMMRegister opr1, XMMRegister opr2, Register dst, bool unordered_is_less) { - ucomisd(opr1, opr2); - - Label L; - if (unordered_is_less) { - movl(dst, -1); - jcc(Assembler::parity, L); - jcc(Assembler::below , L); - movl(dst, 0); - jcc(Assembler::equal , L); - increment(dst); - } else { // unordered is greater - movl(dst, 1); - jcc(Assembler::parity, L); - jcc(Assembler::above , L); - movl(dst, 0); - jcc(Assembler::equal , L); - decrement(dst); - } - bind(L); -} - - - -void MacroAssembler::fpop() { - ffree(); - fincstp(); -} - - -void MacroAssembler::sign_extend_short(Register reg) { - if (VM_Version::is_P6()) { - movsxw(reg, reg); - } else { - shll(reg, 16); - sarl(reg, 16); - } -} - - -void MacroAssembler::sign_extend_byte(Register reg) { - if (VM_Version::is_P6() && reg->has_byte_register()) { - movsxb(reg, reg); - } else { - shll(reg, 24); - sarl(reg, 24); - } -} - - -void MacroAssembler::division_with_shift (Register reg, int shift_value) { - assert (shift_value > 0, "illegal shift value"); - Label _is_positive; - testl (reg, reg); - jcc (Assembler::positive, _is_positive); - int offset = (1 << shift_value) - 1 ; - - increment(reg, offset); - - bind (_is_positive); - sarl(reg, shift_value); -} - - -void MacroAssembler::round_to(Register reg, int modulus) { - addl(reg, modulus - 1); - andl(reg, -modulus); -} - -// C++ bool manipulation - -void MacroAssembler::movbool(Register dst, Address src) { - if(sizeof(bool) == 1) - movb(dst, src); - else if(sizeof(bool) == 2) - movw(dst, src); - else if(sizeof(bool) == 4) - movl(dst, src); - else - // unsupported - ShouldNotReachHere(); -} - -void MacroAssembler::movbool(Address dst, bool boolconst) { - if(sizeof(bool) == 1) - movb(dst, (int) boolconst); - else if(sizeof(bool) == 2) - movw(dst, (int) boolconst); - else if(sizeof(bool) == 4) - movl(dst, (int) boolconst); - else - // unsupported - ShouldNotReachHere(); -} - -void MacroAssembler::movbool(Address dst, Register src) { - if(sizeof(bool) == 1) - movb(dst, src); - else if(sizeof(bool) == 2) - movw(dst, src); - else if(sizeof(bool) == 4) - movl(dst, src); - else - // unsupported - ShouldNotReachHere(); -} - -void MacroAssembler::testbool(Register dst) { - if(sizeof(bool) == 1) - testb(dst, (int) 0xff); - else if(sizeof(bool) == 2) { - // testw implementation needed for two byte bools - ShouldNotReachHere(); - } else if(sizeof(bool) == 4) - testl(dst, dst); - else - // unsupported - ShouldNotReachHere(); -} - -void MacroAssembler::verify_oop(Register reg, const char* s) { - if (!VerifyOops) return; - // Pass register number to verify_oop_subroutine - char* b = new char[strlen(s) + 50]; - sprintf(b, "verify_oop: %s: %s", reg->name(), s); - pushl(rax); // save rax, - pushl(reg); // pass register argument - ExternalAddress buffer((address) b); - pushptr(buffer.addr()); - // call indirectly to solve generation ordering problem - movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address())); - call(rax); -} - - -void MacroAssembler::verify_oop_addr(Address addr, const char* s) { - if (!VerifyOops) return; - // QQQ fix this - // Address adjust(addr.base(), addr.index(), addr.scale(), addr.disp() + BytesPerWord); - // Pass register number to verify_oop_subroutine - char* b = new char[strlen(s) + 50]; - sprintf(b, "verify_oop_addr: %s", s); - pushl(rax); // save rax, - // addr may contain rsp so we will have to adjust it based on the push - // we just did - if (addr.uses(rsp)) { - leal(rax, addr); - pushl(Address(rax, BytesPerWord)); - } else { - pushl(addr); - } - ExternalAddress buffer((address) b); - // pass msg argument - pushptr(buffer.addr()); - // call indirectly to solve generation ordering problem - movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address())); - call(rax); - // Caller pops the arguments and restores rax, from the stack -} - - -void MacroAssembler::stop(const char* msg) { - ExternalAddress message((address)msg); - // push address of message - pushptr(message.addr()); - { Label L; call(L, relocInfo::none); bind(L); } // push eip - pushad(); // push registers - call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug))); - hlt(); -} - - -void MacroAssembler::warn(const char* msg) { - push_CPU_state(); - - ExternalAddress message((address) msg); - // push address of message - pushptr(message.addr()); - - call(RuntimeAddress(CAST_FROM_FN_PTR(address, warning))); - addl(rsp, wordSize); // discard argument - pop_CPU_state(); -} - - -void MacroAssembler::debug(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip, char* msg) { - // In order to get locks to work, we need to fake a in_VM state - JavaThread* thread = JavaThread::current(); - JavaThreadState saved_state = thread->thread_state(); - thread->set_thread_state(_thread_in_vm); - if (ShowMessageBoxOnError) { - JavaThread* thread = JavaThread::current(); - JavaThreadState saved_state = thread->thread_state(); - thread->set_thread_state(_thread_in_vm); - ttyLocker ttyl; - if (CountBytecodes || TraceBytecodes || StopInterpreterAt) { - BytecodeCounter::print(); - } - // To see where a verify_oop failed, get $ebx+40/X for this frame. - // This is the value of eip which points to where verify_oop will return. - if (os::message_box(msg, "Execution stopped, print registers?")) { - tty->print_cr("eip = 0x%08x", eip); - tty->print_cr("rax, = 0x%08x", rax); - tty->print_cr("rbx, = 0x%08x", rbx); - tty->print_cr("rcx = 0x%08x", rcx); - tty->print_cr("rdx = 0x%08x", rdx); - tty->print_cr("rdi = 0x%08x", rdi); - tty->print_cr("rsi = 0x%08x", rsi); - tty->print_cr("rbp, = 0x%08x", rbp); - tty->print_cr("rsp = 0x%08x", rsp); - BREAKPOINT; - } - } else { - ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n", msg); - assert(false, "DEBUG MESSAGE"); - } - ThreadStateTransition::transition(thread, _thread_in_vm, saved_state); -} - - - -void MacroAssembler::os_breakpoint() { - // instead of directly emitting a breakpoint, call os:breakpoint for better debugability - // (e.g., MSVC can't call ps() otherwise) - call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint))); -} - - -void MacroAssembler::push_fTOS() { - subl(rsp, 2 * wordSize); - fstp_d(Address(rsp, 0)); -} - - -void MacroAssembler::pop_fTOS() { - fld_d(Address(rsp, 0)); - addl(rsp, 2 * wordSize); -} - - -void MacroAssembler::empty_FPU_stack() { - if (VM_Version::supports_mmx()) { - emms(); - } else { - for (int i = 8; i-- > 0; ) ffree(i); - } -} - - -class ControlWord { - public: - int32_t _value; - - int rounding_control() const { return (_value >> 10) & 3 ; } - int precision_control() const { return (_value >> 8) & 3 ; } - bool precision() const { return ((_value >> 5) & 1) != 0; } - bool underflow() const { return ((_value >> 4) & 1) != 0; } - bool overflow() const { return ((_value >> 3) & 1) != 0; } - bool zero_divide() const { return ((_value >> 2) & 1) != 0; } - bool denormalized() const { return ((_value >> 1) & 1) != 0; } - bool invalid() const { return ((_value >> 0) & 1) != 0; } - - void print() const { - // rounding control - const char* rc; - switch (rounding_control()) { - case 0: rc = "round near"; break; - case 1: rc = "round down"; break; - case 2: rc = "round up "; break; - case 3: rc = "chop "; break; - }; - // precision control - const char* pc; - switch (precision_control()) { - case 0: pc = "24 bits "; break; - case 1: pc = "reserved"; break; - case 2: pc = "53 bits "; break; - case 3: pc = "64 bits "; break; - }; - // flags - char f[9]; - f[0] = ' '; - f[1] = ' '; - f[2] = (precision ()) ? 'P' : 'p'; - f[3] = (underflow ()) ? 'U' : 'u'; - f[4] = (overflow ()) ? 'O' : 'o'; - f[5] = (zero_divide ()) ? 'Z' : 'z'; - f[6] = (denormalized()) ? 'D' : 'd'; - f[7] = (invalid ()) ? 'I' : 'i'; - f[8] = '\x0'; - // output - printf("%04x masks = %s, %s, %s", _value & 0xFFFF, f, rc, pc); - } - -}; - - -class StatusWord { - public: - int32_t _value; - - bool busy() const { return ((_value >> 15) & 1) != 0; } - bool C3() const { return ((_value >> 14) & 1) != 0; } - bool C2() const { return ((_value >> 10) & 1) != 0; } - bool C1() const { return ((_value >> 9) & 1) != 0; } - bool C0() const { return ((_value >> 8) & 1) != 0; } - int top() const { return (_value >> 11) & 7 ; } - bool error_status() const { return ((_value >> 7) & 1) != 0; } - bool stack_fault() const { return ((_value >> 6) & 1) != 0; } - bool precision() const { return ((_value >> 5) & 1) != 0; } - bool underflow() const { return ((_value >> 4) & 1) != 0; } - bool overflow() const { return ((_value >> 3) & 1) != 0; } - bool zero_divide() const { return ((_value >> 2) & 1) != 0; } - bool denormalized() const { return ((_value >> 1) & 1) != 0; } - bool invalid() const { return ((_value >> 0) & 1) != 0; } - - void print() const { - // condition codes - char c[5]; - c[0] = (C3()) ? '3' : '-'; - c[1] = (C2()) ? '2' : '-'; - c[2] = (C1()) ? '1' : '-'; - c[3] = (C0()) ? '0' : '-'; - c[4] = '\x0'; - // flags - char f[9]; - f[0] = (error_status()) ? 'E' : '-'; - f[1] = (stack_fault ()) ? 'S' : '-'; - f[2] = (precision ()) ? 'P' : '-'; - f[3] = (underflow ()) ? 'U' : '-'; - f[4] = (overflow ()) ? 'O' : '-'; - f[5] = (zero_divide ()) ? 'Z' : '-'; - f[6] = (denormalized()) ? 'D' : '-'; - f[7] = (invalid ()) ? 'I' : '-'; - f[8] = '\x0'; - // output - printf("%04x flags = %s, cc = %s, top = %d", _value & 0xFFFF, f, c, top()); - } - -}; - - -class TagWord { - public: - int32_t _value; - - int tag_at(int i) const { return (_value >> (i*2)) & 3; } - - void print() const { - printf("%04x", _value & 0xFFFF); - } - -}; - - -class FPU_Register { - public: - int32_t _m0; - int32_t _m1; - int16_t _ex; - - bool is_indefinite() const { - return _ex == -1 && _m1 == (int32_t)0xC0000000 && _m0 == 0; - } - - void print() const { - char sign = (_ex < 0) ? '-' : '+'; - const char* kind = (_ex == 0x7FFF || _ex == (int16_t)-1) ? "NaN" : " "; - printf("%c%04hx.%08x%08x %s", sign, _ex, _m1, _m0, kind); - }; - -}; - - -class FPU_State { - public: - enum { - register_size = 10, - number_of_registers = 8, - register_mask = 7 - }; - - ControlWord _control_word; - StatusWord _status_word; - TagWord _tag_word; - int32_t _error_offset; - int32_t _error_selector; - int32_t _data_offset; - int32_t _data_selector; - int8_t _register[register_size * number_of_registers]; - - int tag_for_st(int i) const { return _tag_word.tag_at((_status_word.top() + i) & register_mask); } - FPU_Register* st(int i) const { return (FPU_Register*)&_register[register_size * i]; } - - const char* tag_as_string(int tag) const { - switch (tag) { - case 0: return "valid"; - case 1: return "zero"; - case 2: return "special"; - case 3: return "empty"; - } - ShouldNotReachHere() - return NULL; - } - - void print() const { - // print computation registers - { int t = _status_word.top(); - for (int i = 0; i < number_of_registers; i++) { - int j = (i - t) & register_mask; - printf("%c r%d = ST%d = ", (j == 0 ? '*' : ' '), i, j); - st(j)->print(); - printf(" %s\n", tag_as_string(_tag_word.tag_at(i))); - } - } - printf("\n"); - // print control registers - printf("ctrl = "); _control_word.print(); printf("\n"); - printf("stat = "); _status_word .print(); printf("\n"); - printf("tags = "); _tag_word .print(); printf("\n"); - } - -}; - - -class Flag_Register { - public: - int32_t _value; - - bool overflow() const { return ((_value >> 11) & 1) != 0; } - bool direction() const { return ((_value >> 10) & 1) != 0; } - bool sign() const { return ((_value >> 7) & 1) != 0; } - bool zero() const { return ((_value >> 6) & 1) != 0; } - bool auxiliary_carry() const { return ((_value >> 4) & 1) != 0; } - bool parity() const { return ((_value >> 2) & 1) != 0; } - bool carry() const { return ((_value >> 0) & 1) != 0; } - - void print() const { - // flags - char f[8]; - f[0] = (overflow ()) ? 'O' : '-'; - f[1] = (direction ()) ? 'D' : '-'; - f[2] = (sign ()) ? 'S' : '-'; - f[3] = (zero ()) ? 'Z' : '-'; - f[4] = (auxiliary_carry()) ? 'A' : '-'; - f[5] = (parity ()) ? 'P' : '-'; - f[6] = (carry ()) ? 'C' : '-'; - f[7] = '\x0'; - // output - printf("%08x flags = %s", _value, f); - } - -}; - - -class IU_Register { - public: - int32_t _value; - - void print() const { - printf("%08x %11d", _value, _value); - } - -}; - - -class IU_State { - public: - Flag_Register _eflags; - IU_Register _rdi; - IU_Register _rsi; - IU_Register _rbp; - IU_Register _rsp; - IU_Register _rbx; - IU_Register _rdx; - IU_Register _rcx; - IU_Register _rax; - - void print() const { - // computation registers - printf("rax, = "); _rax.print(); printf("\n"); - printf("rbx, = "); _rbx.print(); printf("\n"); - printf("rcx = "); _rcx.print(); printf("\n"); - printf("rdx = "); _rdx.print(); printf("\n"); - printf("rdi = "); _rdi.print(); printf("\n"); - printf("rsi = "); _rsi.print(); printf("\n"); - printf("rbp, = "); _rbp.print(); printf("\n"); - printf("rsp = "); _rsp.print(); printf("\n"); - printf("\n"); - // control registers - printf("flgs = "); _eflags.print(); printf("\n"); - } -}; - - -class CPU_State { - public: - FPU_State _fpu_state; - IU_State _iu_state; - - void print() const { - printf("--------------------------------------------------\n"); - _iu_state .print(); - printf("\n"); - _fpu_state.print(); - printf("--------------------------------------------------\n"); - } - -}; - - -static void _print_CPU_state(CPU_State* state) { - state->print(); -}; - - -void MacroAssembler::print_CPU_state() { - push_CPU_state(); - pushl(rsp); // pass CPU state - call(RuntimeAddress(CAST_FROM_FN_PTR(address, _print_CPU_state))); - addl(rsp, wordSize); // discard argument - pop_CPU_state(); -} - - -static bool _verify_FPU(int stack_depth, char* s, CPU_State* state) { - static int counter = 0; - FPU_State* fs = &state->_fpu_state; - counter++; - // For leaf calls, only verify that the top few elements remain empty. - // We only need 1 empty at the top for C2 code. - if( stack_depth < 0 ) { - if( fs->tag_for_st(7) != 3 ) { - printf("FPR7 not empty\n"); - state->print(); - assert(false, "error"); - return false; - } - return true; // All other stack states do not matter - } - - assert((fs->_control_word._value & 0xffff) == StubRoutines::_fpu_cntrl_wrd_std, - "bad FPU control word"); - - // compute stack depth - int i = 0; - while (i < FPU_State::number_of_registers && fs->tag_for_st(i) < 3) i++; - int d = i; - while (i < FPU_State::number_of_registers && fs->tag_for_st(i) == 3) i++; - // verify findings - if (i != FPU_State::number_of_registers) { - // stack not contiguous - printf("%s: stack not contiguous at ST%d\n", s, i); - state->print(); - assert(false, "error"); - return false; - } - // check if computed stack depth corresponds to expected stack depth - if (stack_depth < 0) { - // expected stack depth is -stack_depth or less - if (d > -stack_depth) { - // too many elements on the stack - printf("%s: <= %d stack elements expected but found %d\n", s, -stack_depth, d); - state->print(); - assert(false, "error"); - return false; - } - } else { - // expected stack depth is stack_depth - if (d != stack_depth) { - // wrong stack depth - printf("%s: %d stack elements expected but found %d\n", s, stack_depth, d); - state->print(); - assert(false, "error"); - return false; - } - } - // everything is cool - return true; -} - - -void MacroAssembler::verify_FPU(int stack_depth, const char* s) { - if (!VerifyFPU) return; - push_CPU_state(); - pushl(rsp); // pass CPU state - ExternalAddress msg((address) s); - // pass message string s - pushptr(msg.addr()); - pushl(stack_depth); // pass stack depth - call(RuntimeAddress(CAST_FROM_FN_PTR(address, _verify_FPU))); - addl(rsp, 3 * wordSize); // discard arguments - // check for error - { Label L; - testl(rax, rax); - jcc(Assembler::notZero, L); - int3(); // break if error condition - bind(L); - } - pop_CPU_state(); -} - - -void MacroAssembler::push_IU_state() { - pushad(); - pushfd(); -} - - -void MacroAssembler::pop_IU_state() { - popfd(); - popad(); -} - - -void MacroAssembler::push_FPU_state() { - subl(rsp, FPUStateSizeInWords * wordSize); - fnsave(Address(rsp, 0)); - fwait(); -} - - -void MacroAssembler::pop_FPU_state() { - frstor(Address(rsp, 0)); - addl(rsp, FPUStateSizeInWords * wordSize); -} - - -void MacroAssembler::push_CPU_state() { - push_IU_state(); - push_FPU_state(); -} - - -void MacroAssembler::pop_CPU_state() { - pop_FPU_state(); - pop_IU_state(); -} - - -void MacroAssembler::push_callee_saved_registers() { - pushl(rsi); - pushl(rdi); - pushl(rdx); - pushl(rcx); -} - - -void MacroAssembler::pop_callee_saved_registers() { - popl(rcx); - popl(rdx); - popl(rdi); - popl(rsi); -} - - -void MacroAssembler::set_word_if_not_zero(Register dst) { - xorl(dst, dst); - set_byte_if_not_zero(dst); -} - -// Write serialization page so VM thread can do a pseudo remote membar. -// We use the current thread pointer to calculate a thread specific -// offset to write to within the page. This minimizes bus traffic -// due to cache line collision. -void MacroAssembler::serialize_memory(Register thread, Register tmp) { - movl(tmp, thread); - shrl(tmp, os::get_serialize_page_shift_count()); - andl(tmp, (os::vm_page_size() - sizeof(int))); - - Address index(noreg, tmp, Address::times_1); - ExternalAddress page(os::get_memory_serialize_page()); - - movptr(ArrayAddress(page, index), tmp); -} - - -void MacroAssembler::verify_tlab() { -#ifdef ASSERT - if (UseTLAB && VerifyOops) { - Label next, ok; - Register t1 = rsi; - Register thread_reg = rbx; - - pushl(t1); - pushl(thread_reg); - get_thread(thread_reg); - - movl(t1, Address(thread_reg, in_bytes(JavaThread::tlab_top_offset()))); - cmpl(t1, Address(thread_reg, in_bytes(JavaThread::tlab_start_offset()))); - jcc(Assembler::aboveEqual, next); - stop("assert(top >= start)"); - should_not_reach_here(); - - bind(next); - movl(t1, Address(thread_reg, in_bytes(JavaThread::tlab_end_offset()))); - cmpl(t1, Address(thread_reg, in_bytes(JavaThread::tlab_top_offset()))); - jcc(Assembler::aboveEqual, ok); - stop("assert(top <= end)"); - should_not_reach_here(); - - bind(ok); - popl(thread_reg); - popl(t1); - } -#endif -} - - -// Defines obj, preserves var_size_in_bytes -void MacroAssembler::eden_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, - Register t1, Label& slow_case) { - assert(obj == rax, "obj must be in rax, for cmpxchg"); - assert_different_registers(obj, var_size_in_bytes, t1); - Register end = t1; - Label retry; - bind(retry); - ExternalAddress heap_top((address) Universe::heap()->top_addr()); - movptr(obj, heap_top); - if (var_size_in_bytes == noreg) { - leal(end, Address(obj, con_size_in_bytes)); - } else { - leal(end, Address(obj, var_size_in_bytes, Address::times_1)); - } - // if end < obj then we wrapped around => object too long => slow case - cmpl(end, obj); - jcc(Assembler::below, slow_case); - cmpptr(end, ExternalAddress((address) Universe::heap()->end_addr())); - jcc(Assembler::above, slow_case); - // Compare obj with the top addr, and if still equal, store the new top addr in - // end at the address of the top addr pointer. Sets ZF if was equal, and clears - // it otherwise. Use lock prefix for atomicity on MPs. - if (os::is_MP()) { - lock(); - } - cmpxchgptr(end, heap_top); - jcc(Assembler::notEqual, retry); -} - - -// Defines obj, preserves var_size_in_bytes, okay for t2 == var_size_in_bytes. -void MacroAssembler::tlab_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, - Register t1, Register t2, Label& slow_case) { - assert_different_registers(obj, t1, t2); - assert_different_registers(obj, var_size_in_bytes, t1); - Register end = t2; - Register thread = t1; - - verify_tlab(); - - get_thread(thread); - - movl(obj, Address(thread, JavaThread::tlab_top_offset())); - if (var_size_in_bytes == noreg) { - leal(end, Address(obj, con_size_in_bytes)); - } else { - leal(end, Address(obj, var_size_in_bytes, Address::times_1)); - } - cmpl(end, Address(thread, JavaThread::tlab_end_offset())); - jcc(Assembler::above, slow_case); - - // update the tlab top pointer - movl(Address(thread, JavaThread::tlab_top_offset()), end); - - // recover var_size_in_bytes if necessary - if (var_size_in_bytes == end) { - subl(var_size_in_bytes, obj); - } - verify_tlab(); -} - -// Preserves rbx, and rdx. -void MacroAssembler::tlab_refill(Label& retry, Label& try_eden, Label& slow_case) { - Register top = rax; - Register t1 = rcx; - Register t2 = rsi; - Register thread_reg = rdi; - assert_different_registers(top, thread_reg, t1, t2, /* preserve: */ rbx, rdx); - Label do_refill, discard_tlab; - - if (CMSIncrementalMode || !Universe::heap()->supports_inline_contig_alloc()) { - // No allocation in the shared eden. - jmp(slow_case); - } - - get_thread(thread_reg); - - movl(top, Address(thread_reg, in_bytes(JavaThread::tlab_top_offset()))); - movl(t1, Address(thread_reg, in_bytes(JavaThread::tlab_end_offset()))); - - // calculate amount of free space - subl(t1, top); - shrl(t1, LogHeapWordSize); - - // Retain tlab and allocate object in shared space if - // the amount free in the tlab is too large to discard. - cmpl(t1, Address(thread_reg, in_bytes(JavaThread::tlab_refill_waste_limit_offset()))); - jcc(Assembler::lessEqual, discard_tlab); - - // Retain - movl(t2, ThreadLocalAllocBuffer::refill_waste_limit_increment()); - addl(Address(thread_reg, in_bytes(JavaThread::tlab_refill_waste_limit_offset())), t2); - if (TLABStats) { - // increment number of slow_allocations - addl(Address(thread_reg, in_bytes(JavaThread::tlab_slow_allocations_offset())), 1); - } - jmp(try_eden); - - bind(discard_tlab); - if (TLABStats) { - // increment number of refills - addl(Address(thread_reg, in_bytes(JavaThread::tlab_number_of_refills_offset())), 1); - // accumulate wastage -- t1 is amount free in tlab - addl(Address(thread_reg, in_bytes(JavaThread::tlab_fast_refill_waste_offset())), t1); - } - - // if tlab is currently allocated (top or end != null) then - // fill [top, end + alignment_reserve) with array object - testl (top, top); - jcc(Assembler::zero, do_refill); - - // set up the mark word - movl(Address(top, oopDesc::mark_offset_in_bytes()), (int)markOopDesc::prototype()->copy_set_hash(0x2)); - // set the length to the remaining space - subl(t1, typeArrayOopDesc::header_size(T_INT)); - addl(t1, ThreadLocalAllocBuffer::alignment_reserve()); - shll(t1, log2_intptr(HeapWordSize/sizeof(jint))); - movl(Address(top, arrayOopDesc::length_offset_in_bytes()), t1); - // set klass to intArrayKlass - // dubious reloc why not an oop reloc? - movptr(t1, ExternalAddress((address) Universe::intArrayKlassObj_addr())); - movl(Address(top, oopDesc::klass_offset_in_bytes()), t1); - - // refill the tlab with an eden allocation - bind(do_refill); - movl(t1, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset()))); - shll(t1, LogHeapWordSize); - // add object_size ?? - eden_allocate(top, t1, 0, t2, slow_case); - - // Check that t1 was preserved in eden_allocate. -#ifdef ASSERT - if (UseTLAB) { - Label ok; - Register tsize = rsi; - assert_different_registers(tsize, thread_reg, t1); - pushl(tsize); - movl(tsize, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset()))); - shll(tsize, LogHeapWordSize); - cmpl(t1, tsize); - jcc(Assembler::equal, ok); - stop("assert(t1 != tlab size)"); - should_not_reach_here(); - - bind(ok); - popl(tsize); - } -#endif - movl(Address(thread_reg, in_bytes(JavaThread::tlab_start_offset())), top); - movl(Address(thread_reg, in_bytes(JavaThread::tlab_top_offset())), top); - addl(top, t1); - subl(top, ThreadLocalAllocBuffer::alignment_reserve_in_bytes()); - movl(Address(thread_reg, in_bytes(JavaThread::tlab_end_offset())), top); - verify_tlab(); - jmp(retry); -} - - -int MacroAssembler::biased_locking_enter(Register lock_reg, Register obj_reg, Register swap_reg, Register tmp_reg, - bool swap_reg_contains_mark, - Label& done, Label* slow_case, - BiasedLockingCounters* counters) { - assert(UseBiasedLocking, "why call this otherwise?"); - assert(swap_reg == rax, "swap_reg must be rax, for cmpxchg"); - assert_different_registers(lock_reg, obj_reg, swap_reg); - - if (PrintBiasedLockingStatistics && counters == NULL) - counters = BiasedLocking::counters(); - - bool need_tmp_reg = false; - if (tmp_reg == noreg) { - need_tmp_reg = true; - tmp_reg = lock_reg; - } else { - assert_different_registers(lock_reg, obj_reg, swap_reg, tmp_reg); - } - assert(markOopDesc::age_shift == markOopDesc::lock_bits + markOopDesc::biased_lock_bits, "biased locking makes assumptions about bit layout"); - Address mark_addr (obj_reg, oopDesc::mark_offset_in_bytes()); - Address klass_addr (obj_reg, oopDesc::klass_offset_in_bytes()); - Address saved_mark_addr(lock_reg, 0); - - // Biased locking - // See whether the lock is currently biased toward our thread and - // whether the epoch is still valid - // Note that the runtime guarantees sufficient alignment of JavaThread - // pointers to allow age to be placed into low bits - // First check to see whether biasing is even enabled for this object - Label cas_label; - int null_check_offset = -1; - if (!swap_reg_contains_mark) { - null_check_offset = offset(); - movl(swap_reg, mark_addr); - } - if (need_tmp_reg) { - pushl(tmp_reg); - } - movl(tmp_reg, swap_reg); - andl(tmp_reg, markOopDesc::biased_lock_mask_in_place); - cmpl(tmp_reg, markOopDesc::biased_lock_pattern); - if (need_tmp_reg) { - popl(tmp_reg); - } - jcc(Assembler::notEqual, cas_label); - // The bias pattern is present in the object's header. Need to check - // whether the bias owner and the epoch are both still current. - // Note that because there is no current thread register on x86 we - // need to store off the mark word we read out of the object to - // avoid reloading it and needing to recheck invariants below. This - // store is unfortunate but it makes the overall code shorter and - // simpler. - movl(saved_mark_addr, swap_reg); - if (need_tmp_reg) { - pushl(tmp_reg); - } - get_thread(tmp_reg); - xorl(swap_reg, tmp_reg); - if (swap_reg_contains_mark) { - null_check_offset = offset(); - } - movl(tmp_reg, klass_addr); - xorl(swap_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); - andl(swap_reg, ~((int) markOopDesc::age_mask_in_place)); - if (need_tmp_reg) { - popl(tmp_reg); - } - if (counters != NULL) { - cond_inc32(Assembler::zero, - ExternalAddress((address)counters->biased_lock_entry_count_addr())); - } - jcc(Assembler::equal, done); - - Label try_revoke_bias; - Label try_rebias; - - // At this point we know that the header has the bias pattern and - // that we are not the bias owner in the current epoch. We need to - // figure out more details about the state of the header in order to - // know what operations can be legally performed on the object's - // header. - - // If the low three bits in the xor result aren't clear, that means - // the prototype header is no longer biased and we have to revoke - // the bias on this object. - testl(swap_reg, markOopDesc::biased_lock_mask_in_place); - jcc(Assembler::notZero, try_revoke_bias); - - // Biasing is still enabled for this data type. See whether the - // epoch of the current bias is still valid, meaning that the epoch - // bits of the mark word are equal to the epoch bits of the - // prototype header. (Note that the prototype header's epoch bits - // only change at a safepoint.) If not, attempt to rebias the object - // toward the current thread. Note that we must be absolutely sure - // that the current epoch is invalid in order to do this because - // otherwise the manipulations it performs on the mark word are - // illegal. - testl(swap_reg, markOopDesc::epoch_mask_in_place); - jcc(Assembler::notZero, try_rebias); - - // The epoch of the current bias is still valid but we know nothing - // about the owner; it might be set or it might be clear. Try to - // acquire the bias of the object using an atomic operation. If this - // fails we will go in to the runtime to revoke the object's bias. - // Note that we first construct the presumed unbiased header so we - // don't accidentally blow away another thread's valid bias. - movl(swap_reg, saved_mark_addr); - andl(swap_reg, - markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place); - if (need_tmp_reg) { - pushl(tmp_reg); - } - get_thread(tmp_reg); - orl(tmp_reg, swap_reg); - if (os::is_MP()) { - lock(); - } - cmpxchg(tmp_reg, Address(obj_reg, 0)); - if (need_tmp_reg) { - popl(tmp_reg); - } - // If the biasing toward our thread failed, this means that - // another thread succeeded in biasing it toward itself and we - // need to revoke that bias. The revocation will occur in the - // interpreter runtime in the slow case. - if (counters != NULL) { - cond_inc32(Assembler::zero, - ExternalAddress((address)counters->anonymously_biased_lock_entry_count_addr())); - } - if (slow_case != NULL) { - jcc(Assembler::notZero, *slow_case); - } - jmp(done); - - bind(try_rebias); - // At this point we know the epoch has expired, meaning that the - // current "bias owner", if any, is actually invalid. Under these - // circumstances _only_, we are allowed to use the current header's - // value as the comparison value when doing the cas to acquire the - // bias in the current epoch. In other words, we allow transfer of - // the bias from one thread to another directly in this situation. - // - // FIXME: due to a lack of registers we currently blow away the age - // bits in this situation. Should attempt to preserve them. - if (need_tmp_reg) { - pushl(tmp_reg); - } - get_thread(tmp_reg); - movl(swap_reg, klass_addr); - orl(tmp_reg, Address(swap_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); - movl(swap_reg, saved_mark_addr); - if (os::is_MP()) { - lock(); - } - cmpxchg(tmp_reg, Address(obj_reg, 0)); - if (need_tmp_reg) { - popl(tmp_reg); - } - // If the biasing toward our thread failed, then another thread - // succeeded in biasing it toward itself and we need to revoke that - // bias. The revocation will occur in the runtime in the slow case. - if (counters != NULL) { - cond_inc32(Assembler::zero, - ExternalAddress((address)counters->rebiased_lock_entry_count_addr())); - } - if (slow_case != NULL) { - jcc(Assembler::notZero, *slow_case); - } - jmp(done); - - bind(try_revoke_bias); - // The prototype mark in the klass doesn't have the bias bit set any - // more, indicating that objects of this data type are not supposed - // to be biased any more. We are going to try to reset the mark of - // this object to the prototype value and fall through to the - // CAS-based locking scheme. Note that if our CAS fails, it means - // that another thread raced us for the privilege of revoking the - // bias of this particular object, so it's okay to continue in the - // normal locking code. - // - // FIXME: due to a lack of registers we currently blow away the age - // bits in this situation. Should attempt to preserve them. - movl(swap_reg, saved_mark_addr); - if (need_tmp_reg) { - pushl(tmp_reg); - } - movl(tmp_reg, klass_addr); - movl(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); - if (os::is_MP()) { - lock(); - } - cmpxchg(tmp_reg, Address(obj_reg, 0)); - if (need_tmp_reg) { - popl(tmp_reg); - } - // Fall through to the normal CAS-based lock, because no matter what - // the result of the above CAS, some thread must have succeeded in - // removing the bias bit from the object's header. - if (counters != NULL) { - cond_inc32(Assembler::zero, - ExternalAddress((address)counters->revoked_lock_entry_count_addr())); - } - - bind(cas_label); - - return null_check_offset; -} - - -void MacroAssembler::biased_locking_exit(Register obj_reg, Register temp_reg, Label& done) { - assert(UseBiasedLocking, "why call this otherwise?"); - - // Check for biased locking unlock case, which is a no-op - // Note: we do not have to check the thread ID for two reasons. - // First, the interpreter checks for IllegalMonitorStateException at - // a higher level. Second, if the bias was revoked while we held the - // lock, the object could not be rebiased toward another thread, so - // the bias bit would be clear. - movl(temp_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); - andl(temp_reg, markOopDesc::biased_lock_mask_in_place); - cmpl(temp_reg, markOopDesc::biased_lock_pattern); - jcc(Assembler::equal, done); -} - - -Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) { - switch (cond) { - // Note some conditions are synonyms for others - case Assembler::zero: return Assembler::notZero; - case Assembler::notZero: return Assembler::zero; - case Assembler::less: return Assembler::greaterEqual; - case Assembler::lessEqual: return Assembler::greater; - case Assembler::greater: return Assembler::lessEqual; - case Assembler::greaterEqual: return Assembler::less; - case Assembler::below: return Assembler::aboveEqual; - case Assembler::belowEqual: return Assembler::above; - case Assembler::above: return Assembler::belowEqual; - case Assembler::aboveEqual: return Assembler::below; - case Assembler::overflow: return Assembler::noOverflow; - case Assembler::noOverflow: return Assembler::overflow; - case Assembler::negative: return Assembler::positive; - case Assembler::positive: return Assembler::negative; - case Assembler::parity: return Assembler::noParity; - case Assembler::noParity: return Assembler::parity; - } - ShouldNotReachHere(); return Assembler::overflow; -} - - -void MacroAssembler::cond_inc32(Condition cond, AddressLiteral counter_addr) { - Condition negated_cond = negate_condition(cond); - Label L; - jcc(negated_cond, L); - atomic_incl(counter_addr); - bind(L); -} - -void MacroAssembler::atomic_incl(AddressLiteral counter_addr) { - pushfd(); - if (os::is_MP()) - lock(); - increment(counter_addr); - popfd(); -} - -SkipIfEqual::SkipIfEqual( - MacroAssembler* masm, const bool* flag_addr, bool value) { - _masm = masm; - _masm->cmp8(ExternalAddress((address)flag_addr), value); - _masm->jcc(Assembler::equal, _label); -} - -SkipIfEqual::~SkipIfEqual() { - _masm->bind(_label); -} - - -// Writes to stack successive pages until offset reached to check for -// stack overflow + shadow pages. This clobbers tmp. -void MacroAssembler::bang_stack_size(Register size, Register tmp) { - movl(tmp, rsp); - // Bang stack for total size given plus shadow page size. - // Bang one page at a time because large size can bang beyond yellow and - // red zones. - Label loop; - bind(loop); - movl(Address(tmp, (-os::vm_page_size())), size ); - subl(tmp, os::vm_page_size()); - subl(size, os::vm_page_size()); - jcc(Assembler::greater, loop); - - // Bang down shadow pages too. - // The -1 because we already subtracted 1 page. - for (int i = 0; i< StackShadowPages-1; i++) { - movl(Address(tmp, (-i*os::vm_page_size())), size ); - } -} diff --git a/hotspot/src/cpu/x86/vm/assembler_x86_32.inline.hpp b/hotspot/src/cpu/x86/vm/assembler_x86_32.inline.hpp deleted file mode 100644 index 8e20a2e0620..00000000000 --- a/hotspot/src/cpu/x86/vm/assembler_x86_32.inline.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 1997-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. - * - */ - -inline void MacroAssembler::pd_patch_instruction(address branch, address target) { - unsigned char op = branch[0]; - assert(op == 0xE8 /* call */ || - op == 0xE9 /* jmp */ || - op == 0xEB /* short jmp */ || - (op & 0xF0) == 0x70 /* short jcc */ || - op == 0x0F && (branch[1] & 0xF0) == 0x80 /* jcc */, - "Invalid opcode at patch point"); - - if (op == 0xEB || (op & 0xF0) == 0x70) { - // short offset operators (jmp and jcc) - char* disp = (char*) &branch[1]; - int imm8 = target - (address) &disp[1]; - guarantee(this->is8bit(imm8), "Short forward jump exceeds 8-bit offset"); - *disp = imm8; - } else { - int* disp = (int*) &branch[(op == 0x0F)? 2: 1]; - int imm32 = target - (address) &disp[1]; - *disp = imm32; - } -} - -#ifndef PRODUCT -inline void MacroAssembler::pd_print_patched_instruction(address branch) { - const char* s; - unsigned char op = branch[0]; - if (op == 0xE8) { - s = "call"; - } else if (op == 0xE9 || op == 0xEB) { - s = "jmp"; - } else if ((op & 0xF0) == 0x70) { - s = "jcc"; - } else if (op == 0x0F) { - s = "jcc"; - } else { - s = "????"; - } - tty->print("%s (unresolved)", s); -} -#endif // ndef PRODUCT diff --git a/hotspot/src/cpu/x86/vm/assembler_x86_64.hpp b/hotspot/src/cpu/x86/vm/assembler_x86_64.hpp deleted file mode 100644 index bf509e02b22..00000000000 --- a/hotspot/src/cpu/x86/vm/assembler_x86_64.hpp +++ /dev/null @@ -1,1477 +0,0 @@ -/* - * Copyright 2003-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. - * - */ - -class BiasedLockingCounters; - -// Contains all the definitions needed for amd64 assembly code generation. - -#ifdef _LP64 -// Calling convention -class Argument VALUE_OBJ_CLASS_SPEC { - public: - enum { -#ifdef _WIN64 - n_int_register_parameters_c = 4, // rcx, rdx, r8, r9 (c_rarg0, c_rarg1, ...) - n_float_register_parameters_c = 4, // xmm0 - xmm3 (c_farg0, c_farg1, ... ) -#else - n_int_register_parameters_c = 6, // rdi, rsi, rdx, rcx, r8, r9 (c_rarg0, c_rarg1, ...) - n_float_register_parameters_c = 8, // xmm0 - xmm7 (c_farg0, c_farg1, ... ) -#endif // _WIN64 - n_int_register_parameters_j = 6, // j_rarg0, j_rarg1, ... - n_float_register_parameters_j = 8 // j_farg0, j_farg1, ... - }; -}; - - -// Symbolically name the register arguments used by the c calling convention. -// Windows is different from linux/solaris. So much for standards... - -#ifdef _WIN64 - -REGISTER_DECLARATION(Register, c_rarg0, rcx); -REGISTER_DECLARATION(Register, c_rarg1, rdx); -REGISTER_DECLARATION(Register, c_rarg2, r8); -REGISTER_DECLARATION(Register, c_rarg3, r9); - -REGISTER_DECLARATION(XMMRegister, c_farg0, xmm0); -REGISTER_DECLARATION(XMMRegister, c_farg1, xmm1); -REGISTER_DECLARATION(XMMRegister, c_farg2, xmm2); -REGISTER_DECLARATION(XMMRegister, c_farg3, xmm3); - -#else - -REGISTER_DECLARATION(Register, c_rarg0, rdi); -REGISTER_DECLARATION(Register, c_rarg1, rsi); -REGISTER_DECLARATION(Register, c_rarg2, rdx); -REGISTER_DECLARATION(Register, c_rarg3, rcx); -REGISTER_DECLARATION(Register, c_rarg4, r8); -REGISTER_DECLARATION(Register, c_rarg5, r9); - -REGISTER_DECLARATION(XMMRegister, c_farg0, xmm0); -REGISTER_DECLARATION(XMMRegister, c_farg1, xmm1); -REGISTER_DECLARATION(XMMRegister, c_farg2, xmm2); -REGISTER_DECLARATION(XMMRegister, c_farg3, xmm3); -REGISTER_DECLARATION(XMMRegister, c_farg4, xmm4); -REGISTER_DECLARATION(XMMRegister, c_farg5, xmm5); -REGISTER_DECLARATION(XMMRegister, c_farg6, xmm6); -REGISTER_DECLARATION(XMMRegister, c_farg7, xmm7); - -#endif // _WIN64 - -// Symbolically name the register arguments used by the Java calling convention. -// We have control over the convention for java so we can do what we please. -// What pleases us is to offset the java calling convention so that when -// we call a suitable jni method the arguments are lined up and we don't -// have to do little shuffling. A suitable jni method is non-static and a -// small number of arguments (two fewer args on windows) -// -// |-------------------------------------------------------| -// | c_rarg0 c_rarg1 c_rarg2 c_rarg3 c_rarg4 c_rarg5 | -// |-------------------------------------------------------| -// | rcx rdx r8 r9 rdi* rsi* | windows (* not a c_rarg) -// | rdi rsi rdx rcx r8 r9 | solaris/linux -// |-------------------------------------------------------| -// | j_rarg5 j_rarg0 j_rarg1 j_rarg2 j_rarg3 j_rarg4 | -// |-------------------------------------------------------| - -REGISTER_DECLARATION(Register, j_rarg0, c_rarg1); -REGISTER_DECLARATION(Register, j_rarg1, c_rarg2); -REGISTER_DECLARATION(Register, j_rarg2, c_rarg3); -// Windows runs out of register args here -#ifdef _WIN64 -REGISTER_DECLARATION(Register, j_rarg3, rdi); -REGISTER_DECLARATION(Register, j_rarg4, rsi); -#else -REGISTER_DECLARATION(Register, j_rarg3, c_rarg4); -REGISTER_DECLARATION(Register, j_rarg4, c_rarg5); -#endif // _WIN64 -REGISTER_DECLARATION(Register, j_rarg5, c_rarg0); - -REGISTER_DECLARATION(XMMRegister, j_farg0, xmm0); -REGISTER_DECLARATION(XMMRegister, j_farg1, xmm1); -REGISTER_DECLARATION(XMMRegister, j_farg2, xmm2); -REGISTER_DECLARATION(XMMRegister, j_farg3, xmm3); -REGISTER_DECLARATION(XMMRegister, j_farg4, xmm4); -REGISTER_DECLARATION(XMMRegister, j_farg5, xmm5); -REGISTER_DECLARATION(XMMRegister, j_farg6, xmm6); -REGISTER_DECLARATION(XMMRegister, j_farg7, xmm7); - -REGISTER_DECLARATION(Register, rscratch1, r10); // volatile -REGISTER_DECLARATION(Register, rscratch2, r11); // volatile - -REGISTER_DECLARATION(Register, r12_heapbase, r12); // callee-saved -REGISTER_DECLARATION(Register, r15_thread, r15); // callee-saved - -#endif // _LP64 - -// Address is an abstraction used to represent a memory location -// using any of the amd64 addressing modes with one object. -// -// Note: A register location is represented via a Register, not -// via an address for efficiency & simplicity reasons. - -class ArrayAddress; - -class Address VALUE_OBJ_CLASS_SPEC { - public: - enum ScaleFactor { - no_scale = -1, - times_1 = 0, - times_2 = 1, - times_4 = 2, - times_8 = 3 - }; - - private: - Register _base; - Register _index; - ScaleFactor _scale; - int _disp; - RelocationHolder _rspec; - - // Easily misused constructors make them private - Address(int disp, address loc, relocInfo::relocType rtype); - Address(int disp, address loc, RelocationHolder spec); - - public: - // creation - Address() - : _base(noreg), - _index(noreg), - _scale(no_scale), - _disp(0) { - } - - // No default displacement otherwise Register can be implicitly - // converted to 0(Register) which is quite a different animal. - - Address(Register base, int disp) - : _base(base), - _index(noreg), - _scale(no_scale), - _disp(disp) { - } - - Address(Register base, Register index, ScaleFactor scale, int disp = 0) - : _base (base), - _index(index), - _scale(scale), - _disp (disp) { - assert(!index->is_valid() == (scale == Address::no_scale), - "inconsistent address"); - } - - // The following two overloads are used in connection with the - // ByteSize type (see sizes.hpp). They simplify the use of - // ByteSize'd arguments in assembly code. Note that their equivalent - // for the optimized build are the member functions with int disp - // argument since ByteSize is mapped to an int type in that case. - // - // Note: DO NOT introduce similar overloaded functions for WordSize - // arguments as in the optimized mode, both ByteSize and WordSize - // are mapped to the same type and thus the compiler cannot make a - // distinction anymore (=> compiler errors). - -#ifdef ASSERT - Address(Register base, ByteSize disp) - : _base(base), - _index(noreg), - _scale(no_scale), - _disp(in_bytes(disp)) { - } - - Address(Register base, Register index, ScaleFactor scale, ByteSize disp) - : _base(base), - _index(index), - _scale(scale), - _disp(in_bytes(disp)) { - assert(!index->is_valid() == (scale == Address::no_scale), - "inconsistent address"); - } -#endif // ASSERT - - // accessors - bool uses(Register reg) const { - return _base == reg || _index == reg; - } - - // Convert the raw encoding form into the form expected by the constructor for - // Address. An index of 4 (rsp) corresponds to having no index, so convert - // that to noreg for the Address constructor. - static Address make_raw(int base, int index, int scale, int disp); - - static Address make_array(ArrayAddress); - - private: - bool base_needs_rex() const { - return _base != noreg && _base->encoding() >= 8; - } - - bool index_needs_rex() const { - return _index != noreg &&_index->encoding() >= 8; - } - - relocInfo::relocType reloc() const { return _rspec.type(); } - - friend class Assembler; - friend class MacroAssembler; - friend class LIR_Assembler; // base/index/scale/disp -}; - -// -// AddressLiteral has been split out from Address because operands of this type -// need to be treated specially on 32bit vs. 64bit platforms. By splitting it out -// the few instructions that need to deal with address literals are unique and the -// MacroAssembler does not have to implement every instruction in the Assembler -// in order to search for address literals that may need special handling depending -// on the instruction and the platform. As small step on the way to merging i486/amd64 -// directories. -// -class AddressLiteral VALUE_OBJ_CLASS_SPEC { - friend class ArrayAddress; - RelocationHolder _rspec; - // Typically we use AddressLiterals we want to use their rval - // However in some situations we want the lval (effect address) of the item. - // We provide a special factory for making those lvals. - bool _is_lval; - - // If the target is far we'll need to load the ea of this to - // a register to reach it. Otherwise if near we can do rip - // relative addressing. - - address _target; - - protected: - // creation - AddressLiteral() - : _is_lval(false), - _target(NULL) - {} - - public: - - - AddressLiteral(address target, relocInfo::relocType rtype); - - AddressLiteral(address target, RelocationHolder const& rspec) - : _rspec(rspec), - _is_lval(false), - _target(target) - {} - - AddressLiteral addr() { - AddressLiteral ret = *this; - ret._is_lval = true; - return ret; - } - - - private: - - address target() { return _target; } - bool is_lval() { return _is_lval; } - - relocInfo::relocType reloc() const { return _rspec.type(); } - const RelocationHolder& rspec() const { return _rspec; } - - friend class Assembler; - friend class MacroAssembler; - friend class Address; - friend class LIR_Assembler; -}; - -// Convience classes -class RuntimeAddress: public AddressLiteral { - - public: - - RuntimeAddress(address target) : AddressLiteral(target, relocInfo::runtime_call_type) {} - -}; - -class OopAddress: public AddressLiteral { - - public: - - OopAddress(address target) : AddressLiteral(target, relocInfo::oop_type){} - -}; - -class ExternalAddress: public AddressLiteral { - - public: - - ExternalAddress(address target) : AddressLiteral(target, relocInfo::external_word_type){} - -}; - -class InternalAddress: public AddressLiteral { - - public: - - InternalAddress(address target) : AddressLiteral(target, relocInfo::internal_word_type) {} - -}; - -// x86 can do array addressing as a single operation since disp can be an absolute -// address but amd64 can't [e.g. array_base(rx, ry:width) ]. We create a class -// that expresses the concept but does extra magic on amd64 to get the final result - -class ArrayAddress VALUE_OBJ_CLASS_SPEC { - private: - - AddressLiteral _base; - Address _index; - - public: - - ArrayAddress() {}; - ArrayAddress(AddressLiteral base, Address index): _base(base), _index(index) {}; - AddressLiteral base() { return _base; } - Address index() { return _index; } - -}; - -// The amd64 Assembler: Pure assembler doing NO optimizations on -// the instruction level (e.g. mov rax, 0 is not translated into xor -// rax, rax!); i.e., what you write is what you get. The Assembler is -// generating code into a CodeBuffer. - -const int FPUStateSizeInWords = 512 / wordSize; - -class Assembler : public AbstractAssembler { - friend class AbstractAssembler; // for the non-virtual hack - friend class StubGenerator; - - - protected: -#ifdef ASSERT - void check_relocation(RelocationHolder const& rspec, int format); -#endif - - inline void emit_long64(jlong x); - - void emit_data(jint data, relocInfo::relocType rtype, int format /* = 1 */); - void emit_data(jint data, RelocationHolder const& rspec, int format /* = 1 */); - void emit_data64(jlong data, relocInfo::relocType rtype, int format = 0); - void emit_data64(jlong data, RelocationHolder const& rspec, int format = 0); - - // Helper functions for groups of instructions - void emit_arith_b(int op1, int op2, Register dst, int imm8); - - void emit_arith(int op1, int op2, Register dst, int imm32); - // only x86?? - void emit_arith(int op1, int op2, Register dst, jobject obj); - void emit_arith(int op1, int op2, Register dst, Register src); - - void emit_operand(Register reg, - Register base, Register index, Address::ScaleFactor scale, - int disp, - RelocationHolder const& rspec, - int rip_relative_correction = 0); - void emit_operand(Register reg, Address adr, - int rip_relative_correction = 0); - void emit_operand(XMMRegister reg, - Register base, Register index, Address::ScaleFactor scale, - int disp, - RelocationHolder const& rspec, - int rip_relative_correction = 0); - void emit_operand(XMMRegister reg, Address adr, - int rip_relative_correction = 0); - - // Immediate-to-memory forms - void emit_arith_operand(int op1, Register rm, Address adr, int imm32); - - void emit_farith(int b1, int b2, int i); - - bool reachable(AddressLiteral adr); - - // These are all easily abused and hence protected - - // Make these disappear in 64bit mode since they would never be correct -#ifndef _LP64 - void cmp_literal32(Register src1, int32_t imm32, RelocationHolder const& rspec); - void cmp_literal32(Address src1, int32_t imm32, RelocationHolder const& rspec); - - void mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec); - void mov_literal32(Address dst, int32_t imm32, RelocationHolder const& rspec); - - void push_literal32(int32_t imm32, RelocationHolder const& rspec); -#endif // _LP64 - - - void mov_literal64(Register dst, intptr_t imm64, RelocationHolder const& rspec); - - // These are unique in that we are ensured by the caller that the 32bit - // relative in these instructions will always be able to reach the potentially - // 64bit address described by entry. Since they can take a 64bit address they - // don't have the 32 suffix like the other instructions in this class. - void jmp_literal(address entry, RelocationHolder const& rspec); - void call_literal(address entry, RelocationHolder const& rspec); - - public: - enum Condition { // The amd64 condition codes used for conditional jumps/moves. - zero = 0x4, - notZero = 0x5, - equal = 0x4, - notEqual = 0x5, - less = 0xc, - lessEqual = 0xe, - greater = 0xf, - greaterEqual = 0xd, - below = 0x2, - belowEqual = 0x6, - above = 0x7, - aboveEqual = 0x3, - overflow = 0x0, - noOverflow = 0x1, - carrySet = 0x2, - carryClear = 0x3, - negative = 0x8, - positive = 0x9, - parity = 0xa, - noParity = 0xb - }; - - enum Prefix { - // segment overrides - // XXX remove segment prefixes - CS_segment = 0x2e, - SS_segment = 0x36, - DS_segment = 0x3e, - ES_segment = 0x26, - FS_segment = 0x64, - GS_segment = 0x65, - - REX = 0x40, - - REX_B = 0x41, - REX_X = 0x42, - REX_XB = 0x43, - REX_R = 0x44, - REX_RB = 0x45, - REX_RX = 0x46, - REX_RXB = 0x47, - - REX_W = 0x48, - - REX_WB = 0x49, - REX_WX = 0x4A, - REX_WXB = 0x4B, - REX_WR = 0x4C, - REX_WRB = 0x4D, - REX_WRX = 0x4E, - REX_WRXB = 0x4F - }; - - enum WhichOperand { - // input to locate_operand, and format code for relocations - imm64_operand = 0, // embedded 64-bit immediate operand - disp32_operand = 1, // embedded 32-bit displacement - call32_operand = 2, // embedded 32-bit self-relative displacement -#ifndef AMD64 - _WhichOperand_limit = 3 -#else - narrow_oop_operand = 3, // embedded 32-bit immediate narrow oop - _WhichOperand_limit = 4 -#endif - }; - - public: - - // Creation - Assembler(CodeBuffer* code) - : AbstractAssembler(code) { - } - - // Decoding - static address locate_operand(address inst, WhichOperand which); - static address locate_next_instruction(address inst); - - // Utilities - - static bool is_simm(int64_t x, int nbits) { return -( CONST64(1) << (nbits-1) ) <= x && x < ( CONST64(1) << (nbits-1) ); } - static bool is_simm32 (int64_t x) { return x == (int64_t)(int32_t)x; } - - - // Stack - void pushaq(); - void popaq(); - - void pushfq(); - void popfq(); - - void pushq(int imm32); - - void pushq(Register src); - void pushq(Address src); - - void popq(Register dst); - void popq(Address dst); - - // Instruction prefixes - void prefix(Prefix p); - - int prefix_and_encode(int reg_enc, bool byteinst = false); - int prefixq_and_encode(int reg_enc); - - int prefix_and_encode(int dst_enc, int src_enc, bool byteinst = false); - int prefixq_and_encode(int dst_enc, int src_enc); - - void prefix(Register reg); - void prefix(Address adr); - void prefixq(Address adr); - - void prefix(Address adr, Register reg, bool byteinst = false); - void prefixq(Address adr, Register reg); - - void prefix(Address adr, XMMRegister reg); - - // Moves - void movb(Register dst, Address src); - void movb(Address dst, int imm8); - void movb(Address dst, Register src); - - void movw(Address dst, int imm16); - void movw(Register dst, Address src); - void movw(Address dst, Register src); - - void movl(Register dst, int imm32); - void movl(Register dst, Register src); - void movl(Register dst, Address src); - void movl(Address dst, int imm32); - void movl(Address dst, Register src); - - void movq(Register dst, Register src); - void movq(Register dst, Address src); - void movq(Address dst, Register src); - // These prevent using movq from converting a zero (like NULL) into Register - // by giving the compiler two choices it can't resolve - void movq(Address dst, void* dummy); - void movq(Register dst, void* dummy); - - void mov64(Register dst, intptr_t imm64); - void mov64(Address dst, intptr_t imm64); - - void movsbl(Register dst, Address src); - void movsbl(Register dst, Register src); - void movswl(Register dst, Address src); - void movswl(Register dst, Register src); - void movslq(Register dst, Address src); - void movslq(Register dst, Register src); - - void movzbl(Register dst, Address src); - void movzbl(Register dst, Register src); - void movzwl(Register dst, Address src); - void movzwl(Register dst, Register src); - - protected: // Avoid using the next instructions directly. - // New cpus require use of movsd and movss to avoid partial register stall - // when loading from memory. But for old Opteron use movlpd instead of movsd. - // The selection is done in MacroAssembler::movdbl() and movflt(). - void movss(XMMRegister dst, XMMRegister src); - void movss(XMMRegister dst, Address src); - void movss(Address dst, XMMRegister src); - void movsd(XMMRegister dst, XMMRegister src); - void movsd(Address dst, XMMRegister src); - void movsd(XMMRegister dst, Address src); - void movlpd(XMMRegister dst, Address src); - // New cpus require use of movaps and movapd to avoid partial register stall - // when moving between registers. - void movapd(XMMRegister dst, XMMRegister src); - void movaps(XMMRegister dst, XMMRegister src); - public: - - void movdl(XMMRegister dst, Register src); - void movdl(Register dst, XMMRegister src); - void movdq(XMMRegister dst, Register src); - void movdq(Register dst, XMMRegister src); - - void cmovl(Condition cc, Register dst, Register src); - void cmovl(Condition cc, Register dst, Address src); - void cmovq(Condition cc, Register dst, Register src); - void cmovq(Condition cc, Register dst, Address src); - - // Prefetches - private: - void prefetch_prefix(Address src); - public: - void prefetcht0(Address src); - void prefetcht1(Address src); - void prefetcht2(Address src); - void prefetchnta(Address src); - void prefetchw(Address src); - - // Arithmetics - void adcl(Register dst, int imm32); - void adcl(Register dst, Address src); - void adcl(Register dst, Register src); - void adcq(Register dst, int imm32); - void adcq(Register dst, Address src); - void adcq(Register dst, Register src); - - void addl(Address dst, int imm32); - void addl(Address dst, Register src); - void addl(Register dst, int imm32); - void addl(Register dst, Address src); - void addl(Register dst, Register src); - void addq(Address dst, int imm32); - void addq(Address dst, Register src); - void addq(Register dst, int imm32); - void addq(Register dst, Address src); - void addq(Register dst, Register src); - - void andl(Register dst, int imm32); - void andl(Register dst, Address src); - void andl(Register dst, Register src); - void andq(Register dst, int imm32); - void andq(Register dst, Address src); - void andq(Register dst, Register src); - - void cmpb(Address dst, int imm8); - void cmpl(Address dst, int imm32); - void cmpl(Register dst, int imm32); - void cmpl(Register dst, Register src); - void cmpl(Register dst, Address src); - void cmpq(Address dst, int imm32); - void cmpq(Address dst, Register src); - void cmpq(Register dst, int imm32); - void cmpq(Register dst, Register src); - void cmpq(Register dst, Address src); - - void ucomiss(XMMRegister dst, XMMRegister src); - void ucomisd(XMMRegister dst, XMMRegister src); - - protected: - // Don't use next inc() and dec() methods directly. INC & DEC instructions - // could cause a partial flag stall since they don't set CF flag. - // Use MacroAssembler::decrement() & MacroAssembler::increment() methods - // which call inc() & dec() or add() & sub() in accordance with - // the product flag UseIncDec value. - - void decl(Register dst); - void decl(Address dst); - void decq(Register dst); - void decq(Address dst); - - void incl(Register dst); - void incl(Address dst); - void incq(Register dst); - void incq(Address dst); - - public: - void idivl(Register src); - void idivq(Register src); - void cdql(); - void cdqq(); - - void imull(Register dst, Register src); - void imull(Register dst, Register src, int value); - void imulq(Register dst, Register src); - void imulq(Register dst, Register src, int value); - - void leal(Register dst, Address src); - void leaq(Register dst, Address src); - - void mull(Address src); - void mull(Register src); - - void negl(Register dst); - void negq(Register dst); - - void notl(Register dst); - void notq(Register dst); - - void orl(Address dst, int imm32); - void orl(Register dst, int imm32); - void orl(Register dst, Address src); - void orl(Register dst, Register src); - void orq(Address dst, int imm32); - void orq(Register dst, int imm32); - void orq(Register dst, Address src); - void orq(Register dst, Register src); - - void rcll(Register dst, int imm8); - void rclq(Register dst, int imm8); - - void sarl(Register dst, int imm8); - void sarl(Register dst); - void sarq(Register dst, int imm8); - void sarq(Register dst); - - void sbbl(Address dst, int imm32); - void sbbl(Register dst, int imm32); - void sbbl(Register dst, Address src); - void sbbl(Register dst, Register src); - void sbbq(Address dst, int imm32); - void sbbq(Register dst, int imm32); - void sbbq(Register dst, Address src); - void sbbq(Register dst, Register src); - - void shll(Register dst, int imm8); - void shll(Register dst); - void shlq(Register dst, int imm8); - void shlq(Register dst); - - void shrl(Register dst, int imm8); - void shrl(Register dst); - void shrq(Register dst, int imm8); - void shrq(Register dst); - - void subl(Address dst, int imm32); - void subl(Address dst, Register src); - void subl(Register dst, int imm32); - void subl(Register dst, Address src); - void subl(Register dst, Register src); - void subq(Address dst, int imm32); - void subq(Address dst, Register src); - void subq(Register dst, int imm32); - void subq(Register dst, Address src); - void subq(Register dst, Register src); - - void testb(Register dst, int imm8); - void testl(Register dst, int imm32); - void testl(Register dst, Register src); - void testq(Register dst, int imm32); - void testq(Register dst, Register src); - - void xaddl(Address dst, Register src); - void xaddq(Address dst, Register src); - - void xorl(Register dst, int imm32); - void xorl(Register dst, Address src); - void xorl(Register dst, Register src); - void xorq(Register dst, int imm32); - void xorq(Register dst, Address src); - void xorq(Register dst, Register src); - - // Miscellaneous - void bswapl(Register reg); - void bswapq(Register reg); - void lock(); - - void xchgl(Register reg, Address adr); - void xchgl(Register dst, Register src); - void xchgq(Register reg, Address adr); - void xchgq(Register dst, Register src); - - void cmpxchgl(Register reg, Address adr); - void cmpxchgq(Register reg, Address adr); - - void nop(int i = 1); - void addr_nop_4(); - void addr_nop_5(); - void addr_nop_7(); - void addr_nop_8(); - - void hlt(); - void ret(int imm16); - void smovl(); - void rep_movl(); - void rep_movq(); - void rep_set(); - void repne_scanl(); - void repne_scanq(); - void setb(Condition cc, Register dst); - - void clflush(Address adr); - - enum Membar_mask_bits { - StoreStore = 1 << 3, - LoadStore = 1 << 2, - StoreLoad = 1 << 1, - LoadLoad = 1 << 0 - }; - - // Serializes memory. - void membar(Membar_mask_bits order_constraint) { - // We only have to handle StoreLoad and LoadLoad - if (order_constraint & StoreLoad) { - // MFENCE subsumes LFENCE - mfence(); - } /* [jk] not needed currently: else if (order_constraint & LoadLoad) { - lfence(); - } */ - } - - void lfence() { - emit_byte(0x0F); - emit_byte(0xAE); - emit_byte(0xE8); - } - - void mfence() { - emit_byte(0x0F); - emit_byte(0xAE); - emit_byte(0xF0); - } - - // Identify processor type and features - void cpuid() { - emit_byte(0x0F); - emit_byte(0xA2); - } - - void cld() { emit_byte(0xfc); - } - - void std() { emit_byte(0xfd); - } - - - // Calls - - void call(Label& L, relocInfo::relocType rtype); - void call(Register reg); - void call(Address adr); - - // Jumps - - void jmp(Register reg); - void jmp(Address adr); - - // Label operations & relative jumps (PPUM Appendix D) - // unconditional jump to L - void jmp(Label& L, relocInfo::relocType rtype = relocInfo::none); - - - // Unconditional 8-bit offset jump to L. - // WARNING: be very careful using this for forward jumps. If the label is - // not bound within an 8-bit offset of this instruction, a run-time error - // will occur. - void jmpb(Label& L); - - // jcc is the generic conditional branch generator to run- time - // routines, jcc is used for branches to labels. jcc takes a branch - // opcode (cc) and a label (L) and generates either a backward - // branch or a forward branch and links it to the label fixup - // chain. Usage: - // - // Label L; // unbound label - // jcc(cc, L); // forward branch to unbound label - // bind(L); // bind label to the current pc - // jcc(cc, L); // backward branch to bound label - // bind(L); // illegal: a label may be bound only once - // - // Note: The same Label can be used for forward and backward branches - // but it may be bound only once. - - void jcc(Condition cc, Label& L, - relocInfo::relocType rtype = relocInfo::none); - - // Conditional jump to a 8-bit offset to L. - // WARNING: be very careful using this for forward jumps. If the label is - // not bound within an 8-bit offset of this instruction, a run-time error - // will occur. - void jccb(Condition cc, Label& L); - - // Floating-point operations - - void fxsave(Address dst); - void fxrstor(Address src); - void ldmxcsr(Address src); - void stmxcsr(Address dst); - - void addss(XMMRegister dst, XMMRegister src); - void addss(XMMRegister dst, Address src); - void subss(XMMRegister dst, XMMRegister src); - void subss(XMMRegister dst, Address src); - void mulss(XMMRegister dst, XMMRegister src); - void mulss(XMMRegister dst, Address src); - void divss(XMMRegister dst, XMMRegister src); - void divss(XMMRegister dst, Address src); - void addsd(XMMRegister dst, XMMRegister src); - void addsd(XMMRegister dst, Address src); - void subsd(XMMRegister dst, XMMRegister src); - void subsd(XMMRegister dst, Address src); - void mulsd(XMMRegister dst, XMMRegister src); - void mulsd(XMMRegister dst, Address src); - void divsd(XMMRegister dst, XMMRegister src); - void divsd(XMMRegister dst, Address src); - - // We only need the double form - void sqrtsd(XMMRegister dst, XMMRegister src); - void sqrtsd(XMMRegister dst, Address src); - - void xorps(XMMRegister dst, XMMRegister src); - void xorps(XMMRegister dst, Address src); - void xorpd(XMMRegister dst, XMMRegister src); - void xorpd(XMMRegister dst, Address src); - - void cvtsi2ssl(XMMRegister dst, Register src); - void cvtsi2ssq(XMMRegister dst, Register src); - void cvtsi2sdl(XMMRegister dst, Register src); - void cvtsi2sdq(XMMRegister dst, Register src); - void cvttss2sil(Register dst, XMMRegister src); // truncates - void cvttss2siq(Register dst, XMMRegister src); // truncates - void cvttsd2sil(Register dst, XMMRegister src); // truncates - void cvttsd2siq(Register dst, XMMRegister src); // truncates - void cvtss2sd(XMMRegister dst, XMMRegister src); - void cvtsd2ss(XMMRegister dst, XMMRegister src); - void cvtdq2pd(XMMRegister dst, XMMRegister src); - void cvtdq2ps(XMMRegister dst, XMMRegister src); - - void pxor(XMMRegister dst, Address src); // Xor Packed Byte Integer Values - void pxor(XMMRegister dst, XMMRegister src); // Xor Packed Byte Integer Values - - void movdqa(XMMRegister dst, Address src); // Move Aligned Double Quadword - void movdqa(XMMRegister dst, XMMRegister src); - void movdqa(Address dst, XMMRegister src); - - void movq(XMMRegister dst, Address src); - void movq(Address dst, XMMRegister src); - - void pshufd(XMMRegister dst, XMMRegister src, int mode); // Shuffle Packed Doublewords - void pshufd(XMMRegister dst, Address src, int mode); - void pshuflw(XMMRegister dst, XMMRegister src, int mode); // Shuffle Packed Low Words - void pshuflw(XMMRegister dst, Address src, int mode); - - void psrlq(XMMRegister dst, int shift); // Shift Right Logical Quadword Immediate - - void punpcklbw(XMMRegister dst, XMMRegister src); // Interleave Low Bytes - void punpcklbw(XMMRegister dst, Address src); -}; - - -// MacroAssembler extends Assembler by frequently used macros. -// -// Instructions for which a 'better' code sequence exists depending -// on arguments should also go in here. - -class MacroAssembler : public Assembler { - friend class LIR_Assembler; - protected: - - Address as_Address(AddressLiteral adr); - Address as_Address(ArrayAddress adr); - - // Support for VM calls - // - // This is the base routine called by the different versions of - // call_VM_leaf. The interpreter may customize this version by - // overriding it for its purposes (e.g., to save/restore additional - // registers when doing a VM call). - - virtual void call_VM_leaf_base( - address entry_point, // the entry point - int number_of_arguments // the number of arguments to - // pop after the call - ); - - // This is the base routine called by the different versions of - // call_VM. The interpreter may customize this version by overriding - // it for its purposes (e.g., to save/restore additional registers - // when doing a VM call). - // - // If no java_thread register is specified (noreg) than rdi will be - // used instead. call_VM_base returns the register which contains - // the thread upon return. If a thread register has been specified, - // the return value will correspond to that register. If no - // last_java_sp is specified (noreg) than rsp will be used instead. - virtual void call_VM_base( // returns the register - // containing the thread upon - // return - Register oop_result, // where an oop-result ends up - // if any; use noreg otherwise - Register java_thread, // the thread if computed - // before ; use noreg otherwise - Register last_java_sp, // to set up last_Java_frame in - // stubs; use noreg otherwise - address entry_point, // the entry point - int number_of_arguments, // the number of arguments (w/o - // thread) to pop after the - // call - bool check_exceptions // whether to check for pending - // exceptions after return - ); - - // This routines should emit JVMTI PopFrame handling and ForceEarlyReturn code. - // The implementation is only non-empty for the InterpreterMacroAssembler, - // as only the interpreter handles PopFrame and ForceEarlyReturn requests. - virtual void check_and_handle_popframe(Register java_thread); - virtual void check_and_handle_earlyret(Register java_thread); - - void call_VM_helper(Register oop_result, - address entry_point, - int number_of_arguments, - bool check_exceptions = true); - - public: - MacroAssembler(CodeBuffer* code) : Assembler(code) {} - - // Support for NULL-checks - // - // Generates code that causes a NULL OS exception if the content of - // reg is NULL. If the accessed location is M[reg + offset] and the - // offset is known, provide the offset. No explicit code generation - // is needed if the offset is within a certain range (0 <= offset <= - // page_size). - void null_check(Register reg, int offset = -1); - static bool needs_explicit_null_check(intptr_t offset); - - // Required platform-specific helpers for Label::patch_instructions. - // They _shadow_ the declarations in AbstractAssembler, which are undefined. - void pd_patch_instruction(address branch, address target); -#ifndef PRODUCT - static void pd_print_patched_instruction(address branch); -#endif - - - // The following 4 methods return the offset of the appropriate move - // instruction. Note: these are 32 bit instructions - - // Support for fast byte/word loading with zero extension (depending - // on particular CPU) - int load_unsigned_byte(Register dst, Address src); - int load_unsigned_word(Register dst, Address src); - - // Support for fast byte/word loading with sign extension (depending - // on particular CPU) - int load_signed_byte(Register dst, Address src); - int load_signed_word(Register dst, Address src); - - // Support for inc/dec with optimal instruction selection depending - // on value - void incrementl(Register reg, int value = 1); - void decrementl(Register reg, int value = 1); - void incrementq(Register reg, int value = 1); - void decrementq(Register reg, int value = 1); - - void incrementl(Address dst, int value = 1); - void decrementl(Address dst, int value = 1); - void incrementq(Address dst, int value = 1); - void decrementq(Address dst, int value = 1); - - // Support optimal SSE move instructions. - void movflt(XMMRegister dst, XMMRegister src) { - if (UseXmmRegToRegMoveAll) { movaps(dst, src); return; } - else { movss (dst, src); return; } - } - - void movflt(XMMRegister dst, Address src) { movss(dst, src); } - - void movflt(XMMRegister dst, AddressLiteral src); - - void movflt(Address dst, XMMRegister src) { movss(dst, src); } - - void movdbl(XMMRegister dst, XMMRegister src) { - if (UseXmmRegToRegMoveAll) { movapd(dst, src); return; } - else { movsd (dst, src); return; } - } - - void movdbl(XMMRegister dst, AddressLiteral src); - - void movdbl(XMMRegister dst, Address src) { - if (UseXmmLoadAndClearUpper) { movsd (dst, src); return; } - else { movlpd(dst, src); return; } - } - - void movdbl(Address dst, XMMRegister src) { movsd(dst, src); } - - void incrementl(AddressLiteral dst); - void incrementl(ArrayAddress dst); - - // Alignment - void align(int modulus); - - // Misc - void fat_nop(); // 5 byte nop - - - // C++ bool manipulation - - void movbool(Register dst, Address src); - void movbool(Address dst, bool boolconst); - void movbool(Address dst, Register src); - void testbool(Register dst); - - // oop manipulations - void load_klass(Register dst, Register src); - void store_klass(Register dst, Register src); - void store_klass_gap(Register dst, Register src); - - void load_prototype_header(Register dst, Register src); - - void load_heap_oop(Register dst, Address src); - void store_heap_oop(Address dst, Register src); - void encode_heap_oop(Register r); - void decode_heap_oop(Register r); - void encode_heap_oop_not_null(Register r); - void decode_heap_oop_not_null(Register r); - void encode_heap_oop_not_null(Register dst, Register src); - void decode_heap_oop_not_null(Register dst, Register src); - - void set_narrow_oop(Register dst, jobject obj); - - // Stack frame creation/removal - void enter(); - void leave(); - - // Support for getting the JavaThread pointer (i.e.; a reference to - // thread-local information) The pointer will be loaded into the - // thread register. - void get_thread(Register thread); - - void int3(); - - // Support for VM calls - // - // It is imperative that all calls into the VM are handled via the - // call_VM macros. They make sure that the stack linkage is setup - // correctly. call_VM's correspond to ENTRY/ENTRY_X entry points - // while call_VM_leaf's correspond to LEAF entry points. - void call_VM(Register oop_result, - address entry_point, - bool check_exceptions = true); - void call_VM(Register oop_result, - address entry_point, - Register arg_1, - bool check_exceptions = true); - void call_VM(Register oop_result, - address entry_point, - Register arg_1, Register arg_2, - bool check_exceptions = true); - void call_VM(Register oop_result, - address entry_point, - Register arg_1, Register arg_2, Register arg_3, - bool check_exceptions = true); - - // Overloadings with last_Java_sp - void call_VM(Register oop_result, - Register last_java_sp, - address entry_point, - int number_of_arguments = 0, - bool check_exceptions = true); - void call_VM(Register oop_result, - Register last_java_sp, - address entry_point, - Register arg_1, bool - check_exceptions = true); - void call_VM(Register oop_result, - Register last_java_sp, - address entry_point, - Register arg_1, Register arg_2, - bool check_exceptions = true); - void call_VM(Register oop_result, - Register last_java_sp, - address entry_point, - Register arg_1, Register arg_2, Register arg_3, - bool check_exceptions = true); - - void call_VM_leaf(address entry_point, - int number_of_arguments = 0); - void call_VM_leaf(address entry_point, - Register arg_1); - void call_VM_leaf(address entry_point, - Register arg_1, Register arg_2); - void call_VM_leaf(address entry_point, - Register arg_1, Register arg_2, Register arg_3); - - // last Java Frame (fills frame anchor) - void set_last_Java_frame(Register last_java_sp, - Register last_java_fp, - address last_java_pc); - void reset_last_Java_frame(bool clear_fp, bool clear_pc); - - // Stores - void store_check(Register obj); // store check for - // obj - register is - // destroyed - // afterwards - void store_check(Register obj, Address dst); // same as above, dst - // is exact store - // location (reg. is - // destroyed) - - // split store_check(Register obj) to enhance instruction interleaving - void store_check_part_1(Register obj); - void store_check_part_2(Register obj); - - // C 'boolean' to Java boolean: x == 0 ? 0 : 1 - void c2bool(Register x); - - // Int division/reminder for Java - // (as idivl, but checks for special case as described in JVM spec.) - // returns idivl instruction offset for implicit exception handling - int corrected_idivl(Register reg); - // Long division/reminder for Java - // (as idivq, but checks for special case as described in JVM spec.) - // returns idivq instruction offset for implicit exception handling - int corrected_idivq(Register reg); - - // Push and pop integer/fpu/cpu state - void push_IU_state(); - void pop_IU_state(); - - void push_FPU_state(); - void pop_FPU_state(); - - void push_CPU_state(); - void pop_CPU_state(); - - // Sign extension - void sign_extend_short(Register reg); - void sign_extend_byte(Register reg); - - // Division by power of 2, rounding towards 0 - void division_with_shift(Register reg, int shift_value); - - // Round up to a power of two - void round_to_l(Register reg, int modulus); - void round_to_q(Register reg, int modulus); - - // allocation - void eden_allocate( - Register obj, // result: pointer to object after - // successful allocation - Register var_size_in_bytes, // object size in bytes if unknown at - // compile time; invalid otherwise - int con_size_in_bytes, // object size in bytes if known at - // compile time - Register t1, // temp register - Label& slow_case // continuation point if fast - // allocation fails - ); - void tlab_allocate( - Register obj, // result: pointer to object after - // successful allocation - Register var_size_in_bytes, // object size in bytes if unknown at - // compile time; invalid otherwise - int con_size_in_bytes, // object size in bytes if known at - // compile time - Register t1, // temp register - Register t2, // temp register - Label& slow_case // continuation point if fast - // allocation fails - ); - void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case); - - //---- - - // Debugging - - // only if +VerifyOops - void verify_oop(Register reg, const char* s = "broken oop"); - void verify_oop_addr(Address addr, const char * s = "broken oop addr"); - - // if heap base register is used - reinit it with the correct value - void reinit_heapbase(); - - // only if +VerifyFPU - void verify_FPU(int stack_depth, const char* s = "illegal FPU state") {} - - // prints msg, dumps registers and stops execution - void stop(const char* msg); - - // prints message and continues - void warn(const char* msg); - - static void debug(char* msg, int64_t pc, int64_t regs[]); - - void os_breakpoint(); - - void untested() - { - stop("untested"); - } - - void unimplemented(const char* what = "") - { - char* b = new char[1024]; - sprintf(b, "unimplemented: %s", what); - stop(b); - } - - void should_not_reach_here() - { - stop("should not reach here"); - } - - // Stack overflow checking - void bang_stack_with_offset(int offset) - { - // stack grows down, caller passes positive offset - assert(offset > 0, "must bang with negative offset"); - movl(Address(rsp, (-offset)), rax); - } - - // Writes to stack successive pages until offset reached to check for - // stack overflow + shadow pages. Also, clobbers tmp - void bang_stack_size(Register offset, Register tmp); - - // Support for serializing memory accesses between threads. - void serialize_memory(Register thread, Register tmp); - - void verify_tlab(); - - // Biased locking support - // lock_reg and obj_reg must be loaded up with the appropriate values. - // swap_reg must be rax and is killed. - // tmp_reg must be supplied and is killed. - // If swap_reg_contains_mark is true then the code assumes that the - // mark word of the object has already been loaded into swap_reg. - // Optional slow case is for implementations (interpreter and C1) which branch to - // slow case directly. Leaves condition codes set for C2's Fast_Lock node. - // Returns offset of first potentially-faulting instruction for null - // check info (currently consumed only by C1). If - // swap_reg_contains_mark is true then returns -1 as it is assumed - // the calling code has already passed any potential faults. - int biased_locking_enter(Register lock_reg, Register obj_reg, Register swap_reg, Register tmp_reg, - bool swap_reg_contains_mark, - Label& done, Label* slow_case = NULL, - BiasedLockingCounters* counters = NULL); - void biased_locking_exit (Register obj_reg, Register temp_reg, Label& done); - - Condition negate_condition(Condition cond); - - // Instructions that use AddressLiteral operands. These instruction can handle 32bit/64bit - // operands. In general the names are modified to avoid hiding the instruction in Assembler - // so that we don't need to implement all the varieties in the Assembler with trivial wrappers - // here in MacroAssembler. The major exception to this rule is call - - // Arithmetics - - void cmp8(AddressLiteral src1, int8_t imm32); - - void cmp32(AddressLiteral src1, int32_t src2); - // compare reg - mem, or reg - &mem - void cmp32(Register src1, AddressLiteral src2); - - void cmp32(Register src1, Address src2); - -#ifndef _LP64 - void cmpoop(Address dst, jobject obj); - void cmpoop(Register dst, jobject obj); -#endif // _LP64 - - // NOTE src2 must be the lval. This is NOT an mem-mem compare - void cmpptr(Address src1, AddressLiteral src2); - - void cmpptr(Register src1, AddressLiteral src); - - // will be cmpreg(?) - void cmp64(Register src1, AddressLiteral src); - - void cmpxchgptr(Register reg, Address adr); - void cmpxchgptr(Register reg, AddressLiteral adr); - - // Helper functions for statistics gathering. - // Conditionally (atomically, on MPs) increments passed counter address, preserving condition codes. - void cond_inc32(Condition cond, AddressLiteral counter_addr); - // Unconditional atomic increment. - void atomic_incl(AddressLiteral counter_addr); - - - void lea(Register dst, AddressLiteral src); - void lea(Register dst, Address src); - - - // Calls - void call(Label& L, relocInfo::relocType rtype); - void call(Register entry); - void call(AddressLiteral entry); - - // Jumps - - // 32bit can do a case table jump in one instruction but we no longer allow the base - // to be installed in the Address class - void jump(ArrayAddress entry); - - void jump(AddressLiteral entry); - void jump_cc(Condition cc, AddressLiteral dst); - - // Floating - - void ldmxcsr(Address src) { Assembler::ldmxcsr(src); } - void ldmxcsr(AddressLiteral src); - -private: - // these are private because users should be doing movflt/movdbl - - void movss(XMMRegister dst, XMMRegister src) { Assembler::movss(dst, src); } - void movss(Address dst, XMMRegister src) { Assembler::movss(dst, src); } - void movss(XMMRegister dst, Address src) { Assembler::movss(dst, src); } - void movss(XMMRegister dst, AddressLiteral src); - - void movlpd(XMMRegister dst, Address src) {Assembler::movlpd(dst, src); } - void movlpd(XMMRegister dst, AddressLiteral src); - -public: - - - void xorpd(XMMRegister dst, XMMRegister src) {Assembler::xorpd(dst, src); } - void xorpd(XMMRegister dst, Address src) {Assembler::xorpd(dst, src); } - void xorpd(XMMRegister dst, AddressLiteral src); - - void xorps(XMMRegister dst, XMMRegister src) {Assembler::xorps(dst, src); } - void xorps(XMMRegister dst, Address src) {Assembler::xorps(dst, src); } - void xorps(XMMRegister dst, AddressLiteral src); - - - // Data - - void movoop(Register dst, jobject obj); - void movoop(Address dst, jobject obj); - - void movptr(ArrayAddress dst, Register src); - void movptr(Register dst, AddressLiteral src); - - void movptr(Register dst, intptr_t src); - void movptr(Address dst, intptr_t src); - - void movptr(Register dst, ArrayAddress src); - - // to avoid hiding movl - void mov32(AddressLiteral dst, Register src); - void mov32(Register dst, AddressLiteral src); - - void pushoop(jobject obj); - - // Can push value or effective address - void pushptr(AddressLiteral src); - -}; - -/** - * class SkipIfEqual: - * - * Instantiating this class will result in assembly code being output that will - * jump around any code emitted between the creation of the instance and it's - * automatic destruction at the end of a scope block, depending on the value of - * the flag passed to the constructor, which will be checked at run-time. - */ -class SkipIfEqual { - private: - MacroAssembler* _masm; - Label _label; - - public: - SkipIfEqual(MacroAssembler*, const bool* flag_addr, bool value); - ~SkipIfEqual(); -}; - - -#ifdef ASSERT -inline bool AbstractAssembler::pd_check_instruction_mark() { return true; } -#endif diff --git a/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp b/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp index 09419c95650..283a63d8541 100644 --- a/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp @@ -43,11 +43,12 @@ void ConversionStub::emit_code(LIR_Assembler* ce) { __ comisd(input()->as_xmm_double_reg(), ExternalAddress((address)&double_zero)); } else { - __ pushl(rax); + LP64_ONLY(ShouldNotReachHere()); + __ push(rax); __ ftst(); __ fnstsw_ax(); __ sahf(); - __ popl(rax); + __ pop(rax); } Label NaN, do_return; @@ -61,7 +62,7 @@ void ConversionStub::emit_code(LIR_Assembler* ce) { // input is NaN -> return 0 __ bind(NaN); - __ xorl(result()->as_register(), result()->as_register()); + __ xorptr(result()->as_register(), result()->as_register()); __ bind(do_return); __ jmp(_continuation); @@ -139,7 +140,7 @@ NewInstanceStub::NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKl void NewInstanceStub::emit_code(LIR_Assembler* ce) { assert(__ rsp_offset() == 0, "frame size should be fixed"); __ bind(_entry); - __ movl(rdx, _klass_reg->as_register()); + __ movptr(rdx, _klass_reg->as_register()); __ call(RuntimeAddress(Runtime1::entry_for(_stub_id))); ce->add_call_info_here(_info); ce->verify_oop_map(_info); @@ -306,10 +307,10 @@ void PatchingStub::emit_code(LIR_Assembler* ce) { assert(_obj != noreg, "must be a valid register"); Register tmp = rax; if (_obj == tmp) tmp = rbx; - __ pushl(tmp); + __ push(tmp); __ get_thread(tmp); - __ cmpl(tmp, Address(_obj, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc))); - __ popl(tmp); + __ cmpptr(tmp, Address(_obj, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc))); + __ pop(tmp); __ jcc(Assembler::notEqual, call_patch); // access_field patches may execute the patched code before it's @@ -434,7 +435,7 @@ void ArrayCopyStub::emit_code(LIR_Assembler* ce) { VMReg r_1 = args[i].first(); if (r_1->is_stack()) { int st_off = r_1->reg2stack() * wordSize; - __ movl (Address(rsp, st_off), r[i]); + __ movptr (Address(rsp, st_off), r[i]); } else { assert(r[i] == args[i].first()->as_Register(), "Wrong register for arg "); } @@ -449,7 +450,7 @@ void ArrayCopyStub::emit_code(LIR_Assembler* ce) { ce->add_call_info_here(info()); #ifndef PRODUCT - __ increment(ExternalAddress((address)&Runtime1::_arraycopy_slowcase_cnt)); + __ incrementl(ExternalAddress((address)&Runtime1::_arraycopy_slowcase_cnt)); #endif __ jmp(_continuation); diff --git a/hotspot/src/cpu/x86/vm/c1_Defs_x86.hpp b/hotspot/src/cpu/x86/vm/c1_Defs_x86.hpp index 8594a834907..e8d3e8b6714 100644 --- a/hotspot/src/cpu/x86/vm/c1_Defs_x86.hpp +++ b/hotspot/src/cpu/x86/vm/c1_Defs_x86.hpp @@ -36,27 +36,34 @@ enum { // registers enum { - pd_nof_cpu_regs_frame_map = 8, // number of registers used during code emission - pd_nof_fpu_regs_frame_map = 8, // number of registers used during code emission - pd_nof_xmm_regs_frame_map = 8, // number of registers used during code emission - pd_nof_caller_save_cpu_regs_frame_map = 6, // number of registers killed by calls - pd_nof_caller_save_fpu_regs_frame_map = 8, // number of registers killed by calls - pd_nof_caller_save_xmm_regs_frame_map = 8, // number of registers killed by calls + pd_nof_cpu_regs_frame_map = RegisterImpl::number_of_registers, // number of registers used during code emission + pd_nof_fpu_regs_frame_map = FloatRegisterImpl::number_of_registers, // number of registers used during code emission + pd_nof_xmm_regs_frame_map = XMMRegisterImpl::number_of_registers, // number of registers used during code emission - pd_nof_cpu_regs_reg_alloc = 6, // number of registers that are visible to register allocator +#ifdef _LP64 + #define UNALLOCATED 4 // rsp, rbp, r15, r10 +#else + #define UNALLOCATED 2 // rsp, rbp +#endif // LP64 + + pd_nof_caller_save_cpu_regs_frame_map = pd_nof_cpu_regs_frame_map - UNALLOCATED, // number of registers killed by calls + pd_nof_caller_save_fpu_regs_frame_map = pd_nof_fpu_regs_frame_map, // number of registers killed by calls + pd_nof_caller_save_xmm_regs_frame_map = pd_nof_xmm_regs_frame_map, // number of registers killed by calls + + pd_nof_cpu_regs_reg_alloc = pd_nof_caller_save_cpu_regs_frame_map, // number of registers that are visible to register allocator pd_nof_fpu_regs_reg_alloc = 6, // number of registers that are visible to register allocator - pd_nof_cpu_regs_linearscan = 8, // number of registers visible to linear scan - pd_nof_fpu_regs_linearscan = 8, // number of registers visible to linear scan - pd_nof_xmm_regs_linearscan = 8, // number of registers visible to linear scan + pd_nof_cpu_regs_linearscan = pd_nof_cpu_regs_frame_map, // number of registers visible to linear scan + pd_nof_fpu_regs_linearscan = pd_nof_fpu_regs_frame_map, // number of registers visible to linear scan + pd_nof_xmm_regs_linearscan = pd_nof_xmm_regs_frame_map, // number of registers visible to linear scan pd_first_cpu_reg = 0, - pd_last_cpu_reg = 5, + pd_last_cpu_reg = NOT_LP64(5) LP64_ONLY(11), pd_first_byte_reg = 2, pd_last_byte_reg = 5, pd_first_fpu_reg = pd_nof_cpu_regs_frame_map, pd_last_fpu_reg = pd_first_fpu_reg + 7, pd_first_xmm_reg = pd_nof_cpu_regs_frame_map + pd_nof_fpu_regs_frame_map, - pd_last_xmm_reg = pd_first_xmm_reg + 7 + pd_last_xmm_reg = pd_first_xmm_reg + pd_nof_xmm_regs_frame_map - 1 }; diff --git a/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.cpp b/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.cpp index 2118ec4483e..a48a8576fc9 100644 --- a/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.cpp @@ -39,10 +39,15 @@ LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool) { opr = LIR_OprFact::address(new LIR_Address(rsp_opr, st_off, type)); } else if (r_1->is_Register()) { Register reg = r_1->as_Register(); - if (r_2->is_Register()) { + if (r_2->is_Register() && (type == T_LONG || type == T_DOUBLE)) { Register reg2 = r_2->as_Register(); +#ifdef _LP64 + assert(reg2 == reg, "must be same register"); + opr = as_long_opr(reg); +#else opr = as_long_opr(reg2, reg); - } else if (type == T_OBJECT) { +#endif // _LP64 + } else if (type == T_OBJECT || type == T_ARRAY) { opr = as_oop_opr(reg); } else { opr = as_opr(reg); @@ -88,18 +93,39 @@ LIR_Opr FrameMap::rax_oop_opr; LIR_Opr FrameMap::rdx_oop_opr; LIR_Opr FrameMap::rcx_oop_opr; -LIR_Opr FrameMap::rax_rdx_long_opr; -LIR_Opr FrameMap::rbx_rcx_long_opr; +LIR_Opr FrameMap::long0_opr; +LIR_Opr FrameMap::long1_opr; LIR_Opr FrameMap::fpu0_float_opr; LIR_Opr FrameMap::fpu0_double_opr; LIR_Opr FrameMap::xmm0_float_opr; LIR_Opr FrameMap::xmm0_double_opr; +#ifdef _LP64 + +LIR_Opr FrameMap::r8_opr; +LIR_Opr FrameMap::r9_opr; +LIR_Opr FrameMap::r10_opr; +LIR_Opr FrameMap::r11_opr; +LIR_Opr FrameMap::r12_opr; +LIR_Opr FrameMap::r13_opr; +LIR_Opr FrameMap::r14_opr; +LIR_Opr FrameMap::r15_opr; + +// r10 and r15 can never contain oops since they aren't available to +// the allocator +LIR_Opr FrameMap::r8_oop_opr; +LIR_Opr FrameMap::r9_oop_opr; +LIR_Opr FrameMap::r11_oop_opr; +LIR_Opr FrameMap::r12_oop_opr; +LIR_Opr FrameMap::r13_oop_opr; +LIR_Opr FrameMap::r14_oop_opr; +#endif // _LP64 + LIR_Opr FrameMap::_caller_save_cpu_regs[] = { 0, }; LIR_Opr FrameMap::_caller_save_fpu_regs[] = { 0, }; LIR_Opr FrameMap::_caller_save_xmm_regs[] = { 0, }; -XMMRegister FrameMap::_xmm_regs [8] = { 0, }; +XMMRegister FrameMap::_xmm_regs [] = { 0, }; XMMRegister FrameMap::nr2xmmreg(int rnr) { assert(_init_done, "tables not initialized"); @@ -113,18 +139,39 @@ XMMRegister FrameMap::nr2xmmreg(int rnr) { void FrameMap::init() { if (_init_done) return; - assert(nof_cpu_regs == 8, "wrong number of CPU registers"); - map_register(0, rsi); rsi_opr = LIR_OprFact::single_cpu(0); rsi_oop_opr = LIR_OprFact::single_cpu_oop(0); - map_register(1, rdi); rdi_opr = LIR_OprFact::single_cpu(1); rdi_oop_opr = LIR_OprFact::single_cpu_oop(1); - map_register(2, rbx); rbx_opr = LIR_OprFact::single_cpu(2); rbx_oop_opr = LIR_OprFact::single_cpu_oop(2); - map_register(3, rax); rax_opr = LIR_OprFact::single_cpu(3); rax_oop_opr = LIR_OprFact::single_cpu_oop(3); - map_register(4, rdx); rdx_opr = LIR_OprFact::single_cpu(4); rdx_oop_opr = LIR_OprFact::single_cpu_oop(4); - map_register(5, rcx); rcx_opr = LIR_OprFact::single_cpu(5); rcx_oop_opr = LIR_OprFact::single_cpu_oop(5); - map_register(6, rsp); rsp_opr = LIR_OprFact::single_cpu(6); - map_register(7, rbp); rbp_opr = LIR_OprFact::single_cpu(7); + assert(nof_cpu_regs == LP64_ONLY(16) NOT_LP64(8), "wrong number of CPU registers"); + map_register(0, rsi); rsi_opr = LIR_OprFact::single_cpu(0); + map_register(1, rdi); rdi_opr = LIR_OprFact::single_cpu(1); + map_register(2, rbx); rbx_opr = LIR_OprFact::single_cpu(2); + map_register(3, rax); rax_opr = LIR_OprFact::single_cpu(3); + map_register(4, rdx); rdx_opr = LIR_OprFact::single_cpu(4); + map_register(5, rcx); rcx_opr = LIR_OprFact::single_cpu(5); - rax_rdx_long_opr = LIR_OprFact::double_cpu(3 /*eax*/, 4 /*edx*/); - rbx_rcx_long_opr = LIR_OprFact::double_cpu(2 /*ebx*/, 5 /*ecx*/); +#ifndef _LP64 + // The unallocatable registers are at the end + map_register(6, rsp); + map_register(7, rbp); +#else + map_register( 6, r8); r8_opr = LIR_OprFact::single_cpu(6); + map_register( 7, r9); r9_opr = LIR_OprFact::single_cpu(7); + map_register( 8, r11); r11_opr = LIR_OprFact::single_cpu(8); + map_register( 9, r12); r12_opr = LIR_OprFact::single_cpu(9); + map_register(10, r13); r13_opr = LIR_OprFact::single_cpu(10); + map_register(11, r14); r14_opr = LIR_OprFact::single_cpu(11); + // The unallocatable registers are at the end + map_register(12, r10); r10_opr = LIR_OprFact::single_cpu(12); + map_register(13, r15); r15_opr = LIR_OprFact::single_cpu(13); + map_register(14, rsp); + map_register(15, rbp); +#endif // _LP64 + +#ifdef _LP64 + long0_opr = LIR_OprFact::double_cpu(3 /*eax*/, 3 /*eax*/); + long1_opr = LIR_OprFact::double_cpu(2 /*ebx*/, 2 /*ebx*/); +#else + long0_opr = LIR_OprFact::double_cpu(3 /*eax*/, 4 /*edx*/); + long1_opr = LIR_OprFact::double_cpu(2 /*ebx*/, 5 /*ecx*/); +#endif // _LP64 fpu0_float_opr = LIR_OprFact::single_fpu(0); fpu0_double_opr = LIR_OprFact::double_fpu(0); xmm0_float_opr = LIR_OprFact::single_xmm(0); @@ -137,6 +184,15 @@ void FrameMap::init() { _caller_save_cpu_regs[4] = rdx_opr; _caller_save_cpu_regs[5] = rcx_opr; +#ifdef _LP64 + _caller_save_cpu_regs[6] = r8_opr; + _caller_save_cpu_regs[7] = r9_opr; + _caller_save_cpu_regs[8] = r11_opr; + _caller_save_cpu_regs[9] = r12_opr; + _caller_save_cpu_regs[10] = r13_opr; + _caller_save_cpu_regs[11] = r14_opr; +#endif // _LP64 + _xmm_regs[0] = xmm0; _xmm_regs[1] = xmm1; @@ -147,18 +203,51 @@ void FrameMap::init() { _xmm_regs[6] = xmm6; _xmm_regs[7] = xmm7; +#ifdef _LP64 + _xmm_regs[8] = xmm8; + _xmm_regs[9] = xmm9; + _xmm_regs[10] = xmm10; + _xmm_regs[11] = xmm11; + _xmm_regs[12] = xmm12; + _xmm_regs[13] = xmm13; + _xmm_regs[14] = xmm14; + _xmm_regs[15] = xmm15; +#endif // _LP64 + for (int i = 0; i < 8; i++) { _caller_save_fpu_regs[i] = LIR_OprFact::single_fpu(i); + } + + for (int i = 0; i < nof_caller_save_xmm_regs ; i++) { _caller_save_xmm_regs[i] = LIR_OprFact::single_xmm(i); } _init_done = true; + rsi_oop_opr = as_oop_opr(rsi); + rdi_oop_opr = as_oop_opr(rdi); + rbx_oop_opr = as_oop_opr(rbx); + rax_oop_opr = as_oop_opr(rax); + rdx_oop_opr = as_oop_opr(rdx); + rcx_oop_opr = as_oop_opr(rcx); + + rsp_opr = as_pointer_opr(rsp); + rbp_opr = as_pointer_opr(rbp); + +#ifdef _LP64 + r8_oop_opr = as_oop_opr(r8); + r9_oop_opr = as_oop_opr(r9); + r11_oop_opr = as_oop_opr(r11); + r12_oop_opr = as_oop_opr(r12); + r13_oop_opr = as_oop_opr(r13); + r14_oop_opr = as_oop_opr(r14); +#endif // _LP64 + VMRegPair regs; BasicType sig_bt = T_OBJECT; SharedRuntime::java_calling_convention(&sig_bt, ®s, 1, true); receiver_opr = as_oop_opr(regs.first()->as_Register()); - assert(receiver_opr == rcx_oop_opr, "rcvr ought to be rcx"); + } diff --git a/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp b/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp index 419b8600a3c..d5d9816b7b2 100644 --- a/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp +++ b/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp @@ -38,8 +38,13 @@ nof_xmm_regs = pd_nof_xmm_regs_frame_map, nof_caller_save_xmm_regs = pd_nof_caller_save_xmm_regs_frame_map, first_available_sp_in_frame = 0, +#ifndef _LP64 frame_pad_in_bytes = 8, nof_reg_args = 2 +#else + frame_pad_in_bytes = 16, + nof_reg_args = 6 +#endif // _LP64 }; private: @@ -65,17 +70,49 @@ static LIR_Opr rax_oop_opr; static LIR_Opr rdx_oop_opr; static LIR_Opr rcx_oop_opr; +#ifdef _LP64 - static LIR_Opr rax_rdx_long_opr; - static LIR_Opr rbx_rcx_long_opr; + static LIR_Opr r8_opr; + static LIR_Opr r9_opr; + static LIR_Opr r10_opr; + static LIR_Opr r11_opr; + static LIR_Opr r12_opr; + static LIR_Opr r13_opr; + static LIR_Opr r14_opr; + static LIR_Opr r15_opr; + + static LIR_Opr r8_oop_opr; + static LIR_Opr r9_oop_opr; + + static LIR_Opr r11_oop_opr; + static LIR_Opr r12_oop_opr; + static LIR_Opr r13_oop_opr; + static LIR_Opr r14_oop_opr; + +#endif // _LP64 + + static LIR_Opr long0_opr; + static LIR_Opr long1_opr; static LIR_Opr fpu0_float_opr; static LIR_Opr fpu0_double_opr; static LIR_Opr xmm0_float_opr; static LIR_Opr xmm0_double_opr; +#ifdef _LP64 + static LIR_Opr as_long_opr(Register r) { + return LIR_OprFact::double_cpu(cpu_reg2rnr(r), cpu_reg2rnr(r)); + } + static LIR_Opr as_pointer_opr(Register r) { + return LIR_OprFact::double_cpu(cpu_reg2rnr(r), cpu_reg2rnr(r)); + } +#else static LIR_Opr as_long_opr(Register r, Register r2) { return LIR_OprFact::double_cpu(cpu_reg2rnr(r), cpu_reg2rnr(r2)); } + static LIR_Opr as_pointer_opr(Register r) { + return LIR_OprFact::single_cpu(cpu_reg2rnr(r)); + } +#endif // _LP64 // VMReg name for spilled physical FPU stack slot n static VMReg fpu_regname (int n); diff --git a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp index 081f38c3bac..c267d0e6ac7 100644 --- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @@ -113,7 +113,7 @@ bool LIR_Assembler::is_small_constant(LIR_Opr opr) { LIR_Opr LIR_Assembler::receiverOpr() { - return FrameMap::rcx_oop_opr; + return FrameMap::receiver_opr; } LIR_Opr LIR_Assembler::incomingReceiverOpr() { @@ -121,7 +121,7 @@ LIR_Opr LIR_Assembler::incomingReceiverOpr() { } LIR_Opr LIR_Assembler::osrBufferPointer() { - return FrameMap::rcx_opr; + return FrameMap::as_pointer_opr(receiverOpr()->as_register()); } //--------------fpu register translations----------------------- @@ -181,7 +181,7 @@ void LIR_Assembler::push(LIR_Opr opr) { if (opr->is_single_cpu()) { __ push_reg(opr->as_register()); } else if (opr->is_double_cpu()) { - __ push_reg(opr->as_register_hi()); + NOT_LP64(__ push_reg(opr->as_register_hi())); __ push_reg(opr->as_register_lo()); } else if (opr->is_stack()) { __ push_addr(frame_map()->address_for_slot(opr->single_stack_ix())); @@ -202,31 +202,45 @@ void LIR_Assembler::push(LIR_Opr opr) { void LIR_Assembler::pop(LIR_Opr opr) { if (opr->is_single_cpu()) { - __ pop(opr->as_register()); + __ pop_reg(opr->as_register()); } else { ShouldNotReachHere(); } } +bool LIR_Assembler::is_literal_address(LIR_Address* addr) { + return addr->base()->is_illegal() && addr->index()->is_illegal(); +} + //------------------------------------------- + Address LIR_Assembler::as_Address(LIR_Address* addr) { + return as_Address(addr, rscratch1); +} + +Address LIR_Assembler::as_Address(LIR_Address* addr, Register tmp) { if (addr->base()->is_illegal()) { assert(addr->index()->is_illegal(), "must be illegal too"); - //return Address(addr->disp(), relocInfo::none); - // hack for now since this should really return an AddressLiteral - // which will have to await 64bit c1 changes. - return Address(noreg, addr->disp()); + AddressLiteral laddr((address)addr->disp(), relocInfo::none); + if (! __ reachable(laddr)) { + __ movptr(tmp, laddr.addr()); + Address res(tmp, 0); + return res; + } else { + return __ as_Address(laddr); + } } - Register base = addr->base()->as_register(); + Register base = addr->base()->as_pointer_register(); if (addr->index()->is_illegal()) { return Address( base, addr->disp()); - } else if (addr->index()->is_single_cpu()) { - Register index = addr->index()->as_register(); + } else if (addr->index()->is_cpu_register()) { + Register index = addr->index()->as_pointer_register(); return Address(base, index, (Address::ScaleFactor) addr->scale(), addr->disp()); } else if (addr->index()->is_constant()) { - int addr_offset = (addr->index()->as_constant_ptr()->as_jint() << addr->scale()) + addr->disp(); + intptr_t addr_offset = (addr->index()->as_constant_ptr()->as_jint() << addr->scale()) + addr->disp(); + assert(Assembler::is_simm32(addr_offset), "must be"); return Address(base, addr_offset); } else { @@ -284,7 +298,7 @@ void LIR_Assembler::osr_entry() { // All other registers are dead at this point and the locals will be // copied into place by code emitted in the IR. - Register OSR_buf = osrBufferPointer()->as_register(); + Register OSR_buf = osrBufferPointer()->as_pointer_register(); { assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below"); int monitor_offset = BytesPerWord * method()->max_locals() + (BasicObjectLock::size() * BytesPerWord) * (number_of_locks - 1); @@ -294,16 +308,16 @@ void LIR_Assembler::osr_entry() { // verify the interpreter's monitor has a non-null object { Label L; - __ cmpl(Address(OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes()), NULL_WORD); + __ cmpptr(Address(OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes()), (int32_t)NULL_WORD); __ jcc(Assembler::notZero, L); __ stop("locked object is NULL"); __ bind(L); } #endif - __ movl(rbx, Address(OSR_buf, slot_offset + BasicObjectLock::lock_offset_in_bytes())); - __ movl(frame_map()->address_for_monitor_lock(i), rbx); - __ movl(rbx, Address(OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes())); - __ movl(frame_map()->address_for_monitor_object(i), rbx); + __ movptr(rbx, Address(OSR_buf, slot_offset + BasicObjectLock::lock_offset_in_bytes())); + __ movptr(frame_map()->address_for_monitor_lock(i), rbx); + __ movptr(rbx, Address(OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes())); + __ movptr(frame_map()->address_for_monitor_object(i), rbx); } } } @@ -313,10 +327,11 @@ void LIR_Assembler::osr_entry() { int LIR_Assembler::check_icache() { Register receiver = FrameMap::receiver_opr->as_register(); Register ic_klass = IC_Klass; + const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9); if (!VerifyOops) { // insert some nops so that the verified entry point is aligned on CodeEntryAlignment - while ((__ offset() + 9) % CodeEntryAlignment != 0) { + while ((__ offset() + ic_cmp_size) % CodeEntryAlignment != 0) { __ nop(); } } @@ -347,7 +362,7 @@ void LIR_Assembler::monitorexit(LIR_Opr obj_opr, LIR_Opr lock_opr, Register new_ // and cannot block => no GC can happen // The slow case (MonitorAccessStub) uses the first two stack slots // ([esp+0] and [esp+4]), therefore we store the exception at [esp+8] - __ movl (Address(rsp, 2*wordSize), exception); + __ movptr (Address(rsp, 2*wordSize), exception); } Register obj_reg = obj_opr->as_register(); @@ -360,7 +375,7 @@ void LIR_Assembler::monitorexit(LIR_Opr obj_opr, LIR_Opr lock_opr, Register new_ lock_reg = new_hdr; // compute pointer to BasicLock Address lock_addr = frame_map()->address_for_monitor_lock(monitor_no); - __ leal(lock_reg, lock_addr); + __ lea(lock_reg, lock_addr); // unlock object MonitorAccessStub* slow_case = new MonitorExitStub(lock_opr, true, monitor_no); // _slow_case_stubs->append(slow_case); @@ -385,14 +400,18 @@ void LIR_Assembler::monitorexit(LIR_Opr obj_opr, LIR_Opr lock_opr, Register new_ if (exception->is_valid()) { // restore exception - __ movl (exception, Address(rsp, 2 * wordSize)); + __ movptr (exception, Address(rsp, 2 * wordSize)); } } // This specifies the rsp decrement needed to build the frame int LIR_Assembler::initial_frame_size_in_bytes() { // if rounding, must let FrameMap know! - return (frame_map()->framesize() - 2) * BytesPerWord; // subtract two words to account for return address and link + + // The frame_map records size in slots (32bit word) + + // subtract two words to account for return address and link + return (frame_map()->framesize() - (2*VMRegImpl::slots_per_word)) * VMRegImpl::stack_slot_size; } @@ -495,43 +514,43 @@ void LIR_Assembler::emit_deopt_handler() { // This is the fast version of java.lang.String.compare; it has not // OSR-entry and therefore, we generate a slow version for OSR's void LIR_Assembler::emit_string_compare(LIR_Opr arg0, LIR_Opr arg1, LIR_Opr dst, CodeEmitInfo* info) { - __ movl (rbx, rcx); // receiver is in rcx - __ movl (rax, arg1->as_register()); + __ movptr (rbx, rcx); // receiver is in rcx + __ movptr (rax, arg1->as_register()); // Get addresses of first characters from both Strings - __ movl (rsi, Address(rax, java_lang_String::value_offset_in_bytes())); - __ movl (rcx, Address(rax, java_lang_String::offset_offset_in_bytes())); - __ leal (rsi, Address(rsi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); + __ movptr (rsi, Address(rax, java_lang_String::value_offset_in_bytes())); + __ movptr (rcx, Address(rax, java_lang_String::offset_offset_in_bytes())); + __ lea (rsi, Address(rsi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); // rbx, may be NULL add_debug_info_for_null_check_here(info); - __ movl (rdi, Address(rbx, java_lang_String::value_offset_in_bytes())); - __ movl (rcx, Address(rbx, java_lang_String::offset_offset_in_bytes())); - __ leal (rdi, Address(rdi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); + __ movptr (rdi, Address(rbx, java_lang_String::value_offset_in_bytes())); + __ movptr (rcx, Address(rbx, java_lang_String::offset_offset_in_bytes())); + __ lea (rdi, Address(rdi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); // compute minimum length (in rax) and difference of lengths (on top of stack) if (VM_Version::supports_cmov()) { - __ movl (rbx, Address(rbx, java_lang_String::count_offset_in_bytes())); - __ movl (rax, Address(rax, java_lang_String::count_offset_in_bytes())); - __ movl (rcx, rbx); - __ subl (rbx, rax); // subtract lengths - __ pushl(rbx); // result - __ cmovl(Assembler::lessEqual, rax, rcx); + __ movl (rbx, Address(rbx, java_lang_String::count_offset_in_bytes())); + __ movl (rax, Address(rax, java_lang_String::count_offset_in_bytes())); + __ mov (rcx, rbx); + __ subptr (rbx, rax); // subtract lengths + __ push (rbx); // result + __ cmov (Assembler::lessEqual, rax, rcx); } else { Label L; - __ movl (rbx, Address(rbx, java_lang_String::count_offset_in_bytes())); - __ movl (rcx, Address(rax, java_lang_String::count_offset_in_bytes())); - __ movl (rax, rbx); - __ subl (rbx, rcx); - __ pushl(rbx); - __ jcc (Assembler::lessEqual, L); - __ movl (rax, rcx); + __ movl (rbx, Address(rbx, java_lang_String::count_offset_in_bytes())); + __ movl (rcx, Address(rax, java_lang_String::count_offset_in_bytes())); + __ mov (rax, rbx); + __ subptr (rbx, rcx); + __ push (rbx); + __ jcc (Assembler::lessEqual, L); + __ mov (rax, rcx); __ bind (L); } // is minimum length 0? Label noLoop, haveResult; - __ testl (rax, rax); + __ testptr (rax, rax); __ jcc (Assembler::zero, noLoop); // compare first characters @@ -546,9 +565,9 @@ void LIR_Assembler::emit_string_compare(LIR_Opr arg0, LIR_Opr arg1, LIR_Opr dst, // set rsi.edi to the end of the arrays (arrays have same length) // negate the index - __ leal(rsi, Address(rsi, rax, Address::times_2, type2aelembytes(T_CHAR))); - __ leal(rdi, Address(rdi, rax, Address::times_2, type2aelembytes(T_CHAR))); - __ negl(rax); + __ lea(rsi, Address(rsi, rax, Address::times_2, type2aelembytes(T_CHAR))); + __ lea(rdi, Address(rdi, rax, Address::times_2, type2aelembytes(T_CHAR))); + __ negptr(rax); // compare the strings in a loop @@ -565,12 +584,12 @@ void LIR_Assembler::emit_string_compare(LIR_Opr arg0, LIR_Opr arg1, LIR_Opr dst, // strings are equal up to min length __ bind(noLoop); - __ popl(rax); + __ pop(rax); return_op(LIR_OprFact::illegalOpr); __ bind(haveResult); // leave instruction is going to discard the TOS value - __ movl (rax, rcx); // result of call is in rax, + __ mov (rax, rcx); // result of call is in rax, } @@ -589,6 +608,11 @@ void LIR_Assembler::return_op(LIR_Opr result) { // the poll sets the condition code, but no data registers AddressLiteral polling_page(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()), relocInfo::poll_return_type); + + // NOTE: the requires that the polling page be reachable else the reloc + // goes to the movq that loads the address and not the faulting instruction + // which breaks the signal handler code + __ test32(rax, polling_page); __ ret(0); @@ -606,17 +630,22 @@ int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) { } int offset = __ offset(); + + // NOTE: the requires that the polling page be reachable else the reloc + // goes to the movq that loads the address and not the faulting instruction + // which breaks the signal handler code + __ test32(rax, polling_page); return offset; } void LIR_Assembler::move_regs(Register from_reg, Register to_reg) { - if (from_reg != to_reg) __ movl(to_reg, from_reg); + if (from_reg != to_reg) __ mov(to_reg, from_reg); } void LIR_Assembler::swap_reg(Register a, Register b) { - __ xchgl(a, b); + __ xchgptr(a, b); } @@ -634,8 +663,12 @@ void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_cod case T_LONG: { assert(patch_code == lir_patch_none, "no patching handled here"); - __ movl(dest->as_register_lo(), c->as_jint_lo()); - __ movl(dest->as_register_hi(), c->as_jint_hi()); +#ifdef _LP64 + __ movptr(dest->as_register_lo(), (intptr_t)c->as_jlong()); +#else + __ movptr(dest->as_register_lo(), c->as_jint_lo()); + __ movptr(dest->as_register_hi(), c->as_jint_hi()); +#endif // _LP64 break; } @@ -714,10 +747,15 @@ void LIR_Assembler::const2stack(LIR_Opr src, LIR_Opr dest) { case T_LONG: // fall through case T_DOUBLE: - __ movl(frame_map()->address_for_slot(dest->double_stack_ix(), - lo_word_offset_in_bytes), c->as_jint_lo_bits()); - __ movl(frame_map()->address_for_slot(dest->double_stack_ix(), - hi_word_offset_in_bytes), c->as_jint_hi_bits()); +#ifdef _LP64 + __ movptr(frame_map()->address_for_slot(dest->double_stack_ix(), + lo_word_offset_in_bytes), (intptr_t)c->as_jlong_bits()); +#else + __ movptr(frame_map()->address_for_slot(dest->double_stack_ix(), + lo_word_offset_in_bytes), c->as_jint_lo_bits()); + __ movptr(frame_map()->address_for_slot(dest->double_stack_ix(), + hi_word_offset_in_bytes), c->as_jint_hi_bits()); +#endif // _LP64 break; default: @@ -731,7 +769,7 @@ void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmi LIR_Const* c = src->as_constant_ptr(); LIR_Address* addr = dest->as_address_ptr(); - if (info != NULL) add_debug_info_for_null_check_here(info); + int null_check_here = code_offset(); switch (type) { case T_INT: // fall through case T_FLOAT: @@ -741,16 +779,33 @@ void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmi case T_OBJECT: // fall through case T_ARRAY: if (c->as_jobject() == NULL) { - __ movl(as_Address(addr), NULL_WORD); + __ movptr(as_Address(addr), (int32_t)NULL_WORD); } else { - __ movoop(as_Address(addr), c->as_jobject()); + if (is_literal_address(addr)) { + ShouldNotReachHere(); + __ movoop(as_Address(addr, noreg), c->as_jobject()); + } else { + __ movoop(as_Address(addr), c->as_jobject()); + } } break; case T_LONG: // fall through case T_DOUBLE: - __ movl(as_Address_hi(addr), c->as_jint_hi_bits()); - __ movl(as_Address_lo(addr), c->as_jint_lo_bits()); +#ifdef _LP64 + if (is_literal_address(addr)) { + ShouldNotReachHere(); + __ movptr(as_Address(addr, r15_thread), (intptr_t)c->as_jlong_bits()); + } else { + __ movptr(r10, (intptr_t)c->as_jlong_bits()); + null_check_here = code_offset(); + __ movptr(as_Address_lo(addr), r10); + } +#else + // Always reachable in 32bit so this doesn't produce useless move literal + __ movptr(as_Address_hi(addr), c->as_jint_hi_bits()); + __ movptr(as_Address_lo(addr), c->as_jint_lo_bits()); +#endif // _LP64 break; case T_BOOLEAN: // fall through @@ -766,6 +821,10 @@ void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmi default: ShouldNotReachHere(); }; + + if (info != NULL) { + add_debug_info_for_null_check(null_check_here, info); + } } @@ -775,6 +834,13 @@ void LIR_Assembler::reg2reg(LIR_Opr src, LIR_Opr dest) { // move between cpu-registers if (dest->is_single_cpu()) { +#ifdef _LP64 + if (src->type() == T_LONG) { + // Can do LONG -> OBJECT + move_regs(src->as_register_lo(), dest->as_register()); + return; + } +#endif assert(src->is_single_cpu(), "must match"); if (src->type() == T_OBJECT) { __ verify_oop(src->as_register()); @@ -782,13 +848,27 @@ void LIR_Assembler::reg2reg(LIR_Opr src, LIR_Opr dest) { move_regs(src->as_register(), dest->as_register()); } else if (dest->is_double_cpu()) { +#ifdef _LP64 + if (src->type() == T_OBJECT || src->type() == T_ARRAY) { + // Surprising to me but we can see move of a long to t_object + __ verify_oop(src->as_register()); + move_regs(src->as_register(), dest->as_register_lo()); + return; + } +#endif assert(src->is_double_cpu(), "must match"); Register f_lo = src->as_register_lo(); Register f_hi = src->as_register_hi(); Register t_lo = dest->as_register_lo(); Register t_hi = dest->as_register_hi(); +#ifdef _LP64 + assert(f_hi == f_lo, "must be same"); + assert(t_hi == t_lo, "must be same"); + move_regs(f_lo, t_lo); +#else assert(f_lo != f_hi && t_lo != t_hi, "invalid register allocation"); + if (f_lo == t_hi && f_hi == t_lo) { swap_reg(f_lo, f_hi); } else if (f_hi == t_lo) { @@ -800,6 +880,7 @@ void LIR_Assembler::reg2reg(LIR_Opr src, LIR_Opr dest) { move_regs(f_lo, t_lo); move_regs(f_hi, t_hi); } +#endif // LP64 // special moves from fpu-register to xmm-register // necessary for method results @@ -841,14 +922,16 @@ void LIR_Assembler::reg2stack(LIR_Opr src, LIR_Opr dest, BasicType type, bool po Address dst = frame_map()->address_for_slot(dest->single_stack_ix()); if (type == T_OBJECT || type == T_ARRAY) { __ verify_oop(src->as_register()); + __ movptr (dst, src->as_register()); + } else { + __ movl (dst, src->as_register()); } - __ movl (dst, src->as_register()); } else if (src->is_double_cpu()) { Address dstLO = frame_map()->address_for_slot(dest->double_stack_ix(), lo_word_offset_in_bytes); Address dstHI = frame_map()->address_for_slot(dest->double_stack_ix(), hi_word_offset_in_bytes); - __ movl (dstLO, src->as_register_lo()); - __ movl (dstHI, src->as_register_hi()); + __ movptr (dstLO, src->as_register_lo()); + NOT_LP64(__ movptr (dstHI, src->as_register_hi())); } else if (src->is_single_xmm()) { Address dst_addr = frame_map()->address_for_slot(dest->single_stack_ix()); @@ -885,6 +968,8 @@ void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch } if (patch_code != lir_patch_none) { patch = new PatchingStub(_masm, PatchingStub::access_field_id); + Address toa = as_Address(to_addr); + assert(toa.disp() != 0, "must have"); } if (info != NULL) { add_debug_info_for_null_check_here(info); @@ -918,6 +1003,10 @@ void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch case T_ADDRESS: // fall through case T_ARRAY: // fall through case T_OBJECT: // fall through +#ifdef _LP64 + __ movptr(as_Address(to_addr), src->as_register()); + break; +#endif // _LP64 case T_INT: __ movl(as_Address(to_addr), src->as_register()); break; @@ -925,6 +1014,9 @@ void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch case T_LONG: { Register from_lo = src->as_register_lo(); Register from_hi = src->as_register_hi(); +#ifdef _LP64 + __ movptr(as_Address_lo(to_addr), from_lo); +#else Register base = to_addr->base()->as_register(); Register index = noreg; if (to_addr->index()->is_register()) { @@ -950,6 +1042,7 @@ void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch } __ movl(as_Address_hi(to_addr), from_hi); } +#endif // _LP64 break; } @@ -982,16 +1075,18 @@ void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) { assert(dest->is_register(), "should not call otherwise"); if (dest->is_single_cpu()) { - __ movl(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix())); if (type == T_ARRAY || type == T_OBJECT) { + __ movptr(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix())); __ verify_oop(dest->as_register()); + } else { + __ movl(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix())); } } else if (dest->is_double_cpu()) { Address src_addr_LO = frame_map()->address_for_slot(src->double_stack_ix(), lo_word_offset_in_bytes); Address src_addr_HI = frame_map()->address_for_slot(src->double_stack_ix(), hi_word_offset_in_bytes); - __ movl(dest->as_register_hi(), src_addr_HI); - __ movl(dest->as_register_lo(), src_addr_LO); + __ movptr(dest->as_register_lo(), src_addr_LO); + NOT_LP64(__ movptr(dest->as_register_hi(), src_addr_HI)); } else if (dest->is_single_xmm()) { Address src_addr = frame_map()->address_for_slot(src->single_stack_ix()); @@ -1019,15 +1114,25 @@ void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) { void LIR_Assembler::stack2stack(LIR_Opr src, LIR_Opr dest, BasicType type) { if (src->is_single_stack()) { - __ pushl(frame_map()->address_for_slot(src ->single_stack_ix())); - __ popl (frame_map()->address_for_slot(dest->single_stack_ix())); + if (type == T_OBJECT || type == T_ARRAY) { + __ pushptr(frame_map()->address_for_slot(src ->single_stack_ix())); + __ popptr (frame_map()->address_for_slot(dest->single_stack_ix())); + } else { + __ pushl(frame_map()->address_for_slot(src ->single_stack_ix())); + __ popl (frame_map()->address_for_slot(dest->single_stack_ix())); + } } else if (src->is_double_stack()) { +#ifdef _LP64 + __ pushptr(frame_map()->address_for_slot(src ->double_stack_ix())); + __ popptr (frame_map()->address_for_slot(dest->double_stack_ix())); +#else __ pushl(frame_map()->address_for_slot(src ->double_stack_ix(), 0)); - // push and pop the part at src + 4, adding 4 for the previous push - __ pushl(frame_map()->address_for_slot(src ->double_stack_ix(), 4 + 4)); - __ popl (frame_map()->address_for_slot(dest->double_stack_ix(), 4 + 4)); + // push and pop the part at src + wordSize, adding wordSize for the previous push + __ pushl(frame_map()->address_for_slot(src ->double_stack_ix(), wordSize)); + __ popl (frame_map()->address_for_slot(dest->double_stack_ix(), wordSize)); __ popl (frame_map()->address_for_slot(dest->double_stack_ix(), 0)); +#endif // _LP64 } else { ShouldNotReachHere(); @@ -1052,7 +1157,7 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch // so blow away the value of to_rinfo before loading a // partial word into it. Do it here so that it precedes // the potential patch point below. - __ xorl(dest->as_register(), dest->as_register()); + __ xorptr(dest->as_register(), dest->as_register()); } break; } @@ -1060,6 +1165,7 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch PatchingStub* patch = NULL; if (patch_code != lir_patch_none) { patch = new PatchingStub(_masm, PatchingStub::access_field_id); + assert(from_addr.disp() != 0, "must have"); } if (info != NULL) { add_debug_info_for_null_check_here(info); @@ -1091,13 +1197,21 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch case T_ADDRESS: // fall through case T_OBJECT: // fall through case T_ARRAY: // fall through +#ifdef _LP64 + __ movptr(dest->as_register(), from_addr); + break; +#endif // _L64 case T_INT: - __ movl(dest->as_register(), from_addr); + // %%% could this be a movl? this is safer but longer instruction + __ movl2ptr(dest->as_register(), from_addr); break; case T_LONG: { Register to_lo = dest->as_register_lo(); Register to_hi = dest->as_register_hi(); +#ifdef _LP64 + __ movptr(to_lo, as_Address_lo(addr)); +#else Register base = addr->base()->as_register(); Register index = noreg; if (addr->index()->is_register()) { @@ -1109,7 +1223,7 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch // array access so this code will never have to deal with // patches or null checks. assert(info == NULL && patch == NULL, "must be"); - __ leal(to_hi, as_Address(addr)); + __ lea(to_hi, as_Address(addr)); __ movl(to_lo, Address(to_hi, 0)); __ movl(to_hi, Address(to_hi, BytesPerWord)); } else if (base == to_lo || index == to_lo) { @@ -1132,6 +1246,7 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch } __ movl(to_hi, as_Address_hi(addr)); } +#endif // _LP64 break; } @@ -1140,12 +1255,13 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch Register dest_reg = dest->as_register(); assert(VM_Version::is_P6() || dest_reg->has_byte_register(), "must use byte registers if not P6"); if (VM_Version::is_P6() || from_addr.uses(dest_reg)) { - __ movsxb(dest_reg, from_addr); + __ movsbl(dest_reg, from_addr); } else { __ movb(dest_reg, from_addr); __ shll(dest_reg, 24); __ sarl(dest_reg, 24); } + // These are unsigned so the zero extension on 64bit is just what we need break; } @@ -1153,22 +1269,26 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch Register dest_reg = dest->as_register(); assert(VM_Version::is_P6() || dest_reg->has_byte_register(), "must use byte registers if not P6"); if (VM_Version::is_P6() || from_addr.uses(dest_reg)) { - __ movzxw(dest_reg, from_addr); + __ movzwl(dest_reg, from_addr); } else { __ movw(dest_reg, from_addr); } + // This is unsigned so the zero extension on 64bit is just what we need + // __ movl2ptr(dest_reg, dest_reg); break; } case T_SHORT: { Register dest_reg = dest->as_register(); if (VM_Version::is_P6() || from_addr.uses(dest_reg)) { - __ movsxw(dest_reg, from_addr); + __ movswl(dest_reg, from_addr); } else { __ movw(dest_reg, from_addr); __ shll(dest_reg, 16); __ sarl(dest_reg, 16); } + // Might not be needed in 64bit but certainly doesn't hurt (except for code size) + __ movl2ptr(dest_reg, dest_reg); break; } @@ -1306,9 +1426,13 @@ void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) { switch (op->bytecode()) { case Bytecodes::_i2l: +#ifdef _LP64 + __ movl2ptr(dest->as_register_lo(), src->as_register()); +#else move_regs(src->as_register(), dest->as_register_lo()); move_regs(src->as_register(), dest->as_register_hi()); __ sarl(dest->as_register_hi(), 31); +#endif // LP64 break; case Bytecodes::_l2i: @@ -1346,9 +1470,9 @@ void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) { case Bytecodes::_i2f: case Bytecodes::_i2d: if (dest->is_single_xmm()) { - __ cvtsi2ss(dest->as_xmm_float_reg(), src->as_register()); + __ cvtsi2ssl(dest->as_xmm_float_reg(), src->as_register()); } else if (dest->is_double_xmm()) { - __ cvtsi2sd(dest->as_xmm_double_reg(), src->as_register()); + __ cvtsi2sdl(dest->as_xmm_double_reg(), src->as_register()); } else { assert(dest->fpu() == 0, "result must be on TOS"); __ movl(Address(rsp, 0), src->as_register()); @@ -1359,9 +1483,9 @@ void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) { case Bytecodes::_f2i: case Bytecodes::_d2i: if (src->is_single_xmm()) { - __ cvttss2si(dest->as_register(), src->as_xmm_float_reg()); + __ cvttss2sil(dest->as_register(), src->as_xmm_float_reg()); } else if (src->is_double_xmm()) { - __ cvttsd2si(dest->as_register(), src->as_xmm_double_reg()); + __ cvttsd2sil(dest->as_register(), src->as_xmm_double_reg()); } else { assert(src->fpu() == 0, "input must be on TOS"); __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_trunc())); @@ -1382,8 +1506,8 @@ void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) { assert(!dest->is_xmm_register(), "result in xmm register not supported (no SSE instruction present)"); assert(dest->fpu() == 0, "result must be on TOS"); - __ movl(Address(rsp, 0), src->as_register_lo()); - __ movl(Address(rsp, BytesPerWord), src->as_register_hi()); + __ movptr(Address(rsp, 0), src->as_register_lo()); + NOT_LP64(__ movl(Address(rsp, BytesPerWord), src->as_register_hi())); __ fild_d(Address(rsp, 0)); // float result is rounded later through spilling break; @@ -1392,7 +1516,7 @@ void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) { case Bytecodes::_d2l: assert(!src->is_xmm_register(), "input in xmm register not supported (no SSE instruction present)"); assert(src->fpu() == 0, "input must be on TOS"); - assert(dest == FrameMap::rax_rdx_long_opr, "runtime stub places result in these registers"); + assert(dest == FrameMap::long0_opr, "runtime stub places result in these registers"); // instruction sequence too long to inline it here { @@ -1439,7 +1563,7 @@ void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) { } else if (len == tmp3) { // everything is ok } else { - __ movl(tmp3, len); + __ mov(tmp3, len); } __ allocate_array(op->obj()->as_register(), len, @@ -1466,31 +1590,32 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { CodeStub* stub = op->stub(); Label done; - __ cmpl(value, 0); + __ cmpptr(value, (int32_t)NULL_WORD); __ jcc(Assembler::equal, done); add_debug_info_for_null_check_here(op->info_for_exception()); - __ movl(k_RInfo, Address(array, oopDesc::klass_offset_in_bytes())); - __ movl(klass_RInfo, Address(value, oopDesc::klass_offset_in_bytes())); + __ movptr(k_RInfo, Address(array, oopDesc::klass_offset_in_bytes())); + __ movptr(klass_RInfo, Address(value, oopDesc::klass_offset_in_bytes())); // get instance klass - __ movl(k_RInfo, Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc))); + __ movptr(k_RInfo, Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc))); // get super_check_offset __ movl(Rtmp1, Address(k_RInfo, sizeof(oopDesc) + Klass::super_check_offset_offset_in_bytes())); // See if we get an immediate positive hit - __ cmpl(k_RInfo, Address(klass_RInfo, Rtmp1, Address::times_1)); + __ cmpptr(k_RInfo, Address(klass_RInfo, Rtmp1, Address::times_1)); __ jcc(Assembler::equal, done); // check for immediate negative hit __ cmpl(Rtmp1, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()); __ jcc(Assembler::notEqual, *stub->entry()); // check for self - __ cmpl(klass_RInfo, k_RInfo); + __ cmpptr(klass_RInfo, k_RInfo); __ jcc(Assembler::equal, done); - __ pushl(klass_RInfo); - __ pushl(k_RInfo); + __ push(klass_RInfo); + __ push(k_RInfo); __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); - __ popl(klass_RInfo); - __ popl(k_RInfo); + __ pop(klass_RInfo); + __ pop(k_RInfo); + // result is a boolean __ cmpl(k_RInfo, 0); __ jcc(Assembler::equal, *stub->entry()); __ bind(done); @@ -1521,10 +1646,14 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { if (!k->is_loaded()) { jobject2reg_with_patching(k_RInfo, op->info_for_patch()); } else { +#ifdef _LP64 + __ movoop(k_RInfo, k->encoding()); +#else k_RInfo = noreg; +#endif // _LP64 } assert(obj != k_RInfo, "must be different"); - __ cmpl(obj, 0); + __ cmpptr(obj, (int32_t)NULL_WORD); if (op->profiled_method() != NULL) { ciMethod* method = op->profiled_method(); int bci = op->profiled_bci(); @@ -1556,9 +1685,13 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { // get object classo // not a safepoint as obj null check happens earlier if (k->is_loaded()) { +#ifdef _LP64 + __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); +#else __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->encoding()); +#endif // _LP64 } else { - __ cmpl(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); + __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); } __ jcc(Assembler::notEqual, *stub->entry()); @@ -1566,24 +1699,37 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { } else { // get object class // not a safepoint as obj null check happens earlier - __ movl(klass_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); + __ movptr(klass_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); if (k->is_loaded()) { // See if we get an immediate positive hit +#ifdef _LP64 + __ cmpptr(k_RInfo, Address(klass_RInfo, k->super_check_offset())); +#else __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->encoding()); +#endif // _LP64 if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() != k->super_check_offset()) { __ jcc(Assembler::notEqual, *stub->entry()); } else { // See if we get an immediate positive hit __ jcc(Assembler::equal, done); // check for self +#ifdef _LP64 + __ cmpptr(klass_RInfo, k_RInfo); +#else __ cmpoop(klass_RInfo, k->encoding()); +#endif // _LP64 __ jcc(Assembler::equal, done); - __ pushl(klass_RInfo); + __ push(klass_RInfo); +#ifdef _LP64 + __ push(k_RInfo); +#else __ pushoop(k->encoding()); +#endif // _LP64 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); - __ popl(klass_RInfo); - __ popl(klass_RInfo); + __ pop(klass_RInfo); + __ pop(klass_RInfo); + // result is a boolean __ cmpl(klass_RInfo, 0); __ jcc(Assembler::equal, *stub->entry()); } @@ -1591,20 +1737,21 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { } else { __ movl(Rtmp1, Address(k_RInfo, sizeof(oopDesc) + Klass::super_check_offset_offset_in_bytes())); // See if we get an immediate positive hit - __ cmpl(k_RInfo, Address(klass_RInfo, Rtmp1, Address::times_1)); + __ cmpptr(k_RInfo, Address(klass_RInfo, Rtmp1, Address::times_1)); __ jcc(Assembler::equal, done); // check for immediate negative hit __ cmpl(Rtmp1, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()); __ jcc(Assembler::notEqual, *stub->entry()); // check for self - __ cmpl(klass_RInfo, k_RInfo); + __ cmpptr(klass_RInfo, k_RInfo); __ jcc(Assembler::equal, done); - __ pushl(klass_RInfo); - __ pushl(k_RInfo); + __ push(klass_RInfo); + __ push(k_RInfo); __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); - __ popl(klass_RInfo); - __ popl(k_RInfo); + __ pop(klass_RInfo); + __ pop(k_RInfo); + // result is a boolean __ cmpl(k_RInfo, 0); __ jcc(Assembler::equal, *stub->entry()); __ bind(done); @@ -1612,7 +1759,7 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { } if (dst != obj) { - __ movl(dst, obj); + __ mov(dst, obj); } } else if (code == lir_instanceof) { Register obj = op->object()->as_register(); @@ -1632,29 +1779,33 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { // so let's do it before loading the class if (!k->is_loaded()) { jobject2reg_with_patching(k_RInfo, op->info_for_patch()); + } else { + LP64_ONLY(__ movoop(k_RInfo, k->encoding())); } assert(obj != k_RInfo, "must be different"); __ verify_oop(obj); if (op->fast_check()) { - __ cmpl(obj, 0); + __ cmpptr(obj, (int32_t)NULL_WORD); __ jcc(Assembler::equal, zero); // get object class // not a safepoint as obj null check happens earlier - if (k->is_loaded()) { - __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->encoding()); + if (LP64_ONLY(false &&) k->is_loaded()) { + NOT_LP64(__ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->encoding())); k_RInfo = noreg; } else { - __ cmpl(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); + __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); } __ jcc(Assembler::equal, one); } else { // get object class // not a safepoint as obj null check happens earlier - __ cmpl(obj, 0); + __ cmpptr(obj, (int32_t)NULL_WORD); __ jcc(Assembler::equal, zero); - __ movl(klass_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); + __ movptr(klass_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); + +#ifndef _LP64 if (k->is_loaded()) { // See if we get an immediate positive hit __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->encoding()); @@ -1663,40 +1814,43 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { // check for self __ cmpoop(klass_RInfo, k->encoding()); __ jcc(Assembler::equal, one); - __ pushl(klass_RInfo); + __ push(klass_RInfo); __ pushoop(k->encoding()); __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); - __ popl(klass_RInfo); - __ popl(dst); + __ pop(klass_RInfo); + __ pop(dst); __ jmp(done); } } else { +#else + { // YUCK +#endif // LP64 assert(dst != klass_RInfo && dst != k_RInfo, "need 3 registers"); __ movl(dst, Address(k_RInfo, sizeof(oopDesc) + Klass::super_check_offset_offset_in_bytes())); // See if we get an immediate positive hit - __ cmpl(k_RInfo, Address(klass_RInfo, dst, Address::times_1)); + __ cmpptr(k_RInfo, Address(klass_RInfo, dst, Address::times_1)); __ jcc(Assembler::equal, one); // check for immediate negative hit __ cmpl(dst, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()); __ jcc(Assembler::notEqual, zero); // check for self - __ cmpl(klass_RInfo, k_RInfo); + __ cmpptr(klass_RInfo, k_RInfo); __ jcc(Assembler::equal, one); - __ pushl(klass_RInfo); - __ pushl(k_RInfo); + __ push(klass_RInfo); + __ push(k_RInfo); __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); - __ popl(klass_RInfo); - __ popl(dst); + __ pop(klass_RInfo); + __ pop(dst); __ jmp(done); } } __ bind(zero); - __ xorl(dst, dst); + __ xorptr(dst, dst); __ jmp(done); __ bind(one); - __ movl(dst, 1); + __ movptr(dst, 1); __ bind(done); } else { ShouldNotReachHere(); @@ -1706,8 +1860,7 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) { - if (op->code() == lir_cas_long) { - assert(VM_Version::supports_cx8(), "wrong machine"); + if (LP64_ONLY(false &&) op->code() == lir_cas_long && VM_Version::supports_cx8()) { assert(op->cmp_value()->as_register_lo() == rax, "wrong register"); assert(op->cmp_value()->as_register_hi() == rdx, "wrong register"); assert(op->new_value()->as_register_lo() == rbx, "wrong register"); @@ -1716,10 +1869,11 @@ void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) { if (os::is_MP()) { __ lock(); } - __ cmpxchg8(Address(addr, 0)); + NOT_LP64(__ cmpxchg8(Address(addr, 0))); - } else if (op->code() == lir_cas_int || op->code() == lir_cas_obj) { - Register addr = op->addr()->as_register(); + } else if (op->code() == lir_cas_int || op->code() == lir_cas_obj ) { + NOT_LP64(assert(op->addr()->is_single_cpu(), "must be single");) + Register addr = (op->addr()->is_single_cpu() ? op->addr()->as_register() : op->addr()->as_register_lo()); Register newval = op->new_value()->as_register(); Register cmpval = op->cmp_value()->as_register(); assert(cmpval == rax, "wrong register"); @@ -1730,7 +1884,28 @@ void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) { if (os::is_MP()) { __ lock(); } - __ cmpxchg(newval, Address(addr, 0)); + if ( op->code() == lir_cas_obj) { + __ cmpxchgptr(newval, Address(addr, 0)); + } else if (op->code() == lir_cas_int) { + __ cmpxchgl(newval, Address(addr, 0)); + } else { + LP64_ONLY(__ cmpxchgq(newval, Address(addr, 0))); + } +#ifdef _LP64 + } else if (op->code() == lir_cas_long) { + Register addr = (op->addr()->is_single_cpu() ? op->addr()->as_register() : op->addr()->as_register_lo()); + Register newval = op->new_value()->as_register_lo(); + Register cmpval = op->cmp_value()->as_register_lo(); + assert(cmpval == rax, "wrong register"); + assert(newval != NULL, "new val must be register"); + assert(cmpval != newval, "cmp and new values must be in different registers"); + assert(cmpval != addr, "cmp and addr must be in different registers"); + assert(newval != addr, "new value and addr must be in different registers"); + if (os::is_MP()) { + __ lock(); + } + __ cmpxchgq(newval, Address(addr, 0)); +#endif // _LP64 } else { Unimplemented(); } @@ -1765,17 +1940,17 @@ void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, L // optimized version that does not require a branch if (opr2->is_single_cpu()) { assert(opr2->cpu_regnr() != result->cpu_regnr(), "opr2 already overwritten by previous move"); - __ cmovl(ncond, result->as_register(), opr2->as_register()); + __ cmov(ncond, result->as_register(), opr2->as_register()); } else if (opr2->is_double_cpu()) { assert(opr2->cpu_regnrLo() != result->cpu_regnrLo() && opr2->cpu_regnrLo() != result->cpu_regnrHi(), "opr2 already overwritten by previous move"); assert(opr2->cpu_regnrHi() != result->cpu_regnrLo() && opr2->cpu_regnrHi() != result->cpu_regnrHi(), "opr2 already overwritten by previous move"); - __ cmovl(ncond, result->as_register_lo(), opr2->as_register_lo()); - __ cmovl(ncond, result->as_register_hi(), opr2->as_register_hi()); + __ cmovptr(ncond, result->as_register_lo(), opr2->as_register_lo()); + NOT_LP64(__ cmovptr(ncond, result->as_register_hi(), opr2->as_register_hi());) } else if (opr2->is_single_stack()) { __ cmovl(ncond, result->as_register(), frame_map()->address_for_slot(opr2->single_stack_ix())); } else if (opr2->is_double_stack()) { - __ cmovl(ncond, result->as_register_lo(), frame_map()->address_for_slot(opr2->double_stack_ix(), lo_word_offset_in_bytes)); - __ cmovl(ncond, result->as_register_hi(), frame_map()->address_for_slot(opr2->double_stack_ix(), hi_word_offset_in_bytes)); + __ cmovptr(ncond, result->as_register_lo(), frame_map()->address_for_slot(opr2->double_stack_ix(), lo_word_offset_in_bytes)); + NOT_LP64(__ cmovptr(ncond, result->as_register_hi(), frame_map()->address_for_slot(opr2->double_stack_ix(), hi_word_offset_in_bytes));) } else { ShouldNotReachHere(); } @@ -1851,23 +2026,28 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr // cpu register - cpu register Register rreg_lo = right->as_register_lo(); Register rreg_hi = right->as_register_hi(); - assert_different_registers(lreg_lo, lreg_hi, rreg_lo, rreg_hi); + NOT_LP64(assert_different_registers(lreg_lo, lreg_hi, rreg_lo, rreg_hi)); + LP64_ONLY(assert_different_registers(lreg_lo, rreg_lo)); switch (code) { case lir_add: - __ addl(lreg_lo, rreg_lo); - __ adcl(lreg_hi, rreg_hi); + __ addptr(lreg_lo, rreg_lo); + NOT_LP64(__ adcl(lreg_hi, rreg_hi)); break; case lir_sub: - __ subl(lreg_lo, rreg_lo); - __ sbbl(lreg_hi, rreg_hi); + __ subptr(lreg_lo, rreg_lo); + NOT_LP64(__ sbbl(lreg_hi, rreg_hi)); break; case lir_mul: +#ifdef _LP64 + __ imulq(lreg_lo, rreg_lo); +#else assert(lreg_lo == rax && lreg_hi == rdx, "must be"); __ imull(lreg_hi, rreg_lo); __ imull(rreg_hi, lreg_lo); __ addl (rreg_hi, lreg_hi); __ mull (rreg_lo); __ addl (lreg_hi, rreg_hi); +#endif // _LP64 break; default: ShouldNotReachHere(); @@ -1875,20 +2055,35 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr } else if (right->is_constant()) { // cpu register - constant +#ifdef _LP64 + jlong c = right->as_constant_ptr()->as_jlong_bits(); + __ movptr(r10, (intptr_t) c); + switch (code) { + case lir_add: + __ addptr(lreg_lo, r10); + break; + case lir_sub: + __ subptr(lreg_lo, r10); + break; + default: + ShouldNotReachHere(); + } +#else jint c_lo = right->as_constant_ptr()->as_jint_lo(); jint c_hi = right->as_constant_ptr()->as_jint_hi(); switch (code) { case lir_add: - __ addl(lreg_lo, c_lo); + __ addptr(lreg_lo, c_lo); __ adcl(lreg_hi, c_hi); break; case lir_sub: - __ subl(lreg_lo, c_lo); + __ subptr(lreg_lo, c_lo); __ sbbl(lreg_hi, c_hi); break; default: ShouldNotReachHere(); } +#endif // _LP64 } else { ShouldNotReachHere(); @@ -2065,11 +2260,11 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr jint c = right->as_constant_ptr()->as_jint(); switch (code) { case lir_add: { - __ increment(laddr, c); + __ incrementl(laddr, c); break; } case lir_sub: { - __ decrement(laddr, c); + __ decrementl(laddr, c); break; } default: ShouldNotReachHere(); @@ -2211,9 +2406,9 @@ void LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr } else { Register rright = right->as_register(); switch (code) { - case lir_logic_and: __ andl (reg, rright); break; - case lir_logic_or : __ orl (reg, rright); break; - case lir_logic_xor: __ xorl (reg, rright); break; + case lir_logic_and: __ andptr (reg, rright); break; + case lir_logic_or : __ orptr (reg, rright); break; + case lir_logic_xor: __ xorptr (reg, rright); break; default: ShouldNotReachHere(); } } @@ -2222,6 +2417,21 @@ void LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr Register l_lo = left->as_register_lo(); Register l_hi = left->as_register_hi(); if (right->is_constant()) { +#ifdef _LP64 + __ mov64(rscratch1, right->as_constant_ptr()->as_jlong()); + switch (code) { + case lir_logic_and: + __ andq(l_lo, rscratch1); + break; + case lir_logic_or: + __ orq(l_lo, rscratch1); + break; + case lir_logic_xor: + __ xorq(l_lo, rscratch1); + break; + default: ShouldNotReachHere(); + } +#else int r_lo = right->as_constant_ptr()->as_jint_lo(); int r_hi = right->as_constant_ptr()->as_jint_hi(); switch (code) { @@ -2239,22 +2449,23 @@ void LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr break; default: ShouldNotReachHere(); } +#endif // _LP64 } else { Register r_lo = right->as_register_lo(); Register r_hi = right->as_register_hi(); assert(l_lo != r_hi, "overwriting registers"); switch (code) { case lir_logic_and: - __ andl(l_lo, r_lo); - __ andl(l_hi, r_hi); + __ andptr(l_lo, r_lo); + NOT_LP64(__ andptr(l_hi, r_hi);) break; case lir_logic_or: - __ orl(l_lo, r_lo); - __ orl(l_hi, r_hi); + __ orptr(l_lo, r_lo); + NOT_LP64(__ orptr(l_hi, r_hi);) break; case lir_logic_xor: - __ xorl(l_lo, r_lo); - __ xorl(l_hi, r_hi); + __ xorptr(l_lo, r_lo); + NOT_LP64(__ xorptr(l_hi, r_hi);) break; default: ShouldNotReachHere(); } @@ -2263,6 +2474,9 @@ void LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr Register dst_lo = dst->as_register_lo(); Register dst_hi = dst->as_register_hi(); +#ifdef _LP64 + move_regs(l_lo, dst_lo); +#else if (dst_lo == l_hi) { assert(dst_hi != l_lo, "overwriting registers"); move_regs(l_hi, dst_hi); @@ -2272,6 +2486,7 @@ void LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr move_regs(l_lo, dst_lo); move_regs(l_hi, dst_hi); } +#endif // _LP64 } } @@ -2306,7 +2521,7 @@ void LIR_Assembler::arithmetic_idiv(LIR_Code code, LIR_Opr left, LIR_Opr right, move_regs(lreg, dreg); } else if (code == lir_irem) { Label done; - __ movl(dreg, lreg); + __ mov(dreg, lreg); __ andl(dreg, 0x80000000 | (divisor - 1)); __ jcc(Assembler::positive, done); __ decrement(dreg); @@ -2340,21 +2555,36 @@ void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, Register reg1 = opr1->as_register(); if (opr2->is_single_cpu()) { // cpu register - cpu register - __ cmpl(reg1, opr2->as_register()); + if (opr1->type() == T_OBJECT || opr1->type() == T_ARRAY) { + __ cmpptr(reg1, opr2->as_register()); + } else { + assert(opr2->type() != T_OBJECT && opr2->type() != T_ARRAY, "cmp int, oop?"); + __ cmpl(reg1, opr2->as_register()); + } } else if (opr2->is_stack()) { // cpu register - stack - __ cmpl(reg1, frame_map()->address_for_slot(opr2->single_stack_ix())); + if (opr1->type() == T_OBJECT || opr1->type() == T_ARRAY) { + __ cmpptr(reg1, frame_map()->address_for_slot(opr2->single_stack_ix())); + } else { + __ cmpl(reg1, frame_map()->address_for_slot(opr2->single_stack_ix())); + } } else if (opr2->is_constant()) { // cpu register - constant LIR_Const* c = opr2->as_constant_ptr(); if (c->type() == T_INT) { __ cmpl(reg1, c->as_jint()); - } else if (c->type() == T_OBJECT) { + } else if (c->type() == T_OBJECT || c->type() == T_ARRAY) { + // In 64bit oops are single register jobject o = c->as_jobject(); if (o == NULL) { - __ cmpl(reg1, NULL_WORD); + __ cmpptr(reg1, (int32_t)NULL_WORD); } else { +#ifdef _LP64 + __ movoop(rscratch1, o); + __ cmpptr(reg1, rscratch1); +#else __ cmpoop(reg1, c->as_jobject()); +#endif // _LP64 } } else { ShouldNotReachHere(); @@ -2373,6 +2603,9 @@ void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, Register xlo = opr1->as_register_lo(); Register xhi = opr1->as_register_hi(); if (opr2->is_double_cpu()) { +#ifdef _LP64 + __ cmpptr(xlo, opr2->as_register_lo()); +#else // cpu register - cpu register Register ylo = opr2->as_register_lo(); Register yhi = opr2->as_register_hi(); @@ -2381,11 +2614,16 @@ void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, if (condition == lir_cond_equal || condition == lir_cond_notEqual) { __ orl(xhi, xlo); } +#endif // _LP64 } else if (opr2->is_constant()) { // cpu register - constant 0 assert(opr2->as_jlong() == (jlong)0, "only handles zero"); +#ifdef _LP64 + __ cmpptr(xlo, (int32_t)opr2->as_jlong()); +#else assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "only handles equals case"); __ orl(xhi, xlo); +#endif // _LP64 } else { ShouldNotReachHere(); } @@ -2438,16 +2676,28 @@ void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, __ fcmp(noreg, opr2->fpu(), op->fpu_pop_count() > 0, op->fpu_pop_count() > 1); } else if (opr1->is_address() && opr2->is_constant()) { + LIR_Const* c = opr2->as_constant_ptr(); +#ifdef _LP64 + if (c->type() == T_OBJECT || c->type() == T_ARRAY) { + assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "need to reverse"); + __ movoop(rscratch1, c->as_jobject()); + } +#endif // LP64 if (op->info() != NULL) { add_debug_info_for_null_check_here(op->info()); } // special case: address - constant LIR_Address* addr = opr1->as_address_ptr(); - LIR_Const* c = opr2->as_constant_ptr(); if (c->type() == T_INT) { __ cmpl(as_Address(addr), c->as_jint()); - } else if (c->type() == T_OBJECT) { + } else if (c->type() == T_OBJECT || c->type() == T_ARRAY) { +#ifdef _LP64 + // %%% Make this explode if addr isn't reachable until we figure out a + // better strategy by giving noreg as the temp for as_Address + __ cmpptr(rscratch1, as_Address(addr, noreg)); +#else __ cmpoop(as_Address(addr), c->as_jobject()); +#endif // _LP64 } else { ShouldNotReachHere(); } @@ -2476,11 +2726,27 @@ void LIR_Assembler::comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Op } } else { assert(code == lir_cmp_l2i, "check"); +#ifdef _LP64 + Register dest = dst->as_register(); + __ xorptr(dest, dest); + Label high, done; + __ cmpptr(left->as_register_lo(), right->as_register_lo()); + __ jcc(Assembler::equal, done); + __ jcc(Assembler::greater, high); + __ decrement(dest); + __ jmp(done); + __ bind(high); + __ increment(dest); + + __ bind(done); + +#else __ lcmp2int(left->as_register_hi(), left->as_register_lo(), right->as_register_hi(), right->as_register_lo()); move_regs(left->as_register_hi(), dst->as_register()); +#endif // _LP64 } } @@ -2551,7 +2817,8 @@ void LIR_Assembler::emit_static_call_stub() { __ movoop(rbx, (jobject)NULL); // must be set to -1 at code generation time assert(!os::is_MP() || ((__ offset() + 1) % BytesPerWord) == 0, "must be aligned on MP"); - __ jump(RuntimeAddress((address)-1)); + // On 64bit this will die since it will take a movq & jmp, must be only a jmp + __ jump(RuntimeAddress(__ pc())); assert(__ offset() - start <= call_stub_size, "stub too big") __ end_a_stub(); @@ -2616,6 +2883,14 @@ void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, LIR_Opr count, LIR_Opr Register lo = left->as_register_lo(); Register hi = left->as_register_hi(); assert(lo != SHIFT_count && hi != SHIFT_count, "left cannot be ECX"); +#ifdef _LP64 + switch (code) { + case lir_shl: __ shlptr(lo); break; + case lir_shr: __ sarptr(lo); break; + case lir_ushr: __ shrptr(lo); break; + default: ShouldNotReachHere(); + } +#else switch (code) { case lir_shl: __ lshl(hi, lo); break; @@ -2623,6 +2898,7 @@ void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, LIR_Opr count, LIR_Opr case lir_ushr: __ lshr(hi, lo, false); break; default: ShouldNotReachHere(); } +#endif // LP64 } else { ShouldNotReachHere(); } @@ -2643,7 +2919,21 @@ void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, jint count, LIR_Opr de default: ShouldNotReachHere(); } } else if (dest->is_double_cpu()) { +#ifndef _LP64 Unimplemented(); +#else + // first move left into dest so that left is not destroyed by the shift + Register value = dest->as_register_lo(); + count = count & 0x1F; // Java spec + + move_regs(left->as_register_lo(), value); + switch (code) { + case lir_shl: __ shlptr(value, count); break; + case lir_shr: __ sarptr(value, count); break; + case lir_ushr: __ shrptr(value, count); break; + default: ShouldNotReachHere(); + } +#endif // _LP64 } else { ShouldNotReachHere(); } @@ -2654,7 +2944,7 @@ void LIR_Assembler::store_parameter(Register r, int offset_from_rsp_in_words) { assert(offset_from_rsp_in_words >= 0, "invalid offset from rsp"); int offset_from_rsp_in_bytes = offset_from_rsp_in_words * BytesPerWord; assert(offset_from_rsp_in_bytes < frame_map()->reserved_argument_area_size(), "invalid offset"); - __ movl (Address(rsp, offset_from_rsp_in_bytes), r); + __ movptr (Address(rsp, offset_from_rsp_in_bytes), r); } @@ -2662,7 +2952,7 @@ void LIR_Assembler::store_parameter(jint c, int offset_from_rsp_in_words) { assert(offset_from_rsp_in_words >= 0, "invalid offset from rsp"); int offset_from_rsp_in_bytes = offset_from_rsp_in_words * BytesPerWord; assert(offset_from_rsp_in_bytes < frame_map()->reserved_argument_area_size(), "invalid offset"); - __ movl (Address(rsp, offset_from_rsp_in_bytes), c); + __ movptr (Address(rsp, offset_from_rsp_in_bytes), c); } @@ -2710,27 +3000,52 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { // these are just temporary placements until we need to reload store_parameter(src_pos, 3); store_parameter(src, 4); - assert(src == rcx && src_pos == rdx, "mismatch in calling convention"); + NOT_LP64(assert(src == rcx && src_pos == rdx, "mismatch in calling convention");) + + address entry = CAST_FROM_FN_PTR(address, Runtime1::arraycopy); // pass arguments: may push as this is not a safepoint; SP must be fix at each safepoint - __ pushl(length); - __ pushl(dst_pos); - __ pushl(dst); - __ pushl(src_pos); - __ pushl(src); - address entry = CAST_FROM_FN_PTR(address, Runtime1::arraycopy); +#ifdef _LP64 + // The arguments are in java calling convention so we can trivially shift them to C + // convention + assert_different_registers(c_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4); + __ mov(c_rarg0, j_rarg0); + assert_different_registers(c_rarg1, j_rarg2, j_rarg3, j_rarg4); + __ mov(c_rarg1, j_rarg1); + assert_different_registers(c_rarg2, j_rarg3, j_rarg4); + __ mov(c_rarg2, j_rarg2); + assert_different_registers(c_rarg3, j_rarg4); + __ mov(c_rarg3, j_rarg3); +#ifdef _WIN64 + // Allocate abi space for args but be sure to keep stack aligned + __ subptr(rsp, 6*wordSize); + store_parameter(j_rarg4, 4); + __ call(RuntimeAddress(entry)); + __ addptr(rsp, 6*wordSize); +#else + __ mov(c_rarg4, j_rarg4); + __ call(RuntimeAddress(entry)); +#endif // _WIN64 +#else + __ push(length); + __ push(dst_pos); + __ push(dst); + __ push(src_pos); + __ push(src); __ call_VM_leaf(entry, 5); // removes pushed parameter from the stack +#endif // _LP64 + __ cmpl(rax, 0); __ jcc(Assembler::equal, *stub->continuation()); // Reload values from the stack so they are where the stub // expects them. - __ movl (dst, Address(rsp, 0*BytesPerWord)); - __ movl (dst_pos, Address(rsp, 1*BytesPerWord)); - __ movl (length, Address(rsp, 2*BytesPerWord)); - __ movl (src_pos, Address(rsp, 3*BytesPerWord)); - __ movl (src, Address(rsp, 4*BytesPerWord)); + __ movptr (dst, Address(rsp, 0*BytesPerWord)); + __ movptr (dst_pos, Address(rsp, 1*BytesPerWord)); + __ movptr (length, Address(rsp, 2*BytesPerWord)); + __ movptr (src_pos, Address(rsp, 3*BytesPerWord)); + __ movptr (src, Address(rsp, 4*BytesPerWord)); __ jmp(*stub->entry()); __ bind(*stub->continuation()); @@ -2769,13 +3084,15 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { Address src_klass_addr = Address(src, oopDesc::klass_offset_in_bytes()); Address dst_klass_addr = Address(dst, oopDesc::klass_offset_in_bytes()); + // length and pos's are all sign extended at this point on 64bit + // test for NULL if (flags & LIR_OpArrayCopy::src_null_check) { - __ testl(src, src); + __ testptr(src, src); __ jcc(Assembler::zero, *stub->entry()); } if (flags & LIR_OpArrayCopy::dst_null_check) { - __ testl(dst, dst); + __ testptr(dst, dst); __ jcc(Assembler::zero, *stub->entry()); } @@ -2794,19 +3111,19 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { } if (flags & LIR_OpArrayCopy::src_range_check) { - __ leal(tmp, Address(src_pos, length, Address::times_1, 0)); + __ lea(tmp, Address(src_pos, length, Address::times_1, 0)); __ cmpl(tmp, src_length_addr); __ jcc(Assembler::above, *stub->entry()); } if (flags & LIR_OpArrayCopy::dst_range_check) { - __ leal(tmp, Address(dst_pos, length, Address::times_1, 0)); + __ lea(tmp, Address(dst_pos, length, Address::times_1, 0)); __ cmpl(tmp, dst_length_addr); __ jcc(Assembler::above, *stub->entry()); } if (flags & LIR_OpArrayCopy::type_check) { - __ movl(tmp, src_klass_addr); - __ cmpl(tmp, dst_klass_addr); + __ movptr(tmp, src_klass_addr); + __ cmpptr(tmp, dst_klass_addr); __ jcc(Assembler::notEqual, *stub->entry()); } @@ -2822,14 +3139,14 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { Label known_ok, halt; __ movoop(tmp, default_type->encoding()); if (basic_type != T_OBJECT) { - __ cmpl(tmp, dst_klass_addr); + __ cmpptr(tmp, dst_klass_addr); __ jcc(Assembler::notEqual, halt); - __ cmpl(tmp, src_klass_addr); + __ cmpptr(tmp, src_klass_addr); __ jcc(Assembler::equal, known_ok); } else { - __ cmpl(tmp, dst_klass_addr); + __ cmpptr(tmp, dst_klass_addr); __ jcc(Assembler::equal, known_ok); - __ cmpl(src, dst); + __ cmpptr(src, dst); __ jcc(Assembler::equal, known_ok); } __ bind(halt); @@ -2838,14 +3155,24 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { } #endif - __ leal(tmp, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); - store_parameter(tmp, 0); - __ leal(tmp, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); - store_parameter(tmp, 1); if (shift_amount > 0 && basic_type != T_OBJECT) { - __ shll(length, shift_amount); + __ shlptr(length, shift_amount); } + +#ifdef _LP64 + assert_different_registers(c_rarg0, dst, dst_pos, length); + __ lea(c_rarg0, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); + assert_different_registers(c_rarg1, length); + __ lea(c_rarg1, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); + __ mov(c_rarg2, length); + +#else + __ lea(tmp, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); + store_parameter(tmp, 0); + __ lea(tmp, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); + store_parameter(tmp, 1); store_parameter(length, 2); +#endif // _LP64 if (basic_type == T_OBJECT) { __ call_VM_leaf(CAST_FROM_FN_PTR(address, Runtime1::oop_arraycopy), 0); } else { @@ -2945,13 +3272,13 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) { } } } else { - __ movl(recv, Address(recv, oopDesc::klass_offset_in_bytes())); + __ movptr(recv, Address(recv, oopDesc::klass_offset_in_bytes())); Label update_done; uint i; for (i = 0; i < VirtualCallData::row_limit(); i++) { Label next_test; // See if the receiver is receiver[n]. - __ cmpl(recv, Address(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)))); + __ cmpptr(recv, Address(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)))); __ jcc(Assembler::notEqual, next_test); Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); __ addl(data_addr, DataLayout::counter_increment); @@ -2963,9 +3290,9 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) { for (i = 0; i < VirtualCallData::row_limit(); i++) { Label next_test; Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i))); - __ cmpl(recv_addr, NULL_WORD); + __ cmpptr(recv_addr, (int32_t)NULL_WORD); __ jcc(Assembler::notEqual, next_test); - __ movl(recv_addr, recv); + __ movptr(recv_addr, recv); __ movl(Address(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))), DataLayout::counter_increment); if (i < (VirtualCallData::row_limit() - 1)) { __ jmp(update_done); @@ -2985,7 +3312,7 @@ void LIR_Assembler::emit_delay(LIR_OpDelay*) { void LIR_Assembler::monitor_address(int monitor_no, LIR_Opr dst) { - __ leal(dst->as_register(), frame_map()->address_for_monitor_lock(monitor_no)); + __ lea(dst->as_register(), frame_map()->address_for_monitor_lock(monitor_no)); } @@ -3001,6 +3328,11 @@ void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest) { } else if (left->is_double_cpu()) { Register lo = left->as_register_lo(); +#ifdef _LP64 + Register dst = dest->as_register_lo(); + __ movptr(dst, lo); + __ negptr(dst); +#else Register hi = left->as_register_hi(); __ lneg(hi, lo); if (dest->as_register_lo() == hi) { @@ -3011,6 +3343,7 @@ void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest) { move_regs(lo, dest->as_register_lo()); move_regs(hi, dest->as_register_hi()); } +#endif // _LP64 } else if (dest->is_single_xmm()) { if (left->as_xmm_float_reg() != dest->as_xmm_float_reg()) { @@ -3039,8 +3372,9 @@ void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest) { void LIR_Assembler::leal(LIR_Opr addr, LIR_Opr dest) { assert(addr->is_address() && dest->is_register(), "check"); - Register reg = dest->as_register(); - __ leal(dest->as_register(), as_Address(addr->as_address_ptr())); + Register reg; + reg = dest->as_pointer_register(); + __ lea(reg, as_Address(addr->as_address_ptr())); } @@ -3063,9 +3397,13 @@ void LIR_Assembler::volatile_move_op(LIR_Opr src, LIR_Opr dest, BasicType type, if (src->is_double_xmm()) { if (dest->is_double_cpu()) { - __ movd(dest->as_register_lo(), src->as_xmm_double_reg()); +#ifdef _LP64 + __ movdq(dest->as_register_lo(), src->as_xmm_double_reg()); +#else + __ movdl(dest->as_register_lo(), src->as_xmm_double_reg()); __ psrlq(src->as_xmm_double_reg(), 32); - __ movd(dest->as_register_hi(), src->as_xmm_double_reg()); + __ movdl(dest->as_register_hi(), src->as_xmm_double_reg()); +#endif // _LP64 } else if (dest->is_double_stack()) { __ movdbl(frame_map()->address_for_slot(dest->double_stack_ix()), src->as_xmm_double_reg()); } else if (dest->is_address()) { @@ -3109,7 +3447,8 @@ void LIR_Assembler::volatile_move_op(LIR_Opr src, LIR_Opr dest, BasicType type, void LIR_Assembler::membar() { - __ membar(); + // QQQ sparc TSO uses this, + __ membar( Assembler::Membar_mask_bits(Assembler::StoreLoad)); } void LIR_Assembler::membar_acquire() { @@ -3124,7 +3463,12 @@ void LIR_Assembler::membar_release() { void LIR_Assembler::get_thread(LIR_Opr result_reg) { assert(result_reg->is_register(), "check"); +#ifdef _LP64 + // __ get_thread(result_reg->as_register_lo()); + __ mov(result_reg->as_register(), r15_thread); +#else __ get_thread(result_reg->as_register()); +#endif // _LP64 } diff --git a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.hpp b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.hpp index 5621a95a372..41747a1f4fe 100644 --- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.hpp +++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.hpp @@ -36,13 +36,20 @@ address float_constant(float f); address double_constant(double d); + bool is_literal_address(LIR_Address* addr); + + // When we need to use something other than rscratch1 use this + // method. + Address as_Address(LIR_Address* addr, Register tmp); + + public: void store_parameter(Register r, int offset_from_esp_in_words); void store_parameter(jint c, int offset_from_esp_in_words); void store_parameter(jobject c, int offset_from_esp_in_words); - enum { call_stub_size = 15, + enum { call_stub_size = NOT_LP64(15) LP64_ONLY(28), exception_handler_size = DEBUG_ONLY(1*K) NOT_DEBUG(175), - deopt_handler_size = 10 + deopt_handler_size = NOT_LP64(10) LP64_ONLY(17) }; diff --git a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp index d2f9e2d35b7..b8c29fb09a8 100644 --- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp @@ -77,7 +77,7 @@ LIR_Opr LIRGenerator::result_register_for(ValueType* type, bool callee) { switch (type->tag()) { case intTag: opr = FrameMap::rax_opr; break; case objectTag: opr = FrameMap::rax_oop_opr; break; - case longTag: opr = FrameMap::rax_rdx_long_opr; break; + case longTag: opr = FrameMap::long0_opr; break; case floatTag: opr = UseSSE >= 1 ? FrameMap::xmm0_float_opr : FrameMap::fpu0_float_opr; break; case doubleTag: opr = UseSSE >= 2 ? FrameMap::xmm0_double_opr : FrameMap::fpu0_double_opr; break; @@ -117,12 +117,14 @@ bool LIRGenerator::can_store_as_constant(Value v, BasicType type) const { bool LIRGenerator::can_inline_as_constant(Value v) const { + if (v->type()->tag() == longTag) return false; return v->type()->tag() != objectTag || (v->type()->is_constant() && v->type()->as_ObjectType()->constant_value()->is_null_object()); } bool LIRGenerator::can_inline_as_constant(LIR_Const* c) const { + if (c->type() == T_LONG) return false; return c->type() != T_OBJECT || c->as_jobject() == NULL; } @@ -155,6 +157,13 @@ LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_o addr = new LIR_Address(array_opr, offset_in_bytes + index_opr->as_jint() * elem_size, type); } else { +#ifdef _LP64 + if (index_opr->type() == T_INT) { + LIR_Opr tmp = new_register(T_LONG); + __ convert(Bytecodes::_i2l, index_opr, tmp); + index_opr = tmp; + } +#endif // _LP64 addr = new LIR_Address(array_opr, index_opr, LIR_Address::scale(type), @@ -164,7 +173,7 @@ LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_o // This store will need a precise card mark, so go ahead and // compute the full adddres instead of computing once for the // store and again for the card mark. - LIR_Opr tmp = new_register(T_INT); + LIR_Opr tmp = new_pointer_register(); __ leal(LIR_OprFact::address(addr), tmp); return new LIR_Address(tmp, 0, type); } else { @@ -174,9 +183,8 @@ LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_o void LIRGenerator::increment_counter(address counter, int step) { - LIR_Opr temp = new_register(T_INT); - LIR_Opr pointer = new_register(T_INT); - __ move(LIR_OprFact::intConst((int)counter), pointer); + LIR_Opr pointer = new_pointer_register(); + __ move(LIR_OprFact::intptrConst(counter), pointer); LIR_Address* addr = new LIR_Address(pointer, 0, T_INT); increment_counter(addr, step); } @@ -481,7 +489,7 @@ void LIRGenerator::do_ArithmeticOp_Long(ArithmeticOp* x) { left.load_item(); right.load_item(); - LIR_Opr reg = FrameMap::rax_rdx_long_opr; + LIR_Opr reg = FrameMap::long0_opr; arithmetic_op_long(x->op(), reg, left.result(), right.result(), NULL); LIR_Opr result = rlock_result(x); __ move(reg, result); @@ -690,10 +698,10 @@ void LIRGenerator::do_AttemptUpdate(Intrinsic* x) { LIRItem new_value (x->argument_at(2), this); // replace field with new_value if it matches cmp_value // compare value must be in rdx,eax (hi,lo); may be destroyed by cmpxchg8 instruction - cmp_value.load_item_force(FrameMap::rax_rdx_long_opr); + cmp_value.load_item_force(FrameMap::long0_opr); // new value must be in rcx,ebx (hi,lo) - new_value.load_item_force(FrameMap::rbx_rcx_long_opr); + new_value.load_item_force(FrameMap::long1_opr); // object pointer register is overwritten with field address obj.load_item(); @@ -720,7 +728,10 @@ void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) { LIRItem val (x->argument_at(3), this); // replace field with val if matches cmp assert(obj.type()->tag() == objectTag, "invalid type"); - assert(offset.type()->tag() == intTag, "invalid type"); + + // In 64bit the type can be long, sparc doesn't have this assert + // assert(offset.type()->tag() == intTag, "invalid type"); + assert(cmp.type()->tag() == type->tag(), "invalid type"); assert(val.type()->tag() == type->tag(), "invalid type"); @@ -735,8 +746,8 @@ void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) { cmp.load_item_force(FrameMap::rax_opr); val.load_item(); } else if (type == longType) { - cmp.load_item_force(FrameMap::rax_rdx_long_opr); - val.load_item_force(FrameMap::rbx_rcx_long_opr); + cmp.load_item_force(FrameMap::long0_opr); + val.load_item_force(FrameMap::long1_opr); } else { ShouldNotReachHere(); } @@ -833,12 +844,33 @@ void LIRGenerator::do_ArrayCopy(Intrinsic* x) { // operands for arraycopy must use fixed registers, otherwise // LinearScan will fail allocation (because arraycopy always needs a // call) + +#ifndef _LP64 src.load_item_force (FrameMap::rcx_oop_opr); src_pos.load_item_force (FrameMap::rdx_opr); dst.load_item_force (FrameMap::rax_oop_opr); dst_pos.load_item_force (FrameMap::rbx_opr); length.load_item_force (FrameMap::rdi_opr); LIR_Opr tmp = (FrameMap::rsi_opr); +#else + + // The java calling convention will give us enough registers + // so that on the stub side the args will be perfect already. + // On the other slow/special case side we call C and the arg + // positions are not similar enough to pick one as the best. + // Also because the java calling convention is a "shifted" version + // of the C convention we can process the java args trivially into C + // args without worry of overwriting during the xfer + + src.load_item_force (FrameMap::as_oop_opr(j_rarg0)); + src_pos.load_item_force (FrameMap::as_opr(j_rarg1)); + dst.load_item_force (FrameMap::as_oop_opr(j_rarg2)); + dst_pos.load_item_force (FrameMap::as_opr(j_rarg3)); + length.load_item_force (FrameMap::as_opr(j_rarg4)); + + LIR_Opr tmp = FrameMap::as_opr(j_rarg5); +#endif // LP64 + set_no_result(x); int flags; @@ -857,7 +889,7 @@ LIR_Opr fixed_register_for(BasicType type) { case T_FLOAT: return FrameMap::fpu0_float_opr; case T_DOUBLE: return FrameMap::fpu0_double_opr; case T_INT: return FrameMap::rax_opr; - case T_LONG: return FrameMap::rax_rdx_long_opr; + case T_LONG: return FrameMap::long0_opr; default: ShouldNotReachHere(); return LIR_OprFact::illegalOpr; } } @@ -1161,9 +1193,13 @@ void LIRGenerator::do_If(If* x) { LIR_Opr LIRGenerator::getThreadPointer() { +#ifdef _LP64 + return FrameMap::as_pointer_opr(r15_thread); +#else LIR_Opr result = new_register(T_INT); __ get_thread(result); return result; +#endif // } void LIRGenerator::trace_block_entry(BlockBegin* block) { diff --git a/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.hpp b/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.hpp index cdfa446daa2..73510cd5525 100644 --- a/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.hpp +++ b/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.hpp @@ -23,18 +23,29 @@ */ inline bool LinearScan::is_processed_reg_num(int reg_num) { +#ifndef _LP64 // rsp and rbp (numbers 6 ancd 7) are ignored assert(FrameMap::rsp_opr->cpu_regnr() == 6, "wrong assumption below"); assert(FrameMap::rbp_opr->cpu_regnr() == 7, "wrong assumption below"); assert(reg_num >= 0, "invalid reg_num"); return reg_num < 6 || reg_num > 7; +#else + // rsp and rbp, r10, r15 (numbers 6 ancd 7) are ignored + assert(FrameMap::r10_opr->cpu_regnr() == 12, "wrong assumption below"); + assert(FrameMap::r15_opr->cpu_regnr() == 13, "wrong assumption below"); + assert(FrameMap::rsp_opr->cpu_regnrLo() == 14, "wrong assumption below"); + assert(FrameMap::rbp_opr->cpu_regnrLo() == 15, "wrong assumption below"); + assert(reg_num >= 0, "invalid reg_num"); + + return reg_num < 12 || reg_num > 15; +#endif // _LP64 } inline int LinearScan::num_physical_regs(BasicType type) { // Intel requires two cpu registers for long, // but requires only one fpu register for double - if (type == T_LONG) { + if (LP64_ONLY(false &&) type == T_LONG) { return 2; } return 1; diff --git a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp index 27024aa8a4b..8af0ceeb89a 100644 --- a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp @@ -26,18 +26,17 @@ #include "incls/_c1_MacroAssembler_x86.cpp.incl" int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Register scratch, Label& slow_case) { - const int aligned_mask = 3; + const int aligned_mask = BytesPerWord -1; const int hdr_offset = oopDesc::mark_offset_in_bytes(); assert(hdr == rax, "hdr must be rax, for the cmpxchg instruction"); assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different"); - assert(BytesPerWord == 4, "adjust aligned_mask and code"); Label done; int null_check_offset = -1; verify_oop(obj); // save object being locked into the BasicObjectLock - movl(Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()), obj); + movptr(Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()), obj); if (UseBiasedLocking) { assert(scratch != noreg, "should have scratch register at this point"); @@ -47,16 +46,16 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr } // Load object header - movl(hdr, Address(obj, hdr_offset)); + movptr(hdr, Address(obj, hdr_offset)); // and mark it as unlocked - orl(hdr, markOopDesc::unlocked_value); + orptr(hdr, markOopDesc::unlocked_value); // save unlocked object header into the displaced header location on the stack - movl(Address(disp_hdr, 0), hdr); + movptr(Address(disp_hdr, 0), hdr); // test if object header is still the same (i.e. unlocked), and if so, store the // displaced header address in the object header - if it is not the same, get the // object header instead if (os::is_MP()) MacroAssembler::lock(); // must be immediately before cmpxchg! - cmpxchg(disp_hdr, Address(obj, hdr_offset)); + cmpxchgptr(disp_hdr, Address(obj, hdr_offset)); // if the object header was the same, we're done if (PrintBiasedLockingStatistics) { cond_inc32(Assembler::equal, @@ -76,11 +75,11 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr // // assuming both the stack pointer and page_size have their least // significant 2 bits cleared and page_size is a power of 2 - subl(hdr, rsp); - andl(hdr, aligned_mask - os::vm_page_size()); + subptr(hdr, rsp); + andptr(hdr, aligned_mask - os::vm_page_size()); // for recursive locking, the result is zero => save it in the displaced header // location (NULL in the displaced hdr location indicates recursive locking) - movl(Address(disp_hdr, 0), hdr); + movptr(Address(disp_hdr, 0), hdr); // otherwise we don't care about the result and handle locking via runtime call jcc(Assembler::notZero, slow_case); // done @@ -90,35 +89,34 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) { - const int aligned_mask = 3; + const int aligned_mask = BytesPerWord -1; const int hdr_offset = oopDesc::mark_offset_in_bytes(); assert(disp_hdr == rax, "disp_hdr must be rax, for the cmpxchg instruction"); assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different"); - assert(BytesPerWord == 4, "adjust aligned_mask and code"); Label done; if (UseBiasedLocking) { // load object - movl(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes())); + movptr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes())); biased_locking_exit(obj, hdr, done); } // load displaced header - movl(hdr, Address(disp_hdr, 0)); + movptr(hdr, Address(disp_hdr, 0)); // if the loaded hdr is NULL we had recursive locking - testl(hdr, hdr); + testptr(hdr, hdr); // if we had recursive locking, we are done jcc(Assembler::zero, done); if (!UseBiasedLocking) { // load object - movl(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes())); + movptr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes())); } verify_oop(obj); // test if object header is pointing to the displaced header, and if so, restore // the displaced header in the object - if the object header is not pointing to // the displaced header, get the object header instead if (os::is_MP()) MacroAssembler::lock(); // must be immediately before cmpxchg! - cmpxchg(hdr, Address(obj, hdr_offset)); + cmpxchgptr(hdr, Address(obj, hdr_offset)); // if the object header was not pointing to the displaced header, // we do unlocking via runtime call jcc(Assembler::notEqual, slow_case); @@ -141,13 +139,14 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register assert_different_registers(obj, klass, len); if (UseBiasedLocking && !len->is_valid()) { assert_different_registers(obj, klass, len, t1, t2); - movl(t1, Address(klass, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); - movl(Address(obj, oopDesc::mark_offset_in_bytes()), t1); + movptr(t1, Address(klass, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + movptr(Address(obj, oopDesc::mark_offset_in_bytes()), t1); } else { - movl(Address(obj, oopDesc::mark_offset_in_bytes ()), (int)markOopDesc::prototype()); + // This assumes that all prototype bits fit in an int32_t + movptr(Address(obj, oopDesc::mark_offset_in_bytes ()), (int32_t)(intptr_t)markOopDesc::prototype()); } - movl(Address(obj, oopDesc::klass_offset_in_bytes()), klass); + movptr(Address(obj, oopDesc::klass_offset_in_bytes()), klass); if (len->is_valid()) { movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len); } @@ -160,25 +159,27 @@ void C1_MacroAssembler::initialize_body(Register obj, Register len_in_bytes, int assert(obj != len_in_bytes && obj != t1 && t1 != len_in_bytes, "registers must be different"); assert((hdr_size_in_bytes & (BytesPerWord - 1)) == 0, "header size is not a multiple of BytesPerWord"); Register index = len_in_bytes; - subl(index, hdr_size_in_bytes); + // index is positive and ptr sized + subptr(index, hdr_size_in_bytes); jcc(Assembler::zero, done); // initialize topmost word, divide index by 2, check if odd and test if zero // note: for the remaining code to work, index must be a multiple of BytesPerWord #ifdef ASSERT { Label L; - testl(index, BytesPerWord - 1); + testptr(index, BytesPerWord - 1); jcc(Assembler::zero, L); stop("index is not a multiple of BytesPerWord"); bind(L); } #endif - xorl(t1, t1); // use _zero reg to clear memory (shorter code) + xorptr(t1, t1); // use _zero reg to clear memory (shorter code) if (UseIncDec) { - shrl(index, 3); // divide by 8 and set carry flag if bit 2 was set + shrptr(index, 3); // divide by 8/16 and set carry flag if bit 2 was set } else { - shrl(index, 2); // use 2 instructions to avoid partial flag stall - shrl(index, 1); + shrptr(index, 2); // use 2 instructions to avoid partial flag stall + shrptr(index, 1); } +#ifndef _LP64 // index could have been not a multiple of 8 (i.e., bit 2 was set) { Label even; // note: if index was a multiple of 8, than it cannot @@ -186,16 +187,17 @@ void C1_MacroAssembler::initialize_body(Register obj, Register len_in_bytes, int // => if it is even, we don't need to check for 0 again jcc(Assembler::carryClear, even); // clear topmost word (no jump needed if conditional assignment would work here) - movl(Address(obj, index, Address::times_8, hdr_size_in_bytes - 0*BytesPerWord), t1); + movptr(Address(obj, index, Address::times_8, hdr_size_in_bytes - 0*BytesPerWord), t1); // index could be 0 now, need to check again jcc(Assembler::zero, done); bind(even); } +#endif // !_LP64 // initialize remaining object fields: rdx is a multiple of 2 now { Label loop; bind(loop); - movl(Address(obj, index, Address::times_8, hdr_size_in_bytes - 1*BytesPerWord), t1); - movl(Address(obj, index, Address::times_8, hdr_size_in_bytes - 2*BytesPerWord), t1); + movptr(Address(obj, index, Address::times_8, hdr_size_in_bytes - 1*BytesPerWord), t1); + NOT_LP64(movptr(Address(obj, index, Address::times_8, hdr_size_in_bytes - 2*BytesPerWord), t1);) decrement(index); jcc(Assembler::notZero, loop); } @@ -227,30 +229,30 @@ void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register const Register index = t2; const int threshold = 6 * BytesPerWord; // approximate break even point for code size (see comments below) if (var_size_in_bytes != noreg) { - movl(index, var_size_in_bytes); + mov(index, var_size_in_bytes); initialize_body(obj, index, hdr_size_in_bytes, t1_zero); } else if (con_size_in_bytes <= threshold) { // use explicit null stores // code size = 2 + 3*n bytes (n = number of fields to clear) - xorl(t1_zero, t1_zero); // use t1_zero reg to clear memory (shorter code) + xorptr(t1_zero, t1_zero); // use t1_zero reg to clear memory (shorter code) for (int i = hdr_size_in_bytes; i < con_size_in_bytes; i += BytesPerWord) - movl(Address(obj, i), t1_zero); + movptr(Address(obj, i), t1_zero); } else if (con_size_in_bytes > hdr_size_in_bytes) { // use loop to null out the fields // code size = 16 bytes for even n (n = number of fields to clear) // initialize last object field first if odd number of fields - xorl(t1_zero, t1_zero); // use t1_zero reg to clear memory (shorter code) - movl(index, (con_size_in_bytes - hdr_size_in_bytes) >> 3); + xorptr(t1_zero, t1_zero); // use t1_zero reg to clear memory (shorter code) + movptr(index, (con_size_in_bytes - hdr_size_in_bytes) >> 3); // initialize last object field if constant size is odd if (((con_size_in_bytes - hdr_size_in_bytes) & 4) != 0) - movl(Address(obj, con_size_in_bytes - (1*BytesPerWord)), t1_zero); + movptr(Address(obj, con_size_in_bytes - (1*BytesPerWord)), t1_zero); // initialize remaining object fields: rdx is a multiple of 2 { Label loop; bind(loop); - movl(Address(obj, index, Address::times_8, - hdr_size_in_bytes - (1*BytesPerWord)), t1_zero); - movl(Address(obj, index, Address::times_8, - hdr_size_in_bytes - (2*BytesPerWord)), t1_zero); + movptr(Address(obj, index, Address::times_8, hdr_size_in_bytes - (1*BytesPerWord)), + t1_zero); + NOT_LP64(movptr(Address(obj, index, Address::times_8, hdr_size_in_bytes - (2*BytesPerWord)), + t1_zero);) decrement(index); jcc(Assembler::notZero, loop); } @@ -269,17 +271,17 @@ void C1_MacroAssembler::allocate_array(Register obj, Register len, Register t1, assert_different_registers(obj, len, t1, t2, klass); // determine alignment mask - assert(BytesPerWord == 4, "must be a multiple of 2 for masking code to work"); + assert(!(BytesPerWord & 1), "must be a multiple of 2 for masking code to work"); // check for negative or excessive length - cmpl(len, max_array_allocation_length); + cmpptr(len, (int32_t)max_array_allocation_length); jcc(Assembler::above, slow_case); const Register arr_size = t2; // okay to be the same // align object end - movl(arr_size, header_size * BytesPerWord + MinObjAlignmentInBytesMask); - leal(arr_size, Address(arr_size, len, f)); - andl(arr_size, ~MinObjAlignmentInBytesMask); + movptr(arr_size, (int32_t)header_size * BytesPerWord + MinObjAlignmentInBytesMask); + lea(arr_size, Address(arr_size, len, f)); + andptr(arr_size, ~MinObjAlignmentInBytesMask); try_allocate(obj, arr_size, 0, t1, t2, slow_case); @@ -305,12 +307,13 @@ void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) { // check against inline cache assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check"); int start_offset = offset(); - cmpl(iCache, Address(receiver, oopDesc::klass_offset_in_bytes())); + cmpptr(iCache, Address(receiver, oopDesc::klass_offset_in_bytes())); // if icache check fails, then jump to runtime routine // Note: RECEIVER must still contain the receiver! jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); - assert(offset() - start_offset == 9, "check alignment in emit_method_entry"); + const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9); + assert(offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry"); } @@ -364,7 +367,7 @@ void C1_MacroAssembler::verify_stack_oop(int stack_offset) { void C1_MacroAssembler::verify_not_null_oop(Register r) { if (!VerifyOops) return; Label not_null; - testl(r, r); + testptr(r, r); jcc(Assembler::notZero, not_null); stop("non-null oop required"); bind(not_null); @@ -373,12 +376,12 @@ void C1_MacroAssembler::verify_not_null_oop(Register r) { void C1_MacroAssembler::invalidate_registers(bool inv_rax, bool inv_rbx, bool inv_rcx, bool inv_rdx, bool inv_rsi, bool inv_rdi) { #ifdef ASSERT - if (inv_rax) movl(rax, 0xDEAD); - if (inv_rbx) movl(rbx, 0xDEAD); - if (inv_rcx) movl(rcx, 0xDEAD); - if (inv_rdx) movl(rdx, 0xDEAD); - if (inv_rsi) movl(rsi, 0xDEAD); - if (inv_rdi) movl(rdi, 0xDEAD); + if (inv_rax) movptr(rax, 0xDEAD); + if (inv_rbx) movptr(rbx, 0xDEAD); + if (inv_rcx) movptr(rcx, 0xDEAD); + if (inv_rdx) movptr(rdx, 0xDEAD); + if (inv_rsi) movptr(rsi, 0xDEAD); + if (inv_rdi) movptr(rdi, 0xDEAD); #endif } diff --git a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.hpp b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.hpp index 62f6d4c14a8..d0b4230ad52 100644 --- a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.hpp +++ b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.hpp @@ -94,16 +94,17 @@ // Note: NEVER push values directly, but only through following push_xxx functions; // This helps us to track the rsp changes compared to the entry rsp (->_rsp_offset) - void push_jint (jint i) { _rsp_offset++; pushl(i); } + void push_jint (jint i) { _rsp_offset++; push(i); } void push_oop (jobject o) { _rsp_offset++; pushoop(o); } - void push_addr (Address a) { _rsp_offset++; pushl(a); } - void push_reg (Register r) { _rsp_offset++; pushl(r); } - void pop (Register r) { _rsp_offset--; popl (r); assert(_rsp_offset >= 0, "stack offset underflow"); } + // Seems to always be in wordSize + void push_addr (Address a) { _rsp_offset++; pushptr(a); } + void push_reg (Register r) { _rsp_offset++; push(r); } + void pop_reg (Register r) { _rsp_offset--; pop(r); assert(_rsp_offset >= 0, "stack offset underflow"); } void dec_stack (int nof_words) { _rsp_offset -= nof_words; assert(_rsp_offset >= 0, "stack offset underflow"); - addl(rsp, wordSize * nof_words); + addptr(rsp, wordSize * nof_words); } void dec_stack_after_call (int nof_words) { diff --git a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp index be73c79365b..01a232149c7 100644 --- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp @@ -30,52 +30,58 @@ int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, int args_size) { // setup registers - const Register thread = rdi; // is callee-saved register (Visual C++ calling conventions) + const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); // is callee-saved register (Visual C++ calling conventions) assert(!(oop_result1->is_valid() || oop_result2->is_valid()) || oop_result1 != oop_result2, "registers must be different"); assert(oop_result1 != thread && oop_result2 != thread, "registers must be different"); assert(args_size >= 0, "illegal args_size"); +#ifdef _LP64 + mov(c_rarg0, thread); + set_num_rt_args(0); // Nothing on stack +#else set_num_rt_args(1 + args_size); // push java thread (becomes first argument of C function) get_thread(thread); - pushl(thread); + push(thread); +#endif // _LP64 set_last_Java_frame(thread, noreg, rbp, NULL); + // do the call call(RuntimeAddress(entry)); int call_offset = offset(); // verify callee-saved register #ifdef ASSERT guarantee(thread != rax, "change this code"); - pushl(rax); + push(rax); { Label L; get_thread(rax); - cmpl(thread, rax); + cmpptr(thread, rax); jcc(Assembler::equal, L); int3(); stop("StubAssembler::call_RT: rdi not callee saved?"); bind(L); } - popl(rax); + pop(rax); #endif reset_last_Java_frame(thread, true, false); // discard thread and arguments - addl(rsp, (1 + args_size)*BytesPerWord); + NOT_LP64(addptr(rsp, num_rt_args()*BytesPerWord)); // check for pending exceptions { Label L; - cmpl(Address(thread, Thread::pending_exception_offset()), NULL_WORD); + cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); jcc(Assembler::equal, L); // exception pending => remove activation and forward to exception handler - movl(rax, Address(thread, Thread::pending_exception_offset())); + movptr(rax, Address(thread, Thread::pending_exception_offset())); // make sure that the vm_results are cleared if (oop_result1->is_valid()) { - movl(Address(thread, JavaThread::vm_result_offset()), NULL_WORD); + movptr(Address(thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD); } if (oop_result2->is_valid()) { - movl(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD); + movptr(Address(thread, JavaThread::vm_result_2_offset()), (int32_t)NULL_WORD); } if (frame_size() == no_frame_size) { leave(); @@ -89,13 +95,13 @@ int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address e } // get oop results if there are any and reset the values in the thread if (oop_result1->is_valid()) { - movl(oop_result1, Address(thread, JavaThread::vm_result_offset())); - movl(Address(thread, JavaThread::vm_result_offset()), NULL_WORD); + movptr(oop_result1, Address(thread, JavaThread::vm_result_offset())); + movptr(Address(thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD); verify_oop(oop_result1); } if (oop_result2->is_valid()) { - movl(oop_result2, Address(thread, JavaThread::vm_result_2_offset())); - movl(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD); + movptr(oop_result2, Address(thread, JavaThread::vm_result_2_offset())); + movptr(Address(thread, JavaThread::vm_result_2_offset()), (int32_t)NULL_WORD); verify_oop(oop_result2); } return call_offset; @@ -103,22 +109,58 @@ int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address e int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1) { - pushl(arg1); +#ifdef _LP64 + mov(c_rarg1, arg1); +#else + push(arg1); +#endif // _LP64 return call_RT(oop_result1, oop_result2, entry, 1); } int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1, Register arg2) { - pushl(arg2); - pushl(arg1); +#ifdef _LP64 + if (c_rarg1 == arg2) { + if (c_rarg2 == arg1) { + xchgq(arg1, arg2); + } else { + mov(c_rarg2, arg2); + mov(c_rarg1, arg1); + } + } else { + mov(c_rarg1, arg1); + mov(c_rarg2, arg2); + } +#else + push(arg2); + push(arg1); +#endif // _LP64 return call_RT(oop_result1, oop_result2, entry, 2); } int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1, Register arg2, Register arg3) { - pushl(arg3); - pushl(arg2); - pushl(arg1); +#ifdef _LP64 + // if there is any conflict use the stack + if (arg1 == c_rarg2 || arg1 == c_rarg3 || + arg2 == c_rarg1 || arg1 == c_rarg3 || + arg3 == c_rarg1 || arg1 == c_rarg2) { + push(arg3); + push(arg2); + push(arg1); + pop(c_rarg1); + pop(c_rarg2); + pop(c_rarg3); + } else { + mov(c_rarg1, arg1); + mov(c_rarg2, arg2); + mov(c_rarg3, arg3); + } +#else + push(arg3); + push(arg2); + push(arg1); +#endif // _LP64 return call_RT(oop_result1, oop_result2, entry, 3); } @@ -154,7 +196,7 @@ void StubFrame::load_argument(int offset_in_words, Register reg) { // + 3: argument with offset 1 // + 4: ... - __ movl(reg, Address(rbp, (offset_in_words + 2) * BytesPerWord)); + __ movptr(reg, Address(rbp, (offset_in_words + 2) * BytesPerWord)); } @@ -170,8 +212,8 @@ StubFrame::~StubFrame() { #define __ sasm-> -const int float_regs_as_doubles_size_in_words = 16; -const int xmm_regs_as_doubles_size_in_words = 16; +const int float_regs_as_doubles_size_in_slots = pd_nof_fpu_regs_frame_map * 2; +const int xmm_regs_as_doubles_size_in_slots = FrameMap::nof_xmm_regs * 2; // Stack layout for saving/restoring all the registers needed during a runtime // call (this includes deoptimization) @@ -180,29 +222,61 @@ const int xmm_regs_as_doubles_size_in_words = 16; // but the code in save_live_registers will take the argument count into // account. // +#ifdef _LP64 + #define SLOT2(x) x, + #define SLOT_PER_WORD 2 +#else + #define SLOT2(x) + #define SLOT_PER_WORD 1 +#endif // _LP64 + enum reg_save_layout { - dummy1, - dummy2, + // 64bit needs to keep stack 16 byte aligned. So we add some alignment dummies to make that + // happen and will assert if the stack size we create is misaligned +#ifdef _LP64 + align_dummy_0, align_dummy_1, +#endif // _LP64 + dummy1, SLOT2(dummy1H) // 0, 4 + dummy2, SLOT2(dummy2H) // 8, 12 // Two temps to be used as needed by users of save/restore callee registers - temp_2_off, - temp_1_off, - xmm_regs_as_doubles_off, - float_regs_as_doubles_off = xmm_regs_as_doubles_off + xmm_regs_as_doubles_size_in_words, - fpu_state_off = float_regs_as_doubles_off + float_regs_as_doubles_size_in_words, - fpu_state_end_off = fpu_state_off + FPUStateSizeInWords, - marker = fpu_state_end_off, - extra_space_offset, + temp_2_off, SLOT2(temp_2H_off) // 16, 20 + temp_1_off, SLOT2(temp_1H_off) // 24, 28 + xmm_regs_as_doubles_off, // 32 + float_regs_as_doubles_off = xmm_regs_as_doubles_off + xmm_regs_as_doubles_size_in_slots, // 160 + fpu_state_off = float_regs_as_doubles_off + float_regs_as_doubles_size_in_slots, // 224 + // fpu_state_end_off is exclusive + fpu_state_end_off = fpu_state_off + (FPUStateSizeInWords / SLOT_PER_WORD), // 352 + marker = fpu_state_end_off, SLOT2(markerH) // 352, 356 + extra_space_offset, // 360 +#ifdef _LP64 + r15_off = extra_space_offset, r15H_off, // 360, 364 + r14_off, r14H_off, // 368, 372 + r13_off, r13H_off, // 376, 380 + r12_off, r12H_off, // 384, 388 + r11_off, r11H_off, // 392, 396 + r10_off, r10H_off, // 400, 404 + r9_off, r9H_off, // 408, 412 + r8_off, r8H_off, // 416, 420 + rdi_off, rdiH_off, // 424, 428 +#else rdi_off = extra_space_offset, - rsi_off, - rbp_off, - rsp_off, - rbx_off, - rdx_off, - rcx_off, - rax_off, - saved_rbp_off, - return_off, - reg_save_frame_size, // As noted: neglects any parameters to runtime +#endif // _LP64 + rsi_off, SLOT2(rsiH_off) // 432, 436 + rbp_off, SLOT2(rbpH_off) // 440, 444 + rsp_off, SLOT2(rspH_off) // 448, 452 + rbx_off, SLOT2(rbxH_off) // 456, 460 + rdx_off, SLOT2(rdxH_off) // 464, 468 + rcx_off, SLOT2(rcxH_off) // 472, 476 + rax_off, SLOT2(raxH_off) // 480, 484 + saved_rbp_off, SLOT2(saved_rbpH_off) // 488, 492 + return_off, SLOT2(returnH_off) // 496, 500 + reg_save_frame_size, // As noted: neglects any parameters to runtime // 504 + +#ifdef _WIN64 + c_rarg0_off = rcx_off, +#else + c_rarg0_off = rdi_off, +#endif // WIN64 // equates @@ -229,18 +303,49 @@ enum reg_save_layout { static OopMap* generate_oop_map(StubAssembler* sasm, int num_rt_args, bool save_fpu_registers = true) { - int frame_size = reg_save_frame_size + num_rt_args; // args + thread - sasm->set_frame_size(frame_size); + + // In 64bit all the args are in regs so there are no additional stack slots + LP64_ONLY(num_rt_args = 0); + LP64_ONLY(assert((reg_save_frame_size * VMRegImpl::stack_slot_size) % 16 == 0, "must be 16 byte aligned");) + int frame_size_in_slots = reg_save_frame_size + num_rt_args; // args + thread + sasm->set_frame_size(frame_size_in_slots / VMRegImpl::slots_per_word ); // record saved value locations in an OopMap // locations are offsets from sp after runtime call; num_rt_args is number of arguments in call, including thread - OopMap* map = new OopMap(frame_size, 0); + OopMap* map = new OopMap(frame_size_in_slots, 0); map->set_callee_saved(VMRegImpl::stack2reg(rax_off + num_rt_args), rax->as_VMReg()); map->set_callee_saved(VMRegImpl::stack2reg(rcx_off + num_rt_args), rcx->as_VMReg()); map->set_callee_saved(VMRegImpl::stack2reg(rdx_off + num_rt_args), rdx->as_VMReg()); map->set_callee_saved(VMRegImpl::stack2reg(rbx_off + num_rt_args), rbx->as_VMReg()); map->set_callee_saved(VMRegImpl::stack2reg(rsi_off + num_rt_args), rsi->as_VMReg()); map->set_callee_saved(VMRegImpl::stack2reg(rdi_off + num_rt_args), rdi->as_VMReg()); +#ifdef _LP64 + map->set_callee_saved(VMRegImpl::stack2reg(r8_off + num_rt_args), r8->as_VMReg()); + map->set_callee_saved(VMRegImpl::stack2reg(r9_off + num_rt_args), r9->as_VMReg()); + map->set_callee_saved(VMRegImpl::stack2reg(r10_off + num_rt_args), r10->as_VMReg()); + map->set_callee_saved(VMRegImpl::stack2reg(r11_off + num_rt_args), r11->as_VMReg()); + map->set_callee_saved(VMRegImpl::stack2reg(r12_off + num_rt_args), r12->as_VMReg()); + map->set_callee_saved(VMRegImpl::stack2reg(r13_off + num_rt_args), r13->as_VMReg()); + map->set_callee_saved(VMRegImpl::stack2reg(r14_off + num_rt_args), r14->as_VMReg()); + map->set_callee_saved(VMRegImpl::stack2reg(r15_off + num_rt_args), r15->as_VMReg()); + + // This is stupid but needed. + map->set_callee_saved(VMRegImpl::stack2reg(raxH_off + num_rt_args), rax->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(rcxH_off + num_rt_args), rcx->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(rdxH_off + num_rt_args), rdx->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(rbxH_off + num_rt_args), rbx->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(rsiH_off + num_rt_args), rsi->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(rdiH_off + num_rt_args), rdi->as_VMReg()->next()); + + map->set_callee_saved(VMRegImpl::stack2reg(r8H_off + num_rt_args), r8->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(r9H_off + num_rt_args), r9->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(r10H_off + num_rt_args), r10->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(r11H_off + num_rt_args), r11->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(r12H_off + num_rt_args), r12->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(r13H_off + num_rt_args), r13->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(r14H_off + num_rt_args), r14->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(r15H_off + num_rt_args), r15->as_VMReg()->next()); +#endif // _LP64 if (save_fpu_registers) { if (UseSSE < 2) { @@ -288,30 +393,31 @@ static OopMap* save_live_registers(StubAssembler* sasm, int num_rt_args, bool save_fpu_registers = true) { __ block_comment("save_live_registers"); - int frame_size = reg_save_frame_size + num_rt_args; // args + thread + // 64bit passes the args in regs to the c++ runtime + int frame_size_in_slots = reg_save_frame_size NOT_LP64(+ num_rt_args); // args + thread // frame_size = round_to(frame_size, 4); - sasm->set_frame_size(frame_size); + sasm->set_frame_size(frame_size_in_slots / VMRegImpl::slots_per_word ); - __ pushad(); // integer registers + __ pusha(); // integer registers // assert(float_regs_as_doubles_off % 2 == 0, "misaligned offset"); // assert(xmm_regs_as_doubles_off % 2 == 0, "misaligned offset"); - __ subl(rsp, extra_space_offset * wordSize); + __ subptr(rsp, extra_space_offset * VMRegImpl::stack_slot_size); #ifdef ASSERT - __ movl(Address(rsp, marker * wordSize), 0xfeedbeef); + __ movptr(Address(rsp, marker * VMRegImpl::stack_slot_size), (int32_t)0xfeedbeef); #endif if (save_fpu_registers) { if (UseSSE < 2) { // save FPU stack - __ fnsave(Address(rsp, fpu_state_off * wordSize)); + __ fnsave(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size)); __ fwait(); #ifdef ASSERT Label ok; - __ cmpw(Address(rsp, fpu_state_off * wordSize), StubRoutines::fpu_cntrl_wrd_std()); + __ cmpw(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size), StubRoutines::fpu_cntrl_wrd_std()); __ jccb(Assembler::equal, ok); __ stop("corrupted control word detected"); __ bind(ok); @@ -321,18 +427,18 @@ static OopMap* save_live_registers(StubAssembler* sasm, int num_rt_args, // since fstp_d can cause FPU stack underflow exceptions. Write it // into the on stack copy and then reload that to make sure that the // current and future values are correct. - __ movw(Address(rsp, fpu_state_off * wordSize), StubRoutines::fpu_cntrl_wrd_std()); - __ frstor(Address(rsp, fpu_state_off * wordSize)); + __ movw(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size), StubRoutines::fpu_cntrl_wrd_std()); + __ frstor(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size)); // Save the FPU registers in de-opt-able form - __ fstp_d(Address(rsp, float_regs_as_doubles_off * BytesPerWord + 0)); - __ fstp_d(Address(rsp, float_regs_as_doubles_off * BytesPerWord + 8)); - __ fstp_d(Address(rsp, float_regs_as_doubles_off * BytesPerWord + 16)); - __ fstp_d(Address(rsp, float_regs_as_doubles_off * BytesPerWord + 24)); - __ fstp_d(Address(rsp, float_regs_as_doubles_off * BytesPerWord + 32)); - __ fstp_d(Address(rsp, float_regs_as_doubles_off * BytesPerWord + 40)); - __ fstp_d(Address(rsp, float_regs_as_doubles_off * BytesPerWord + 48)); - __ fstp_d(Address(rsp, float_regs_as_doubles_off * BytesPerWord + 56)); + __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 0)); + __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 8)); + __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 16)); + __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 24)); + __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 32)); + __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 40)); + __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 48)); + __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 56)); } if (UseSSE >= 2) { @@ -341,24 +447,34 @@ static OopMap* save_live_registers(StubAssembler* sasm, int num_rt_args, // so always save them as doubles. // note that float values are _not_ converted automatically, so for float values // the second word contains only garbage data. - __ movdbl(Address(rsp, xmm_regs_as_doubles_off * wordSize + 0), xmm0); - __ movdbl(Address(rsp, xmm_regs_as_doubles_off * wordSize + 8), xmm1); - __ movdbl(Address(rsp, xmm_regs_as_doubles_off * wordSize + 16), xmm2); - __ movdbl(Address(rsp, xmm_regs_as_doubles_off * wordSize + 24), xmm3); - __ movdbl(Address(rsp, xmm_regs_as_doubles_off * wordSize + 32), xmm4); - __ movdbl(Address(rsp, xmm_regs_as_doubles_off * wordSize + 40), xmm5); - __ movdbl(Address(rsp, xmm_regs_as_doubles_off * wordSize + 48), xmm6); - __ movdbl(Address(rsp, xmm_regs_as_doubles_off * wordSize + 56), xmm7); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 0), xmm0); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 8), xmm1); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 16), xmm2); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 24), xmm3); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 32), xmm4); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 40), xmm5); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 48), xmm6); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 56), xmm7); +#ifdef _LP64 + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 64), xmm8); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 72), xmm9); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 80), xmm10); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 88), xmm11); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 96), xmm12); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 104), xmm13); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 112), xmm14); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 120), xmm15); +#endif // _LP64 } else if (UseSSE == 1) { // save XMM registers as float because double not supported without SSE2 - __ movflt(Address(rsp, xmm_regs_as_doubles_off * wordSize + 0), xmm0); - __ movflt(Address(rsp, xmm_regs_as_doubles_off * wordSize + 8), xmm1); - __ movflt(Address(rsp, xmm_regs_as_doubles_off * wordSize + 16), xmm2); - __ movflt(Address(rsp, xmm_regs_as_doubles_off * wordSize + 24), xmm3); - __ movflt(Address(rsp, xmm_regs_as_doubles_off * wordSize + 32), xmm4); - __ movflt(Address(rsp, xmm_regs_as_doubles_off * wordSize + 40), xmm5); - __ movflt(Address(rsp, xmm_regs_as_doubles_off * wordSize + 48), xmm6); - __ movflt(Address(rsp, xmm_regs_as_doubles_off * wordSize + 56), xmm7); + __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 0), xmm0); + __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 8), xmm1); + __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 16), xmm2); + __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 24), xmm3); + __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 32), xmm4); + __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 40), xmm5); + __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 48), xmm6); + __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 56), xmm7); } } @@ -373,28 +489,38 @@ static void restore_fpu(StubAssembler* sasm, bool restore_fpu_registers = true) if (restore_fpu_registers) { if (UseSSE >= 2) { // restore XMM registers - __ movdbl(xmm0, Address(rsp, xmm_regs_as_doubles_off * wordSize + 0)); - __ movdbl(xmm1, Address(rsp, xmm_regs_as_doubles_off * wordSize + 8)); - __ movdbl(xmm2, Address(rsp, xmm_regs_as_doubles_off * wordSize + 16)); - __ movdbl(xmm3, Address(rsp, xmm_regs_as_doubles_off * wordSize + 24)); - __ movdbl(xmm4, Address(rsp, xmm_regs_as_doubles_off * wordSize + 32)); - __ movdbl(xmm5, Address(rsp, xmm_regs_as_doubles_off * wordSize + 40)); - __ movdbl(xmm6, Address(rsp, xmm_regs_as_doubles_off * wordSize + 48)); - __ movdbl(xmm7, Address(rsp, xmm_regs_as_doubles_off * wordSize + 56)); + __ movdbl(xmm0, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 0)); + __ movdbl(xmm1, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 8)); + __ movdbl(xmm2, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 16)); + __ movdbl(xmm3, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 24)); + __ movdbl(xmm4, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 32)); + __ movdbl(xmm5, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 40)); + __ movdbl(xmm6, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 48)); + __ movdbl(xmm7, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 56)); +#ifdef _LP64 + __ movdbl(xmm8, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 64)); + __ movdbl(xmm9, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 72)); + __ movdbl(xmm10, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 80)); + __ movdbl(xmm11, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 88)); + __ movdbl(xmm12, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 96)); + __ movdbl(xmm13, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 104)); + __ movdbl(xmm14, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 112)); + __ movdbl(xmm15, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 120)); +#endif // _LP64 } else if (UseSSE == 1) { // restore XMM registers - __ movflt(xmm0, Address(rsp, xmm_regs_as_doubles_off * wordSize + 0)); - __ movflt(xmm1, Address(rsp, xmm_regs_as_doubles_off * wordSize + 8)); - __ movflt(xmm2, Address(rsp, xmm_regs_as_doubles_off * wordSize + 16)); - __ movflt(xmm3, Address(rsp, xmm_regs_as_doubles_off * wordSize + 24)); - __ movflt(xmm4, Address(rsp, xmm_regs_as_doubles_off * wordSize + 32)); - __ movflt(xmm5, Address(rsp, xmm_regs_as_doubles_off * wordSize + 40)); - __ movflt(xmm6, Address(rsp, xmm_regs_as_doubles_off * wordSize + 48)); - __ movflt(xmm7, Address(rsp, xmm_regs_as_doubles_off * wordSize + 56)); + __ movflt(xmm0, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 0)); + __ movflt(xmm1, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 8)); + __ movflt(xmm2, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 16)); + __ movflt(xmm3, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 24)); + __ movflt(xmm4, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 32)); + __ movflt(xmm5, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 40)); + __ movflt(xmm6, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 48)); + __ movflt(xmm7, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 56)); } if (UseSSE < 2) { - __ frstor(Address(rsp, fpu_state_off * wordSize)); + __ frstor(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size)); } else { // check that FPU stack is really empty __ verify_FPU(0, "restore_live_registers"); @@ -408,14 +534,14 @@ static void restore_fpu(StubAssembler* sasm, bool restore_fpu_registers = true) #ifdef ASSERT { Label ok; - __ cmpl(Address(rsp, marker * wordSize), 0xfeedbeef); + __ cmpptr(Address(rsp, marker * VMRegImpl::stack_slot_size), (int32_t)0xfeedbeef); __ jcc(Assembler::equal, ok); __ stop("bad offsets in frame"); __ bind(ok); } -#endif +#endif // ASSERT - __ addl(rsp, extra_space_offset * wordSize); + __ addptr(rsp, extra_space_offset * VMRegImpl::stack_slot_size); } @@ -423,7 +549,7 @@ static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registe __ block_comment("restore_live_registers"); restore_fpu(sasm, restore_fpu_registers); - __ popad(); + __ popa(); } @@ -432,14 +558,35 @@ static void restore_live_registers_except_rax(StubAssembler* sasm, bool restore_ restore_fpu(sasm, restore_fpu_registers); - __ popl(rdi); - __ popl(rsi); - __ popl(rbp); - __ popl(rbx); // skip this value - __ popl(rbx); - __ popl(rdx); - __ popl(rcx); - __ addl(rsp, 4); +#ifdef _LP64 + __ movptr(r15, Address(rsp, 0)); + __ movptr(r14, Address(rsp, wordSize)); + __ movptr(r13, Address(rsp, 2 * wordSize)); + __ movptr(r12, Address(rsp, 3 * wordSize)); + __ movptr(r11, Address(rsp, 4 * wordSize)); + __ movptr(r10, Address(rsp, 5 * wordSize)); + __ movptr(r9, Address(rsp, 6 * wordSize)); + __ movptr(r8, Address(rsp, 7 * wordSize)); + __ movptr(rdi, Address(rsp, 8 * wordSize)); + __ movptr(rsi, Address(rsp, 9 * wordSize)); + __ movptr(rbp, Address(rsp, 10 * wordSize)); + // skip rsp + __ movptr(rbx, Address(rsp, 12 * wordSize)); + __ movptr(rdx, Address(rsp, 13 * wordSize)); + __ movptr(rcx, Address(rsp, 14 * wordSize)); + + __ addptr(rsp, 16 * wordSize); +#else + + __ pop(rdi); + __ pop(rsi); + __ pop(rbp); + __ pop(rbx); // skip this value + __ pop(rbx); + __ pop(rdx); + __ pop(rcx); + __ addptr(rsp, BytesPerWord); +#endif // _LP64 } @@ -465,10 +612,13 @@ OopMapSet* Runtime1::generate_exception_throw(StubAssembler* sasm, address targe // load argument for exception that is passed as an argument into the stub if (has_argument) { - __ movl(temp_reg, Address(rbp, 2*BytesPerWord)); - __ pushl(temp_reg); +#ifdef _LP64 + __ movptr(c_rarg1, Address(rbp, 2*BytesPerWord)); +#else + __ movptr(temp_reg, Address(rbp, 2*BytesPerWord)); + __ push(temp_reg); +#endif // _LP64 } - int call_offset = __ call_RT(noreg, noreg, target, num_rt_args - 1); OopMapSet* oop_maps = new OopMapSet(); @@ -486,7 +636,7 @@ void Runtime1::generate_handle_exception(StubAssembler *sasm, OopMapSet* oop_map const Register exception_pc = rdx; // other registers used in this stub const Register real_return_addr = rbx; - const Register thread = rdi; + const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); __ block_comment("generate_handle_exception"); @@ -503,19 +653,19 @@ void Runtime1::generate_handle_exception(StubAssembler *sasm, OopMapSet* oop_map __ verify_not_null_oop(exception_oop); // load address of JavaThread object for thread-local data - __ get_thread(thread); + NOT_LP64(__ get_thread(thread);) #ifdef ASSERT // check that fields in JavaThread for exception oop and issuing pc are // empty before writing to them Label oop_empty; - __ cmpl(Address(thread, JavaThread::exception_oop_offset()), 0); + __ cmpptr(Address(thread, JavaThread::exception_oop_offset()), (int32_t) NULL_WORD); __ jcc(Assembler::equal, oop_empty); __ stop("exception oop already set"); __ bind(oop_empty); Label pc_empty; - __ cmpl(Address(thread, JavaThread::exception_pc_offset()), 0); + __ cmpptr(Address(thread, JavaThread::exception_pc_offset()), 0); __ jcc(Assembler::equal, pc_empty); __ stop("exception pc already set"); __ bind(pc_empty); @@ -523,15 +673,15 @@ void Runtime1::generate_handle_exception(StubAssembler *sasm, OopMapSet* oop_map // save exception oop and issuing pc into JavaThread // (exception handler will load it from here) - __ movl(Address(thread, JavaThread::exception_oop_offset()), exception_oop); - __ movl(Address(thread, JavaThread::exception_pc_offset()), exception_pc); + __ movptr(Address(thread, JavaThread::exception_oop_offset()), exception_oop); + __ movptr(Address(thread, JavaThread::exception_pc_offset()), exception_pc); // save real return address (pc that called this stub) - __ movl(real_return_addr, Address(rbp, 1*BytesPerWord)); - __ movl(Address(rsp, temp_1_off * BytesPerWord), real_return_addr); + __ movptr(real_return_addr, Address(rbp, 1*BytesPerWord)); + __ movptr(Address(rsp, temp_1_off * VMRegImpl::stack_slot_size), real_return_addr); // patch throwing pc into return address (has bci & oop map) - __ movl(Address(rbp, 1*BytesPerWord), exception_pc); + __ movptr(Address(rbp, 1*BytesPerWord), exception_pc); // compute the exception handler. // the exception oop and the throwing pc are read from the fields in JavaThread @@ -548,12 +698,12 @@ void Runtime1::generate_handle_exception(StubAssembler *sasm, OopMapSet* oop_map // Do we have an exception handler in the nmethod? Label no_handler; Label done; - __ testl(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, no_handler); // exception handler found // patch the return address -> the stub will directly return to the exception handler - __ movl(Address(rbp, 1*BytesPerWord), rax); + __ movptr(Address(rbp, 1*BytesPerWord), rax); // restore registers restore_live_registers(sasm, save_fpu_registers); @@ -568,18 +718,18 @@ void Runtime1::generate_handle_exception(StubAssembler *sasm, OopMapSet* oop_map // there is no need to restore the registers // restore the real return address that was saved before the RT-call - __ movl(real_return_addr, Address(rsp, temp_1_off * BytesPerWord)); - __ movl(Address(rbp, 1*BytesPerWord), real_return_addr); + __ movptr(real_return_addr, Address(rsp, temp_1_off * VMRegImpl::stack_slot_size)); + __ movptr(Address(rbp, 1*BytesPerWord), real_return_addr); // load address of JavaThread object for thread-local data - __ get_thread(thread); + NOT_LP64(__ get_thread(thread);) // restore exception oop into rax, (convention for unwind code) - __ movl(exception_oop, Address(thread, JavaThread::exception_oop_offset())); + __ movptr(exception_oop, Address(thread, JavaThread::exception_oop_offset())); // clear exception fields in JavaThread because they are no longer needed // (fields must be cleared because they are processed by GC otherwise) - __ movl(Address(thread, JavaThread::exception_oop_offset()), NULL_WORD); - __ movl(Address(thread, JavaThread::exception_pc_offset()), NULL_WORD); + __ movptr(Address(thread, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD); + __ movptr(Address(thread, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD); // pop the stub frame off __ leave(); @@ -595,22 +745,22 @@ void Runtime1::generate_unwind_exception(StubAssembler *sasm) { // other registers used in this stub const Register exception_pc = rdx; const Register handler_addr = rbx; - const Register thread = rdi; + const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); // verify that only rax, is valid at this time __ invalidate_registers(false, true, true, true, true, true); #ifdef ASSERT // check that fields in JavaThread for exception oop and issuing pc are empty - __ get_thread(thread); + NOT_LP64(__ get_thread(thread);) Label oop_empty; - __ cmpl(Address(thread, JavaThread::exception_oop_offset()), 0); + __ cmpptr(Address(thread, JavaThread::exception_oop_offset()), 0); __ jcc(Assembler::equal, oop_empty); __ stop("exception oop must be empty"); __ bind(oop_empty); Label pc_empty; - __ cmpl(Address(thread, JavaThread::exception_pc_offset()), 0); + __ cmpptr(Address(thread, JavaThread::exception_pc_offset()), 0); __ jcc(Assembler::equal, pc_empty); __ stop("exception pc must be empty"); __ bind(pc_empty); @@ -622,12 +772,12 @@ void Runtime1::generate_unwind_exception(StubAssembler *sasm) { // leave activation of nmethod __ leave(); // store return address (is on top of stack after leave) - __ movl(exception_pc, Address(rsp, 0)); + __ movptr(exception_pc, Address(rsp, 0)); __ verify_oop(exception_oop); // save exception oop from rax, to stack before call - __ pushl(exception_oop); + __ push(exception_oop); // search the exception handler address of the caller (using the return address) __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), exception_pc); @@ -637,17 +787,17 @@ void Runtime1::generate_unwind_exception(StubAssembler *sasm) { __ invalidate_registers(false, true, true, true, true, true); // move result of call into correct register - __ movl(handler_addr, rax); + __ movptr(handler_addr, rax); // restore exception oop in rax, (required convention of exception handler) - __ popl(exception_oop); + __ pop(exception_oop); __ verify_oop(exception_oop); // get throwing pc (= return address). // rdx has been destroyed by the call, so it must be set again // the pop is also necessary to simulate the effect of a ret(0) - __ popl(exception_pc); + __ pop(exception_pc); // verify that that there is really a valid exception in rax, __ verify_not_null_oop(exception_oop); @@ -677,12 +827,18 @@ OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) { OopMap* oop_map = save_live_registers(sasm, num_rt_args); - __ pushl(rax); // push dummy +#ifdef _LP64 + const Register thread = r15_thread; + // No need to worry about dummy + __ mov(c_rarg0, thread); +#else + __ push(rax); // push dummy const Register thread = rdi; // is callee-saved register (Visual C++ calling conventions) // push java thread (becomes first argument of C function) __ get_thread(thread); - __ pushl(thread); + __ push(thread); +#endif // _LP64 __ set_last_Java_frame(thread, noreg, rbp, NULL); // do the call __ call(RuntimeAddress(target)); @@ -691,27 +847,29 @@ OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) { // verify callee-saved register #ifdef ASSERT guarantee(thread != rax, "change this code"); - __ pushl(rax); + __ push(rax); { Label L; __ get_thread(rax); - __ cmpl(thread, rax); + __ cmpptr(thread, rax); __ jcc(Assembler::equal, L); - __ stop("StubAssembler::call_RT: rdi not callee saved?"); + __ stop("StubAssembler::call_RT: rdi/r15 not callee saved?"); __ bind(L); } - __ popl(rax); + __ pop(rax); #endif __ reset_last_Java_frame(thread, true, false); - __ popl(rcx); // discard thread arg - __ popl(rcx); // discard dummy +#ifndef _LP64 + __ pop(rcx); // discard thread arg + __ pop(rcx); // discard dummy +#endif // _LP64 // check for pending exceptions { Label L; - __ cmpl(Address(thread, Thread::pending_exception_offset()), NULL_WORD); + __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::equal, L); // exception pending => remove activation and forward to exception handler - __ testl(rax, rax); // have we deoptimized? + __ testptr(rax, rax); // have we deoptimized? __ jump_cc(Assembler::equal, RuntimeAddress(Runtime1::entry_for(Runtime1::forward_exception_id))); @@ -719,38 +877,38 @@ OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) { // JavaThread, so copy and clear pending exception. // load and clear pending exception - __ movl(rax, Address(thread, Thread::pending_exception_offset())); - __ movl(Address(thread, Thread::pending_exception_offset()), NULL_WORD); + __ movptr(rax, Address(thread, Thread::pending_exception_offset())); + __ movptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); // check that there is really a valid exception __ verify_not_null_oop(rax); // load throwing pc: this is the return address of the stub - __ movl(rdx, Address(rsp, return_off * BytesPerWord)); + __ movptr(rdx, Address(rsp, return_off * VMRegImpl::stack_slot_size)); #ifdef ASSERT // check that fields in JavaThread for exception oop and issuing pc are empty Label oop_empty; - __ cmpoop(Address(thread, JavaThread::exception_oop_offset()), 0); + __ cmpptr(Address(thread, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::equal, oop_empty); __ stop("exception oop must be empty"); __ bind(oop_empty); Label pc_empty; - __ cmpl(Address(thread, JavaThread::exception_pc_offset()), 0); + __ cmpptr(Address(thread, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::equal, pc_empty); __ stop("exception pc must be empty"); __ bind(pc_empty); #endif // store exception oop and throwing pc to JavaThread - __ movl(Address(thread, JavaThread::exception_oop_offset()), rax); - __ movl(Address(thread, JavaThread::exception_pc_offset()), rdx); + __ movptr(Address(thread, JavaThread::exception_oop_offset()), rax); + __ movptr(Address(thread, JavaThread::exception_pc_offset()), rdx); restore_live_registers(sasm); __ leave(); - __ addl(rsp, 4); // remove return address from stack + __ addptr(rsp, BytesPerWord); // remove return address from stack // Forward the exception directly to deopt blob. We can blow no // registers and must leave throwing pc on the stack. A patch may @@ -767,7 +925,7 @@ OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) { Label reexecuteEntry, cont; - __ testl(rax, rax); // have we deoptimized? + __ testptr(rax, rax); // have we deoptimized? __ jcc(Assembler::equal, cont); // no // Will reexecute. Proper return address is already on the stack we just restore @@ -806,21 +964,21 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { // dispatch to the handler if found. Otherwise unwind and // dispatch to the callers exception handler. - const Register thread = rdi; + const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); const Register exception_oop = rax; const Register exception_pc = rdx; // load pending exception oop into rax, - __ movl(exception_oop, Address(thread, Thread::pending_exception_offset())); + __ movptr(exception_oop, Address(thread, Thread::pending_exception_offset())); // clear pending exception - __ movl(Address(thread, Thread::pending_exception_offset()), NULL_WORD); + __ movptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); // load issuing PC (the return address for this stub) into rdx - __ movl(exception_pc, Address(rbp, 1*BytesPerWord)); + __ movptr(exception_pc, Address(rbp, 1*BytesPerWord)); // make sure that the vm_results are cleared (may be unnecessary) - __ movl(Address(thread, JavaThread::vm_result_offset()), NULL_WORD); - __ movl(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD); + __ movptr(Address(thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD); + __ movptr(Address(thread, JavaThread::vm_result_2_offset()), (int32_t)NULL_WORD); // verify that that there is really a valid exception in rax, __ verify_not_null_oop(exception_oop); @@ -857,8 +1015,8 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { Register t2 = rsi; assert_different_registers(klass, obj, obj_size, t1, t2); - __ pushl(rdi); - __ pushl(rbx); + __ push(rdi); + __ push(rbx); if (id == fast_new_instance_init_check_id) { // make sure the klass is initialized @@ -889,28 +1047,28 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { __ bind(retry_tlab); - // get the instance size + // get the instance size (size is postive so movl is fine for 64bit) __ movl(obj_size, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes())); __ tlab_allocate(obj, obj_size, 0, t1, t2, slow_path); __ initialize_object(obj, klass, obj_size, 0, t1, t2); __ verify_oop(obj); - __ popl(rbx); - __ popl(rdi); + __ pop(rbx); + __ pop(rdi); __ ret(0); __ bind(try_eden); - // get the instance size + // get the instance size (size is postive so movl is fine for 64bit) __ movl(obj_size, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes())); __ eden_allocate(obj, obj_size, 0, t1, slow_path); __ initialize_object(obj, klass, obj_size, 0, t1, t2); __ verify_oop(obj); - __ popl(rbx); - __ popl(rdi); + __ pop(rbx); + __ pop(rdi); __ ret(0); __ bind(slow_path); - __ popl(rbx); - __ popl(rdi); + __ pop(rbx); + __ pop(rdi); } __ enter(); @@ -996,15 +1154,17 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { __ bind(retry_tlab); // get the allocation size: round_up(hdr + length << (layout_helper & 0x1F)) + // since size is postive movl does right thing on 64bit __ movl(t1, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes())); + // since size is postive movl does right thing on 64bit __ movl(arr_size, length); assert(t1 == rcx, "fixed register usage"); - __ shll(arr_size /* by t1=rcx, mod 32 */); - __ shrl(t1, Klass::_lh_header_size_shift); - __ andl(t1, Klass::_lh_header_size_mask); - __ addl(arr_size, t1); - __ addl(arr_size, MinObjAlignmentInBytesMask); // align up - __ andl(arr_size, ~MinObjAlignmentInBytesMask); + __ shlptr(arr_size /* by t1=rcx, mod 32 */); + __ shrptr(t1, Klass::_lh_header_size_shift); + __ andptr(t1, Klass::_lh_header_size_mask); + __ addptr(arr_size, t1); + __ addptr(arr_size, MinObjAlignmentInBytesMask); // align up + __ andptr(arr_size, ~MinObjAlignmentInBytesMask); __ tlab_allocate(obj, arr_size, 0, t1, t2, slow_path); // preserves arr_size @@ -1012,24 +1172,26 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { __ movb(t1, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes() + (Klass::_lh_header_size_shift / BitsPerByte))); assert(Klass::_lh_header_size_shift % BitsPerByte == 0, "bytewise"); assert(Klass::_lh_header_size_mask <= 0xFF, "bytewise"); - __ andl(t1, Klass::_lh_header_size_mask); - __ subl(arr_size, t1); // body length - __ addl(t1, obj); // body start + __ andptr(t1, Klass::_lh_header_size_mask); + __ subptr(arr_size, t1); // body length + __ addptr(t1, obj); // body start __ initialize_body(t1, arr_size, 0, t2); __ verify_oop(obj); __ ret(0); __ bind(try_eden); // get the allocation size: round_up(hdr + length << (layout_helper & 0x1F)) + // since size is postive movl does right thing on 64bit __ movl(t1, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes())); + // since size is postive movl does right thing on 64bit __ movl(arr_size, length); assert(t1 == rcx, "fixed register usage"); - __ shll(arr_size /* by t1=rcx, mod 32 */); - __ shrl(t1, Klass::_lh_header_size_shift); - __ andl(t1, Klass::_lh_header_size_mask); - __ addl(arr_size, t1); - __ addl(arr_size, MinObjAlignmentInBytesMask); // align up - __ andl(arr_size, ~MinObjAlignmentInBytesMask); + __ shlptr(arr_size /* by t1=rcx, mod 32 */); + __ shrptr(t1, Klass::_lh_header_size_shift); + __ andptr(t1, Klass::_lh_header_size_mask); + __ addptr(arr_size, t1); + __ addptr(arr_size, MinObjAlignmentInBytesMask); // align up + __ andptr(arr_size, ~MinObjAlignmentInBytesMask); __ eden_allocate(obj, arr_size, 0, t1, slow_path); // preserves arr_size @@ -1037,9 +1199,9 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { __ movb(t1, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes() + (Klass::_lh_header_size_shift / BitsPerByte))); assert(Klass::_lh_header_size_shift % BitsPerByte == 0, "bytewise"); assert(Klass::_lh_header_size_mask <= 0xFF, "bytewise"); - __ andl(t1, Klass::_lh_header_size_mask); - __ subl(arr_size, t1); // body length - __ addl(t1, obj); // body start + __ andptr(t1, Klass::_lh_header_size_mask); + __ subptr(arr_size, t1); // body length + __ addptr(t1, obj); // body start __ initialize_body(t1, arr_size, 0, t2); __ verify_oop(obj); __ ret(0); @@ -1089,15 +1251,23 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { { __ set_info("register_finalizer", dont_gc_arguments); + // This is called via call_runtime so the arguments + // will be place in C abi locations + +#ifdef _LP64 + __ verify_oop(c_rarg0); + __ mov(rax, c_rarg0); +#else // The object is passed on the stack and we haven't pushed a // frame yet so it's one work away from top of stack. - __ movl(rax, Address(rsp, 1 * BytesPerWord)); + __ movptr(rax, Address(rsp, 1 * BytesPerWord)); __ verify_oop(rax); +#endif // _LP64 // load the klass and check the has finalizer flag Label register_finalizer; Register t = rsi; - __ movl(t, Address(rax, oopDesc::klass_offset_in_bytes())); + __ movptr(t, Address(rax, oopDesc::klass_offset_in_bytes())); __ movl(t, Address(t, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc))); __ testl(t, JVM_ACC_HAS_FINALIZER); __ jcc(Assembler::notZero, register_finalizer); @@ -1185,46 +1355,49 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { case slow_subtype_check_id: { enum layout { - rax_off, - rcx_off, - rsi_off, - rdi_off, - saved_rbp_off, - return_off, - sub_off, - super_off, + rax_off, SLOT2(raxH_off) + rcx_off, SLOT2(rcxH_off) + rsi_off, SLOT2(rsiH_off) + rdi_off, SLOT2(rdiH_off) + // saved_rbp_off, SLOT2(saved_rbpH_off) + return_off, SLOT2(returnH_off) + sub_off, SLOT2(subH_off) + super_off, SLOT2(superH_off) framesize }; __ set_info("slow_subtype_check", dont_gc_arguments); - __ pushl(rdi); - __ pushl(rsi); - __ pushl(rcx); - __ pushl(rax); - __ movl(rsi, Address(rsp, (super_off - 1) * BytesPerWord)); // super - __ movl(rax, Address(rsp, (sub_off - 1) * BytesPerWord)); // sub + __ push(rdi); + __ push(rsi); + __ push(rcx); + __ push(rax); - __ movl(rdi,Address(rsi,sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())); - __ movl(rcx,Address(rdi,arrayOopDesc::length_offset_in_bytes())); - __ addl(rdi,arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + // This is called by pushing args and not with C abi + __ movptr(rsi, Address(rsp, (super_off) * VMRegImpl::stack_slot_size)); // super + __ movptr(rax, Address(rsp, (sub_off ) * VMRegImpl::stack_slot_size)); // sub + + __ movptr(rdi,Address(rsi,sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())); + // since size is postive movl does right thing on 64bit + __ movl(rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes())); + __ addptr(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); Label miss; __ repne_scan(); __ jcc(Assembler::notEqual, miss); - __ movl(Address(rsi,sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()), rax); - __ movl(Address(rsp, (super_off - 1) * BytesPerWord), 1); // result - __ popl(rax); - __ popl(rcx); - __ popl(rsi); - __ popl(rdi); + __ movptr(Address(rsi,sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()), rax); + __ movptr(Address(rsp, (super_off) * VMRegImpl::stack_slot_size), 1); // result + __ pop(rax); + __ pop(rcx); + __ pop(rsi); + __ pop(rdi); __ ret(0); __ bind(miss); - __ movl(Address(rsp, (super_off - 1) * BytesPerWord), 0); // result - __ popl(rax); - __ popl(rcx); - __ popl(rsi); - __ popl(rdi); + __ movptr(Address(rsp, (super_off) * VMRegImpl::stack_slot_size), 0); // result + __ pop(rax); + __ pop(rcx); + __ pop(rsi); + __ pop(rdi); __ ret(0); } break; @@ -1237,6 +1410,8 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { StubFrame f(sasm, "monitorenter", dont_gc_arguments); OopMap* map = save_live_registers(sasm, 3, save_fpu_registers); + // Called with store_parameter and not C abi + f.load_argument(1, rax); // rax,: object f.load_argument(0, rbx); // rbx,: lock address @@ -1256,6 +1431,8 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { StubFrame f(sasm, "monitorexit", dont_gc_arguments); OopMap* map = save_live_registers(sasm, 2, save_fpu_registers); + // Called with store_parameter and not C abi + f.load_argument(0, rax); // rax,: lock address // note: really a leaf routine but must setup last java sp @@ -1304,9 +1481,9 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { // the live registers get saved. save_live_registers(sasm, 1); - __ pushl(rax); + __ NOT_LP64(push(rax)) LP64_ONLY(mov(c_rarg0, rax)); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc))); - __ popl(rax); + NOT_LP64(__ pop(rax)); restore_live_registers(sasm); } @@ -1316,18 +1493,19 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { { // rax, and rdx are destroyed, but should be free since the result is returned there // preserve rsi,ecx - __ pushl(rsi); - __ pushl(rcx); + __ push(rsi); + __ push(rcx); + LP64_ONLY(__ push(rdx);) // check for NaN Label return0, do_return, return_min_jlong, do_convert; - Address value_high_word(rsp, 8); - Address value_low_word(rsp, 4); - Address result_high_word(rsp, 16); - Address result_low_word(rsp, 12); + Address value_high_word(rsp, wordSize + 4); + Address value_low_word(rsp, wordSize); + Address result_high_word(rsp, 3*wordSize + 4); + Address result_low_word(rsp, 3*wordSize); - __ subl(rsp, 20); + __ subptr(rsp, 32); // more than enough on 32bit __ fst_d(value_low_word); __ movl(rax, value_high_word); __ andl(rax, 0x7ff00000); @@ -1340,7 +1518,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { __ bind(do_convert); __ fnstcw(Address(rsp, 0)); - __ movzxw(rax, Address(rsp, 0)); + __ movzwl(rax, Address(rsp, 0)); __ orl(rax, 0xc00); __ movw(Address(rsp, 2), rax); __ fldcw(Address(rsp, 2)); @@ -1348,9 +1526,11 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { __ fistp_d(result_low_word); __ fldcw(Address(rsp, 0)); __ fwait(); - __ movl(rax, result_low_word); + // This gets the entire long in rax on 64bit + __ movptr(rax, result_low_word); + // testing of high bits __ movl(rdx, result_high_word); - __ movl(rcx, rax); + __ mov(rcx, rax); // What the heck is the point of the next instruction??? __ xorl(rcx, 0x0); __ movl(rsi, 0x80000000); @@ -1360,34 +1540,52 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { __ fldz(); __ fcomp_d(value_low_word); __ fnstsw_ax(); +#ifdef _LP64 + __ testl(rax, 0x4100); // ZF & CF == 0 + __ jcc(Assembler::equal, return_min_jlong); +#else __ sahf(); __ jcc(Assembler::above, return_min_jlong); +#endif // _LP64 // return max_jlong +#ifndef _LP64 __ movl(rdx, 0x7fffffff); __ movl(rax, 0xffffffff); +#else + __ mov64(rax, CONST64(0x7fffffffffffffff)); +#endif // _LP64 __ jmp(do_return); __ bind(return_min_jlong); +#ifndef _LP64 __ movl(rdx, 0x80000000); __ xorl(rax, rax); +#else + __ mov64(rax, CONST64(0x8000000000000000)); +#endif // _LP64 __ jmp(do_return); __ bind(return0); __ fpop(); - __ xorl(rdx,rdx); - __ xorl(rax,rax); +#ifndef _LP64 + __ xorptr(rdx,rdx); + __ xorptr(rax,rax); +#else + __ xorptr(rax, rax); +#endif // _LP64 __ bind(do_return); - __ addl(rsp, 20); - __ popl(rcx); - __ popl(rsi); + __ addptr(rsp, 32); + LP64_ONLY(__ pop(rdx);) + __ pop(rcx); + __ pop(rsi); __ ret(0); } break; default: { StubFrame f(sasm, "unimplemented entry", dont_gc_arguments); - __ movl(rax, (int)id); + __ movptr(rax, (int)id); __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), rax); __ should_not_reach_here(); } diff --git a/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp b/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp index 89c497de7a4..a829cb3132b 100644 --- a/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp +++ b/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp @@ -44,6 +44,14 @@ extern "C" void RecursiveInterpreterActivation(interpreterState istate ) Label fast_accessor_slow_entry_path; // fast accessor methods need to be able to jmp to unsynchronized // c++ interpreter entry point this holds that entry point label. +// default registers for state and sender_sp +// state and sender_sp are the same on 32bit because we have no choice. +// state could be rsi on 64bit but it is an arg reg and not callee save +// so r13 is better choice. + +const Register state = NOT_LP64(rsi) LP64_ONLY(r13); +const Register sender_sp_on_entry = NOT_LP64(rsi) LP64_ONLY(r13); + // NEEDED for JVMTI? // address AbstractInterpreter::_remove_activation_preserving_args_entry; @@ -88,7 +96,6 @@ bool CppInterpreter::contains(address pc) { address CppInterpreterGenerator::generate_result_handler_for(BasicType type) { - const Register state = rsi; // current activation object, valid on entry address entry = __ pc(); switch (type) { case T_BOOLEAN: __ c2bool(rax); break; @@ -98,19 +105,22 @@ address CppInterpreterGenerator::generate_result_handler_for(BasicType type) { case T_VOID : // fall thru case T_LONG : // fall thru case T_INT : /* nothing to do */ break; + case T_DOUBLE : case T_FLOAT : - { const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp(); - __ popl(t); // remove return address first - __ pop_dtos_to_rsp(); + { + const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp(); + __ pop(t); // remove return address first // Must return a result for interpreter or compiler. In SSE // mode, results are returned in xmm0 and the FPU stack must // be empty. if (type == T_FLOAT && UseSSE >= 1) { +#ifndef _LP64 // Load ST0 __ fld_d(Address(rsp, 0)); // Store as float and empty fpu stack __ fstp_s(Address(rsp, 0)); +#endif // !_LP64 // and reload __ movflt(xmm0, Address(rsp, 0)); } else if (type == T_DOUBLE && UseSSE >= 2 ) { @@ -120,13 +130,13 @@ address CppInterpreterGenerator::generate_result_handler_for(BasicType type) { __ fld_d(Address(rsp, 0)); } // and pop the temp - __ addl(rsp, 2 * wordSize); - __ pushl(t); // restore return address + __ addptr(rsp, 2 * wordSize); + __ push(t); // restore return address } break; case T_OBJECT : // retrieve result from frame - __ movl(rax, STATE(_oop_temp)); + __ movptr(rax, STATE(_oop_temp)); // and verify it __ verify_oop(rax); break; @@ -146,7 +156,7 @@ address CppInterpreterGenerator::generate_tosca_to_stack_converter(BasicType typ address entry = __ pc(); const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp(); - __ popl(t); // remove return address first + __ pop(t); // remove return address first switch (type) { case T_VOID: break; @@ -154,53 +164,53 @@ address CppInterpreterGenerator::generate_tosca_to_stack_converter(BasicType typ #ifdef EXTEND __ c2bool(rax); #endif - __ pushl(rax); + __ push(rax); break; case T_CHAR : #ifdef EXTEND __ andl(rax, 0xFFFF); #endif - __ pushl(rax); + __ push(rax); break; case T_BYTE : #ifdef EXTEND __ sign_extend_byte (rax); #endif - __ pushl(rax); + __ push(rax); break; case T_SHORT : #ifdef EXTEND __ sign_extend_short(rax); #endif - __ pushl(rax); + __ push(rax); break; case T_LONG : - __ pushl(rdx); - __ pushl(rax); + __ push(rdx); // pushes useless junk on 64bit + __ push(rax); break; case T_INT : - __ pushl(rax); + __ push(rax); break; case T_FLOAT : - // Result is in ST(0) + // Result is in ST(0)/xmm0 + __ subptr(rsp, wordSize); if ( UseSSE < 1) { - __ push(ftos); // and save it + __ fstp_s(Address(rsp, 0)); } else { - __ subl(rsp, wordSize); __ movflt(Address(rsp, 0), xmm0); } break; case T_DOUBLE : + __ subptr(rsp, 2*wordSize); if ( UseSSE < 2 ) { - __ push(dtos); // put ST0 on java stack + __ fstp_d(Address(rsp, 0)); } else { - __ subl(rsp, 2*wordSize); __ movdbl(Address(rsp, 0), xmm0); } break; case T_OBJECT : __ verify_oop(rax); // verify it - __ pushl(rax); + __ push(rax); break; default : ShouldNotReachHere(); } @@ -212,7 +222,7 @@ address CppInterpreterGenerator::generate_stack_to_stack_converter(BasicType typ // A result is in the java expression stack of the interpreted method that has just // returned. Place this result on the java expression stack of the caller. // - // The current interpreter activation in rsi is for the method just returning its + // The current interpreter activation in rsi/r13 is for the method just returning its // result. So we know that the result of this method is on the top of the current // execution stack (which is pre-pushed) and will be return to the top of the caller // stack. The top of the callers stack is the bottom of the locals of the current @@ -222,20 +232,19 @@ address CppInterpreterGenerator::generate_stack_to_stack_converter(BasicType typ // of the calling activation. This enable this routine to leave the return address // to the frame manager on the stack and do a vanilla return. // - // On entry: rsi - interpreter state of activation returning a (potential) result - // On Return: rsi - unchanged + // On entry: rsi/r13 - interpreter state of activation returning a (potential) result + // On Return: rsi/r13 - unchanged // rax - new stack top for caller activation (i.e. activation in _prev_link) // // Can destroy rdx, rcx. // address entry = __ pc(); - const Register state = rsi; // current activation object, valid on entry const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp(); switch (type) { case T_VOID: - __ movl(rax, STATE(_locals)); // pop parameters get new stack value - __ addl(rax, wordSize); // account for prepush before we return + __ movptr(rax, STATE(_locals)); // pop parameters get new stack value + __ addptr(rax, wordSize); // account for prepush before we return break; case T_FLOAT : case T_BOOLEAN: @@ -244,10 +253,10 @@ address CppInterpreterGenerator::generate_stack_to_stack_converter(BasicType typ case T_SHORT : case T_INT : // 1 word result - __ movl(rdx, STATE(_stack)); - __ movl(rax, STATE(_locals)); // address for result + __ movptr(rdx, STATE(_stack)); + __ movptr(rax, STATE(_locals)); // address for result __ movl(rdx, Address(rdx, wordSize)); // get result - __ movl(Address(rax, 0), rdx); // and store it + __ movptr(Address(rax, 0), rdx); // and store it break; case T_LONG : case T_DOUBLE : @@ -256,20 +265,20 @@ address CppInterpreterGenerator::generate_stack_to_stack_converter(BasicType typ // except we allocated one extra word for this intepretState so we won't overwrite it // when we return a two word result. - __ movl(rax, STATE(_locals)); // address for result - __ movl(rcx, STATE(_stack)); - __ subl(rax, wordSize); // need addition word besides locals[0] - __ movl(rdx, Address(rcx, 2*wordSize)); // get result word - __ movl(Address(rax, wordSize), rdx); // and store it - __ movl(rdx, Address(rcx, wordSize)); // get result word - __ movl(Address(rax, 0), rdx); // and store it + __ movptr(rax, STATE(_locals)); // address for result + __ movptr(rcx, STATE(_stack)); + __ subptr(rax, wordSize); // need addition word besides locals[0] + __ movptr(rdx, Address(rcx, 2*wordSize)); // get result word (junk in 64bit) + __ movptr(Address(rax, wordSize), rdx); // and store it + __ movptr(rdx, Address(rcx, wordSize)); // get result word + __ movptr(Address(rax, 0), rdx); // and store it break; case T_OBJECT : - __ movl(rdx, STATE(_stack)); - __ movl(rax, STATE(_locals)); // address for result - __ movl(rdx, Address(rdx, wordSize)); // get result + __ movptr(rdx, STATE(_stack)); + __ movptr(rax, STATE(_locals)); // address for result + __ movptr(rdx, Address(rdx, wordSize)); // get result __ verify_oop(rdx); // verify it - __ movl(Address(rax, 0), rdx); // and store it + __ movptr(Address(rax, 0), rdx); // and store it break; default : ShouldNotReachHere(); } @@ -285,12 +294,11 @@ address CppInterpreterGenerator::generate_stack_to_native_abi_converter(BasicTyp // frame manager execept in this situation the caller is native code (c1/c2/call_stub) // and so rather than return result onto caller's java expression stack we return the // result in the expected location based on the native abi. - // On entry: rsi - interpreter state of activation returning a (potential) result - // On Return: rsi - unchanged + // On entry: rsi/r13 - interpreter state of activation returning a (potential) result + // On Return: rsi/r13 - unchanged // Other registers changed [rax/rdx/ST(0) as needed for the result returned] address entry = __ pc(); - const Register state = rsi; // current activation object, valid on entry switch (type) { case T_VOID: break; @@ -299,17 +307,16 @@ address CppInterpreterGenerator::generate_stack_to_native_abi_converter(BasicTyp case T_BYTE : case T_SHORT : case T_INT : - __ movl(rdx, STATE(_stack)); // get top of stack + __ movptr(rdx, STATE(_stack)); // get top of stack __ movl(rax, Address(rdx, wordSize)); // get result word 1 break; case T_LONG : - __ movl(rdx, STATE(_stack)); // get top of stack - __ movl(rax, Address(rdx, wordSize)); // get result low word - __ movl(rdx, Address(rdx, 2*wordSize)); // get result high word - break; + __ movptr(rdx, STATE(_stack)); // get top of stack + __ movptr(rax, Address(rdx, wordSize)); // get result low word + NOT_LP64(__ movl(rdx, Address(rdx, 2*wordSize));) // get result high word break; case T_FLOAT : - __ movl(rdx, STATE(_stack)); // get top of stack + __ movptr(rdx, STATE(_stack)); // get top of stack if ( UseSSE >= 1) { __ movflt(xmm0, Address(rdx, wordSize)); } else { @@ -317,7 +324,7 @@ address CppInterpreterGenerator::generate_stack_to_native_abi_converter(BasicTyp } break; case T_DOUBLE : - __ movl(rdx, STATE(_stack)); // get top of stack + __ movptr(rdx, STATE(_stack)); // get top of stack if ( UseSSE > 1) { __ movdbl(xmm0, Address(rdx, wordSize)); } else { @@ -325,8 +332,8 @@ address CppInterpreterGenerator::generate_stack_to_native_abi_converter(BasicTyp } break; case T_OBJECT : - __ movl(rdx, STATE(_stack)); // get top of stack - __ movl(rax, Address(rdx, wordSize)); // get result word 1 + __ movptr(rdx, STATE(_stack)); // get top of stack + __ movptr(rax, Address(rdx, wordSize)); // get result word 1 __ verify_oop(rax); // verify it break; default : ShouldNotReachHere(); @@ -408,54 +415,58 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(const Register if (!native) { #ifdef PRODUCT - __ subl(rsp, 2*wordSize); + __ subptr(rsp, 2*wordSize); #else /* PRODUCT */ - __ pushl((int)NULL); - __ pushl(state); // make it look like a real argument + __ push((int32_t)NULL_WORD); + __ push(state); // make it look like a real argument #endif /* PRODUCT */ } // Now that we are assure of space for stack result, setup typical linkage - __ pushl(rax); + __ push(rax); __ enter(); - __ movl(rax, state); // save current state + __ mov(rax, state); // save current state - __ leal(rsp, Address(rsp, -(int)sizeof(BytecodeInterpreter))); - __ movl(state, rsp); + __ lea(rsp, Address(rsp, -(int)sizeof(BytecodeInterpreter))); + __ mov(state, rsp); - // rsi == state/locals rax == prevstate + // rsi/r13 == state/locals rax == prevstate // initialize the "shadow" frame so that use since C++ interpreter not directly // recursive. Simpler to recurse but we can't trim expression stack as we call // new methods. - __ movl(STATE(_locals), locals); // state->_locals = locals() - __ movl(STATE(_self_link), state); // point to self - __ movl(STATE(_prev_link), rax); // state->_link = state on entry (NULL or previous state) - __ movl(STATE(_sender_sp), sender_sp); // state->_sender_sp = sender_sp + __ movptr(STATE(_locals), locals); // state->_locals = locals() + __ movptr(STATE(_self_link), state); // point to self + __ movptr(STATE(_prev_link), rax); // state->_link = state on entry (NULL or previous state) + __ movptr(STATE(_sender_sp), sender_sp); // state->_sender_sp = sender_sp +#ifdef _LP64 + __ movptr(STATE(_thread), r15_thread); // state->_bcp = codes() +#else __ get_thread(rax); // get vm's javathread* - __ movl(STATE(_thread), rax); // state->_bcp = codes() - __ movl(rdx, Address(rbx, methodOopDesc::const_offset())); // get constantMethodOop - __ leal(rdx, Address(rdx, constMethodOopDesc::codes_offset())); // get code base + __ movptr(STATE(_thread), rax); // state->_bcp = codes() +#endif // _LP64 + __ movptr(rdx, Address(rbx, methodOopDesc::const_offset())); // get constantMethodOop + __ lea(rdx, Address(rdx, constMethodOopDesc::codes_offset())); // get code base if (native) { - __ movl(STATE(_bcp), (intptr_t)NULL); // state->_bcp = NULL + __ movptr(STATE(_bcp), (int32_t)NULL_WORD); // state->_bcp = NULL } else { - __ movl(STATE(_bcp), rdx); // state->_bcp = codes() + __ movptr(STATE(_bcp), rdx); // state->_bcp = codes() } - __ xorl(rdx, rdx); - __ movl(STATE(_oop_temp), rdx); // state->_oop_temp = NULL (only really needed for native) - __ movl(STATE(_mdx), rdx); // state->_mdx = NULL - __ movl(rdx, Address(rbx, methodOopDesc::constants_offset())); - __ movl(rdx, Address(rdx, constantPoolOopDesc::cache_offset_in_bytes())); - __ movl(STATE(_constants), rdx); // state->_constants = constants() + __ xorptr(rdx, rdx); + __ movptr(STATE(_oop_temp), rdx); // state->_oop_temp = NULL (only really needed for native) + __ movptr(STATE(_mdx), rdx); // state->_mdx = NULL + __ movptr(rdx, Address(rbx, methodOopDesc::constants_offset())); + __ movptr(rdx, Address(rdx, constantPoolOopDesc::cache_offset_in_bytes())); + __ movptr(STATE(_constants), rdx); // state->_constants = constants() - __ movl(STATE(_method), rbx); // state->_method = method() - __ movl(STATE(_msg), (int) BytecodeInterpreter::method_entry); // state->_msg = initial method entry - __ movl(STATE(_result._to_call._callee), (int) NULL); // state->_result._to_call._callee_callee = NULL + __ movptr(STATE(_method), rbx); // state->_method = method() + __ movl(STATE(_msg), (int32_t) BytecodeInterpreter::method_entry); // state->_msg = initial method entry + __ movptr(STATE(_result._to_call._callee), (int32_t) NULL_WORD); // state->_result._to_call._callee_callee = NULL - __ movl(STATE(_monitor_base), rsp); // set monitor block bottom (grows down) this would point to entry [0] + __ movptr(STATE(_monitor_base), rsp); // set monitor block bottom (grows down) this would point to entry [0] // entries run from -1..x where &monitor[x] == { @@ -479,36 +490,44 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(const Register const int mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes(); __ movl(rax, access_flags); __ testl(rax, JVM_ACC_STATIC); - __ movl(rax, Address(locals, 0)); // get receiver (assume this is frequent case) + __ movptr(rax, Address(locals, 0)); // get receiver (assume this is frequent case) __ jcc(Assembler::zero, done); - __ movl(rax, Address(rbx, methodOopDesc::constants_offset())); - __ movl(rax, Address(rax, constantPoolOopDesc::pool_holder_offset_in_bytes())); - __ movl(rax, Address(rax, mirror_offset)); + __ movptr(rax, Address(rbx, methodOopDesc::constants_offset())); + __ movptr(rax, Address(rax, constantPoolOopDesc::pool_holder_offset_in_bytes())); + __ movptr(rax, Address(rax, mirror_offset)); __ bind(done); // add space for monitor & lock - __ subl(rsp, entry_size); // add space for a monitor entry - __ movl(Address(rsp, BasicObjectLock::obj_offset_in_bytes()), rax); // store object + __ subptr(rsp, entry_size); // add space for a monitor entry + __ movptr(Address(rsp, BasicObjectLock::obj_offset_in_bytes()), rax); // store object __ bind(not_synced); } - __ movl(STATE(_stack_base), rsp); // set expression stack base ( == &monitors[-count]) + __ movptr(STATE(_stack_base), rsp); // set expression stack base ( == &monitors[-count]) if (native) { - __ movl(STATE(_stack), rsp); // set current expression stack tos - __ movl(STATE(_stack_limit), rsp); + __ movptr(STATE(_stack), rsp); // set current expression stack tos + __ movptr(STATE(_stack_limit), rsp); } else { - __ subl(rsp, wordSize); // pre-push stack - __ movl(STATE(_stack), rsp); // set current expression stack tos + __ subptr(rsp, wordSize); // pre-push stack + __ movptr(STATE(_stack), rsp); // set current expression stack tos // compute full expression stack limit const Address size_of_stack (rbx, methodOopDesc::max_stack_offset()); __ load_unsigned_word(rdx, size_of_stack); // get size of expression stack in words - __ negl(rdx); // so we can subtract in next step + __ negptr(rdx); // so we can subtract in next step // Allocate expression stack - __ leal(rsp, Address(rsp, rdx, Address::times_4)); - __ movl(STATE(_stack_limit), rsp); + __ lea(rsp, Address(rsp, rdx, Address::times_ptr)); + __ movptr(STATE(_stack_limit), rsp); } +#ifdef _LP64 + // Make sure stack is properly aligned and sized for the abi + __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows + __ andptr(rsp, -16); // must be 16 byte boundry (see amd64 ABI) +#endif // _LP64 + + + } // Helpers for commoning out cases in the various type of method entries. @@ -528,7 +547,7 @@ void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile const Address backedge_counter (rbx, methodOopDesc::backedge_counter_offset() + InvocationCounter::counter_offset()); if (ProfileInterpreter) { // %%% Merge this into methodDataOop - __ increment(Address(rbx,methodOopDesc::interpreter_invocation_counter_offset())); + __ incrementl(Address(rbx,methodOopDesc::interpreter_invocation_counter_offset())); } // Update standard invocation counters __ movl(rax, backedge_counter); // load backedge counter @@ -552,7 +571,7 @@ void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile void InterpreterGenerator::generate_counter_overflow(Label* do_continue) { // C++ interpreter on entry - // rsi - new interpreter state pointer + // rsi/r13 - new interpreter state pointer // rbp - interpreter frame pointer // rbx - method @@ -563,7 +582,7 @@ void InterpreterGenerator::generate_counter_overflow(Label* do_continue) { // rsp - sender_sp // C++ interpreter only - // rsi - previous interpreter state pointer + // rsi/r13 - previous interpreter state pointer const Address size_of_parameters(rbx, methodOopDesc::size_of_parameters_offset()); @@ -571,16 +590,14 @@ void InterpreterGenerator::generate_counter_overflow(Label* do_continue) { // indicating if the counter overflow occurs at a backwards branch (non-NULL bcp). // The call returns the address of the verified entry point for the method or NULL // if the compilation did not complete (either went background or bailed out). - __ movl(rax, (int)false); + __ movptr(rax, (int32_t)false); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), rax); // for c++ interpreter can rsi really be munged? - __ leal(rsi, Address(rbp, -sizeof(BytecodeInterpreter))); // restore state - __ movl(rbx, Address(rsi, byte_offset_of(BytecodeInterpreter, _method))); // restore method - __ movl(rdi, Address(rsi, byte_offset_of(BytecodeInterpreter, _locals))); // get locals pointer + __ lea(state, Address(rbp, -sizeof(BytecodeInterpreter))); // restore state + __ movptr(rbx, Address(state, byte_offset_of(BytecodeInterpreter, _method))); // restore method + __ movptr(rdi, Address(state, byte_offset_of(BytecodeInterpreter, _locals))); // get locals pointer - // Preserve invariant that rsi/rdi contain bcp/locals of sender frame - // and jump to the interpreted entry. __ jmp(*do_continue, relocInfo::none); } @@ -597,7 +614,7 @@ void InterpreterGenerator::generate_stack_overflow_check(void) { // rbx,: methodOop // C++ Interpreter - // rsi: previous interpreter frame state object + // rsi/r13: previous interpreter frame state object // rdi: &locals[0] // rcx: # of locals // rdx: number of additional locals this frame needs (what we must check) @@ -628,11 +645,11 @@ void InterpreterGenerator::generate_stack_overflow_check(void) { // save rsi == caller's bytecode ptr (c++ previous interp. state) // QQQ problem here?? rsi overload???? - __ pushl(rsi); + __ push(state); - const Register thread = rsi; + const Register thread = LP64_ONLY(r15_thread) NOT_LP64(rsi); - __ get_thread(thread); + NOT_LP64(__ get_thread(thread)); const Address stack_base(thread, Thread::stack_base_offset()); const Address stack_size(thread, Thread::stack_size_offset()); @@ -643,26 +660,26 @@ void InterpreterGenerator::generate_stack_overflow_check(void) { // Any additional monitors need a check when moving the expression stack const one_monitor = frame::interpreter_frame_monitor_size() * wordSize; __ load_unsigned_word(rax, size_of_stack); // get size of expression stack in words - __ leal(rax, Address(noreg, rax, Interpreter::stackElementScale(), one_monitor)); - __ leal(rax, Address(rax, rdx, Interpreter::stackElementScale(), overhead_size)); + __ lea(rax, Address(noreg, rax, Interpreter::stackElementScale(), one_monitor)); + __ lea(rax, Address(rax, rdx, Interpreter::stackElementScale(), overhead_size)); #ifdef ASSERT Label stack_base_okay, stack_size_okay; // verify that thread stack base is non-zero - __ cmpl(stack_base, 0); + __ cmpptr(stack_base, (int32_t)0); __ jcc(Assembler::notEqual, stack_base_okay); __ stop("stack base is zero"); __ bind(stack_base_okay); // verify that thread stack size is non-zero - __ cmpl(stack_size, 0); + __ cmpptr(stack_size, (int32_t)0); __ jcc(Assembler::notEqual, stack_size_okay); __ stop("stack size is zero"); __ bind(stack_size_okay); #endif // Add stack base to locals and subtract stack size - __ addl(rax, stack_base); - __ subl(rax, stack_size); + __ addptr(rax, stack_base); + __ subptr(rax, stack_size); // We should have a magic number here for the size of the c++ interpreter frame. // We can't actually tell this ahead of time. The debug version size is around 3k @@ -674,20 +691,20 @@ void InterpreterGenerator::generate_stack_overflow_check(void) { (StackRedPages+StackYellowPages); // Only need this if we are stack banging which is temporary while // we're debugging. - __ addl(rax, slop + 2*max_pages * page_size); + __ addptr(rax, slop + 2*max_pages * page_size); // check against the current stack bottom - __ cmpl(rsp, rax); + __ cmpptr(rsp, rax); __ jcc(Assembler::above, after_frame_check_pop); - __ popl(rsi); // get saved bcp / (c++ prev state ). + __ pop(state); // get c++ prev state. // throw exception return address becomes throwing pc __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_StackOverflowError)); // all done with frame size check __ bind(after_frame_check_pop); - __ popl(rsi); + __ pop(state); __ bind(after_frame_check); } @@ -696,17 +713,18 @@ void InterpreterGenerator::generate_stack_overflow_check(void) { // rbx - methodOop // void InterpreterGenerator::lock_method(void) { - // assumes state == rsi == pointer to current interpreterState - // minimally destroys rax, rdx, rdi + // assumes state == rsi/r13 == pointer to current interpreterState + // minimally destroys rax, rdx|c_rarg1, rdi // // synchronize method - const Register state = rsi; const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; const Address access_flags (rbx, methodOopDesc::access_flags_offset()); + const Register monitor = NOT_LP64(rdx) LP64_ONLY(c_rarg1); + // find initial monitor i.e. monitors[-1] - __ movl(rdx, STATE(_monitor_base)); // get monitor bottom limit - __ subl(rdx, entry_size); // point to initial monitor + __ movptr(monitor, STATE(_monitor_base)); // get monitor bottom limit + __ subptr(monitor, entry_size); // point to initial monitor #ifdef ASSERT { Label L; @@ -721,35 +739,34 @@ void InterpreterGenerator::lock_method(void) { { Label done; const int mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes(); __ movl(rax, access_flags); - __ movl(rdi, STATE(_locals)); // prepare to get receiver (assume common case) + __ movptr(rdi, STATE(_locals)); // prepare to get receiver (assume common case) __ testl(rax, JVM_ACC_STATIC); - __ movl(rax, Address(rdi, 0)); // get receiver (assume this is frequent case) + __ movptr(rax, Address(rdi, 0)); // get receiver (assume this is frequent case) __ jcc(Assembler::zero, done); - __ movl(rax, Address(rbx, methodOopDesc::constants_offset())); - __ movl(rax, Address(rax, constantPoolOopDesc::pool_holder_offset_in_bytes())); - __ movl(rax, Address(rax, mirror_offset)); + __ movptr(rax, Address(rbx, methodOopDesc::constants_offset())); + __ movptr(rax, Address(rax, constantPoolOopDesc::pool_holder_offset_in_bytes())); + __ movptr(rax, Address(rax, mirror_offset)); __ bind(done); } #ifdef ASSERT { Label L; - __ cmpl(rax, Address(rdx, BasicObjectLock::obj_offset_in_bytes())); // correct object? + __ cmpptr(rax, Address(monitor, BasicObjectLock::obj_offset_in_bytes())); // correct object? __ jcc(Assembler::equal, L); __ stop("wrong synchronization lobject"); __ bind(L); } #endif // ASSERT - // can destroy rax, rdx, rcx, and (via call_VM) rdi! - __ lock_object(rdx); + // can destroy rax, rdx|c_rarg1, rcx, and (via call_VM) rdi! + __ lock_object(monitor); } // Call an accessor method (assuming it is resolved, otherwise drop into vanilla (slow path) entry address InterpreterGenerator::generate_accessor_entry(void) { - // rbx,: methodOop - // rcx: receiver (preserve for slow entry into asm interpreter) + // rbx: methodOop - // rsi: senderSP must preserved for slow path, set SP to it on fast path + // rsi/r13: senderSP must preserved for slow path, set SP to it on fast path Label xreturn_path; @@ -772,21 +789,21 @@ address InterpreterGenerator::generate_accessor_entry(void) { // these conditions first and use slow path if necessary. // rbx,: method // rcx: receiver - __ movl(rax, Address(rsp, wordSize)); + __ movptr(rax, Address(rsp, wordSize)); // check if local 0 != NULL and read field - __ testl(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, slow_path); - __ movl(rdi, Address(rbx, methodOopDesc::constants_offset())); + __ movptr(rdi, Address(rbx, methodOopDesc::constants_offset())); // read first instruction word and extract bytecode @ 1 and index @ 2 - __ movl(rdx, Address(rbx, methodOopDesc::const_offset())); + __ movptr(rdx, Address(rbx, methodOopDesc::const_offset())); __ movl(rdx, Address(rdx, constMethodOopDesc::codes_offset())); // Shift codes right to get the index on the right. // The bytecode fetched looks like <0xb4><0x2a> __ shrl(rdx, 2*BitsPerByte); __ shll(rdx, exact_log2(in_words(ConstantPoolCacheEntry::size()))); - __ movl(rdi, Address(rdi, constantPoolOopDesc::cache_offset_in_bytes())); + __ movptr(rdi, Address(rdi, constantPoolOopDesc::cache_offset_in_bytes())); // rax,: local 0 // rbx,: method @@ -794,7 +811,7 @@ address InterpreterGenerator::generate_accessor_entry(void) { // rcx: scratch // rdx: constant pool cache index // rdi: constant pool cache - // rsi: sender sp + // rsi/r13: sender sp // check if getfield has been resolved and read constant pool cache entry // check the validity of the cache entry by testing whether _indices field @@ -803,21 +820,21 @@ address InterpreterGenerator::generate_accessor_entry(void) { __ movl(rcx, Address(rdi, rdx, - Address::times_4, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset())); + Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset())); __ shrl(rcx, 2*BitsPerByte); __ andl(rcx, 0xFF); __ cmpl(rcx, Bytecodes::_getfield); __ jcc(Assembler::notEqual, slow_path); // Note: constant pool entry is not valid before bytecode is resolved - __ movl(rcx, + __ movptr(rcx, Address(rdi, rdx, - Address::times_4, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f2_offset())); + Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f2_offset())); __ movl(rdx, Address(rdi, rdx, - Address::times_4, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::flags_offset())); + Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::flags_offset())); Label notByte, notShort, notChar; const Address field_address (rax, rcx, Address::times_1); @@ -828,6 +845,16 @@ address InterpreterGenerator::generate_accessor_entry(void) { __ shrl(rdx, ConstantPoolCacheEntry::tosBits); // Make sure we don't need to mask rdx for tosBits after the above shift ConstantPoolCacheEntry::verify_tosBits(); +#ifdef _LP64 + Label notObj; + __ cmpl(rdx, atos); + __ jcc(Assembler::notEqual, notObj); + // atos + __ movptr(rax, field_address); + __ jmp(xreturn_path); + + __ bind(notObj); +#endif // _LP64 __ cmpl(rdx, btos); __ jcc(Assembler::notEqual, notByte); __ load_signed_byte(rax, field_address); @@ -848,8 +875,10 @@ address InterpreterGenerator::generate_accessor_entry(void) { __ bind(notChar); #ifdef ASSERT Label okay; +#ifndef _LP64 __ cmpl(rdx, atos); __ jcc(Assembler::equal, okay); +#endif // _LP64 __ cmpl(rdx, itos); __ jcc(Assembler::equal, okay); __ stop("what type is this?"); @@ -861,8 +890,8 @@ address InterpreterGenerator::generate_accessor_entry(void) { __ bind(xreturn_path); // _ireturn/_areturn - __ popl(rdi); // get return address - __ movl(rsp, rsi); // set sp to sender sp + __ pop(rdi); // get return address + __ mov(rsp, sender_sp_on_entry); // set sp to sender sp __ jmp(rdi); // generate a vanilla interpreter entry as the slow path @@ -894,8 +923,8 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // rbx: methodOop // rcx: receiver (unused) - // rsi: previous interpreter state (if called from C++ interpreter) must preserve - // in any case. If called via c1/c2/call_stub rsi is junk (to use) but harmless + // rsi/r13: previous interpreter state (if called from C++ interpreter) must preserve + // in any case. If called via c1/c2/call_stub rsi/r13 is junk (to use) but harmless // to save/restore. address entry_point = __ pc(); @@ -904,8 +933,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { const Address invocation_counter(rbx, methodOopDesc::invocation_counter_offset() + InvocationCounter::counter_offset()); const Address access_flags (rbx, methodOopDesc::access_flags_offset()); - // rsi == state/locals rdi == prevstate - const Register state = rsi; + // rsi/r13 == state/locals rdi == prevstate const Register locals = rdi; // get parameter size (always needed) @@ -913,11 +941,11 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // rbx: methodOop // rcx: size of parameters - __ popl(rax); // get return address + __ pop(rax); // get return address // for natives the size of locals is zero // compute beginning of parameters /locals - __ leal(locals, Address(rsp, rcx, Address::times_4, -wordSize)); + __ lea(locals, Address(rsp, rcx, Address::times_ptr, -wordSize)); // initialize fixed part of activation frame @@ -931,15 +959,20 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // OUT(rsp) -> bottom of methods expression stack // save sender_sp - __ movl(rcx, rsi); + __ mov(rcx, sender_sp_on_entry); // start with NULL previous state - __ movl(state, 0); + __ movptr(state, (int32_t)NULL_WORD); generate_compute_interpreter_state(state, locals, rcx, true); #ifdef ASSERT { Label L; - __ movl(rax, STATE(_stack_base)); - __ cmpl(rax, rsp); + __ movptr(rax, STATE(_stack_base)); +#ifdef _LP64 + // duplicate the alignment rsp got after setting stack_base + __ subptr(rax, frame::arg_reg_save_area_bytes); // windows + __ andptr(rax, -16); // must be 16 byte boundry (see amd64 ABI) +#endif // _LP64 + __ cmpptr(rax, rsp); __ jcc(Assembler::equal, L); __ stop("broken stack frame setup in interpreter"); __ bind(L); @@ -948,14 +981,15 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { if (inc_counter) __ movl(rcx, invocation_counter); // (pre-)fetch invocation count - __ movl(rax, STATE(_thread)); // get thread + const Register unlock_thread = LP64_ONLY(r15_thread) NOT_LP64(rax); + NOT_LP64(__ movptr(unlock_thread, STATE(_thread));) // get thread // Since at this point in the method invocation the exception handler // would try to exit the monitor of synchronized methods which hasn't // been entered yet, we set the thread local variable // _do_not_unlock_if_synchronized to true. The remove_activation will // check this flag. - const Address do_not_unlock_if_synchronized(rax, + const Address do_not_unlock_if_synchronized(unlock_thread, in_bytes(JavaThread::do_not_unlock_if_synchronized_offset())); __ movbool(do_not_unlock_if_synchronized, true); @@ -991,7 +1025,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { bang_stack_shadow_pages(true); // reset the _do_not_unlock_if_synchronized flag - __ movl(rax, STATE(_thread)); // get thread + NOT_LP64(__ movl(rax, STATE(_thread));) // get thread __ movbool(do_not_unlock_if_synchronized, false); @@ -1022,62 +1056,81 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // work registers const Register method = rbx; - const Register thread = rdi; - const Register t = rcx; + const Register thread = LP64_ONLY(r15_thread) NOT_LP64(rdi); + const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp(); // rcx|rscratch1 // allocate space for parameters - __ movl(method, STATE(_method)); + __ movptr(method, STATE(_method)); __ verify_oop(method); __ load_unsigned_word(t, Address(method, methodOopDesc::size_of_parameters_offset())); __ shll(t, 2); - __ addl(t, 2*wordSize); // allocate two more slots for JNIEnv and possible mirror - __ subl(rsp, t); - __ andl(rsp, -(StackAlignmentInBytes)); // gcc needs 16 byte aligned stacks to do XMM intrinsics +#ifdef _LP64 + __ subptr(rsp, t); + __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows + __ andptr(rsp, -16); // must be 16 byte boundry (see amd64 ABI) +#else + __ addptr(t, 2*wordSize); // allocate two more slots for JNIEnv and possible mirror + __ subptr(rsp, t); + __ andptr(rsp, -(StackAlignmentInBytes)); // gcc needs 16 byte aligned stacks to do XMM intrinsics +#endif // _LP64 // get signature handler Label pending_exception_present; { Label L; - __ movl(t, Address(method, methodOopDesc::signature_handler_offset())); - __ testl(t, t); + __ movptr(t, Address(method, methodOopDesc::signature_handler_offset())); + __ testptr(t, t); __ jcc(Assembler::notZero, L); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), method, false); - __ movl(method, STATE(_method)); - __ cmpl(Address(thread, Thread::pending_exception_offset()), NULL_WORD); + __ movptr(method, STATE(_method)); + __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::notEqual, pending_exception_present); __ verify_oop(method); - __ movl(t, Address(method, methodOopDesc::signature_handler_offset())); + __ movptr(t, Address(method, methodOopDesc::signature_handler_offset())); __ bind(L); } #ifdef ASSERT { Label L; - __ pushl(t); + __ push(t); __ get_thread(t); // get vm's javathread* - __ cmpl(t, STATE(_thread)); + __ cmpptr(t, STATE(_thread)); __ jcc(Assembler::equal, L); __ int3(); __ bind(L); - __ popl(t); + __ pop(t); } #endif // + const Register from_ptr = InterpreterRuntime::SignatureHandlerGenerator::from(); // call signature handler - assert(InterpreterRuntime::SignatureHandlerGenerator::from() == rdi, "adjust this code"); assert(InterpreterRuntime::SignatureHandlerGenerator::to () == rsp, "adjust this code"); - assert(InterpreterRuntime::SignatureHandlerGenerator::temp() == t , "adjust this code"); + // The generated handlers do not touch RBX (the method oop). // However, large signatures cannot be cached and are generated // each time here. The slow-path generator will blow RBX // sometime, so we must reload it after the call. - __ movl(rdi, STATE(_locals)); // get the from pointer + __ movptr(from_ptr, STATE(_locals)); // get the from pointer __ call(t); - __ movl(method, STATE(_method)); + __ movptr(method, STATE(_method)); __ verify_oop(method); // result handler is in rax // set result handler - __ movl(STATE(_result_handler), rax); + __ movptr(STATE(_result_handler), rax); + + + // get native function entry point + { Label L; + __ movptr(rax, Address(method, methodOopDesc::native_function_offset())); + __ testptr(rax, rax); + __ jcc(Assembler::notZero, L); + __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), method); + __ movptr(method, STATE(_method)); + __ verify_oop(method); + __ movptr(rax, Address(method, methodOopDesc::native_function_offset())); + __ bind(L); + } // pass mirror handle if static call { Label L; @@ -1086,55 +1139,53 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ testl(t, JVM_ACC_STATIC); __ jcc(Assembler::zero, L); // get mirror - __ movl(t, Address(method, methodOopDesc:: constants_offset())); - __ movl(t, Address(t, constantPoolOopDesc::pool_holder_offset_in_bytes())); - __ movl(t, Address(t, mirror_offset)); + __ movptr(t, Address(method, methodOopDesc:: constants_offset())); + __ movptr(t, Address(t, constantPoolOopDesc::pool_holder_offset_in_bytes())); + __ movptr(t, Address(t, mirror_offset)); // copy mirror into activation object - __ movl(STATE(_oop_temp), t); + __ movptr(STATE(_oop_temp), t); // pass handle to mirror - __ leal(t, STATE(_oop_temp)); - __ movl(Address(rsp, wordSize), t); +#ifdef _LP64 + __ lea(c_rarg1, STATE(_oop_temp)); +#else + __ lea(t, STATE(_oop_temp)); + __ movptr(Address(rsp, wordSize), t); +#endif // _LP64 __ bind(L); } #ifdef ASSERT { Label L; - __ pushl(t); + __ push(t); __ get_thread(t); // get vm's javathread* - __ cmpl(t, STATE(_thread)); + __ cmpptr(t, STATE(_thread)); __ jcc(Assembler::equal, L); __ int3(); __ bind(L); - __ popl(t); + __ pop(t); } #endif // - // get native function entry point - { Label L; - __ movl(rax, Address(method, methodOopDesc::native_function_offset())); - __ testl(rax, rax); - __ jcc(Assembler::notZero, L); - __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), method); - __ movl(method, STATE(_method)); - __ verify_oop(method); - __ movl(rax, Address(method, methodOopDesc::native_function_offset())); - __ bind(L); - } - // pass JNIEnv - __ movl(thread, STATE(_thread)); // get thread - __ leal(t, Address(thread, JavaThread::jni_environment_offset())); - __ movl(Address(rsp, 0), t); +#ifdef _LP64 + __ lea(c_rarg0, Address(thread, JavaThread::jni_environment_offset())); +#else + __ movptr(thread, STATE(_thread)); // get thread + __ lea(t, Address(thread, JavaThread::jni_environment_offset())); + + __ movptr(Address(rsp, 0), t); +#endif // _LP64 + #ifdef ASSERT { Label L; - __ pushl(t); + __ push(t); __ get_thread(t); // get vm's javathread* - __ cmpl(t, STATE(_thread)); + __ cmpptr(t, STATE(_thread)); __ jcc(Assembler::equal, L); __ int3(); __ bind(L); - __ popl(t); + __ pop(t); } #endif // @@ -1159,8 +1210,8 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ call(rax); // result potentially in rdx:rax or ST0 - __ movl(method, STATE(_method)); - __ movl(thread, STATE(_thread)); // get thread + __ movptr(method, STATE(_method)); + NOT_LP64(__ movptr(thread, STATE(_thread));) // get thread // The potential result is in ST(0) & rdx:rax // With C++ interpreter we leave any possible result in ST(0) until we are in result handler and then @@ -1170,7 +1221,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // It is safe to do these pushes because state is _thread_in_native and return address will be found // via _last_native_pc and not via _last_jave_sp - // Must save the value of ST(0) since it could be destroyed before we get to result handler + // Must save the value of ST(0)/xmm0 since it could be destroyed before we get to result handler { Label Lpush, Lskip; ExternalAddress float_handler(AbstractInterpreter::result_handler(T_FLOAT)); ExternalAddress double_handler(AbstractInterpreter::result_handler(T_DOUBLE)); @@ -1179,11 +1230,20 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ cmpptr(STATE(_result_handler), double_handler.addr()); __ jcc(Assembler::notEqual, Lskip); __ bind(Lpush); - __ push(dtos); + __ subptr(rsp, 2*wordSize); + if ( UseSSE < 2 ) { + __ fstp_d(Address(rsp, 0)); + } else { + __ movdbl(Address(rsp, 0), xmm0); + } __ bind(Lskip); } - __ push(ltos); // save rax:rdx for potential use by result handler. + // save rax:rdx for potential use by result handler. + __ push(rax); +#ifndef _LP64 + __ push(rdx); +#endif // _LP64 // Either restore the MXCSR register after returning from the JNI Call // or verify that it wasn't changed. @@ -1192,15 +1252,17 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ ldmxcsr(ExternalAddress(StubRoutines::addr_mxcsr_std())); } else if (CheckJNICalls ) { - __ call(RuntimeAddress(StubRoutines::i486::verify_mxcsr_entry())); + __ call(RuntimeAddress(StubRoutines::x86::verify_mxcsr_entry())); } } +#ifndef _LP64 // Either restore the x87 floating pointer control word after returning // from the JNI call or verify that it wasn't changed. if (CheckJNICalls) { - __ call(RuntimeAddress(StubRoutines::i486::verify_fpu_cntrl_wrd_entry())); + __ call(RuntimeAddress(StubRoutines::x86::verify_fpu_cntrl_wrd_entry())); } +#endif // _LP64 // change thread state @@ -1231,17 +1293,16 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // Don't use call_VM as it will see a possible pending exception and forward it // and never return here preventing us from clearing _last_native_pc down below. // Also can't use call_VM_leaf either as it will check to see if rsi & rdi are - // preserved and correspond to the bcp/locals pointers. So we do a runtime call - // by hand. + // preserved and correspond to the bcp/locals pointers. // - __ pushl(thread); - __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, - JavaThread::check_special_condition_for_native_trans))); + + ((MacroAssembler*)_masm)->call_VM_leaf(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans), + thread); __ increment(rsp, wordSize); - __ movl(method, STATE(_method)); + __ movptr(method, STATE(_method)); __ verify_oop(method); - __ movl(thread, STATE(_thread)); // get thread + __ movptr(thread, STATE(_thread)); // get thread __ bind(Continue); } @@ -1252,8 +1313,8 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ reset_last_Java_frame(thread, true, true); // reset handle block - __ movl(t, Address(thread, JavaThread::active_handles_offset())); - __ movl(Address(t, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD); + __ movptr(t, Address(thread, JavaThread::active_handles_offset())); + __ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); // If result was an oop then unbox and save it in the frame { Label L; @@ -1261,15 +1322,21 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { ExternalAddress oop_handler(AbstractInterpreter::result_handler(T_OBJECT)); __ cmpptr(STATE(_result_handler), oop_handler.addr()); __ jcc(Assembler::notEqual, no_oop); - __ pop(ltos); - __ testl(rax, rax); +#ifndef _LP64 + __ pop(rdx); +#endif // _LP64 + __ pop(rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, store_result); // unbox - __ movl(rax, Address(rax, 0)); + __ movptr(rax, Address(rax, 0)); __ bind(store_result); - __ movl(STATE(_oop_temp), rax); + __ movptr(STATE(_oop_temp), rax); // keep stack depth as expected by pushing oop which will eventually be discarded - __ push(ltos); + __ push(rax); +#ifndef _LP64 + __ push(rdx); +#endif // _LP64 __ bind(no_oop); } @@ -1278,9 +1345,9 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ cmpl(Address(thread, JavaThread::stack_guard_state_offset()), JavaThread::stack_guard_yellow_disabled); __ jcc(Assembler::notEqual, no_reguard); - __ pushad(); + __ pusha(); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages))); - __ popad(); + __ popa(); __ bind(no_reguard); } @@ -1295,7 +1362,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // handle exceptions (exception handling will handle unlocking!) { Label L; - __ cmpl(Address(thread, Thread::pending_exception_offset()), NULL_WORD); + __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::zero, L); __ bind(pending_exception_present); @@ -1307,12 +1374,12 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // remove activation - __ movl(t, STATE(_sender_sp)); + __ movptr(t, STATE(_sender_sp)); __ leave(); // remove frame anchor - __ popl(rdi); // get return address - __ movl(state, STATE(_prev_link)); // get previous state for return - __ movl(rsp, t); // set sp to sender sp - __ pushl(rdi); // [ush throwing pc + __ pop(rdi); // get return address + __ movptr(state, STATE(_prev_link)); // get previous state for return + __ mov(rsp, t); // set sp to sender sp + __ push(rdi); // push throwing pc // The skips unlocking!! This seems to be what asm interpreter does but seems // very wrong. Not clear if this violates the spec. __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); @@ -1326,13 +1393,14 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ jcc(Assembler::zero, L); // the code below should be shared with interpreter macro assembler implementation { Label unlock; + const Register monitor = NOT_LP64(rdx) LP64_ONLY(c_rarg1); // BasicObjectLock will be first in list, since this is a synchronized method. However, need // to check that the object has not been unlocked by an explicit monitorexit bytecode. - __ movl(rdx, STATE(_monitor_base)); - __ subl(rdx, frame::interpreter_frame_monitor_size() * wordSize); // address of initial monitor + __ movptr(monitor, STATE(_monitor_base)); + __ subptr(monitor, frame::interpreter_frame_monitor_size() * wordSize); // address of initial monitor - __ movl(t, Address(rdx, BasicObjectLock::obj_offset_in_bytes())); - __ testl(t, t); + __ movptr(t, Address(monitor, BasicObjectLock::obj_offset_in_bytes())); + __ testptr(t, t); __ jcc(Assembler::notZero, unlock); // Entry already unlocked, need to throw exception @@ -1340,9 +1408,9 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ should_not_reach_here(); __ bind(unlock); - __ unlock_object(rdx); + __ unlock_object(monitor); // unlock can blow rbx so restore it for path that needs it below - __ movl(method, STATE(_method)); + __ movptr(method, STATE(_method)); } __ bind(L); } @@ -1355,18 +1423,21 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ notify_method_exit(vtos, InterpreterMacroAssembler::NotifyJVMTI); // restore potential result in rdx:rax, call result handler to restore potential result in ST0 & handle result - __ pop(ltos); // restore rax/rdx floating result if present still on stack - __ movl(t, STATE(_result_handler)); // get result handler +#ifndef _LP64 + __ pop(rdx); +#endif // _LP64 + __ pop(rax); + __ movptr(t, STATE(_result_handler)); // get result handler __ call(t); // call result handler to convert to tosca form // remove activation - __ movl(t, STATE(_sender_sp)); + __ movptr(t, STATE(_sender_sp)); __ leave(); // remove frame anchor - __ popl(rdi); // get return address - __ movl(state, STATE(_prev_link)); // get previous state for return (if c++ interpreter was caller) - __ movl(rsp, t); // set sp to sender sp + __ pop(rdi); // get return address + __ movptr(state, STATE(_prev_link)); // get previous state for return (if c++ interpreter was caller) + __ mov(rsp, t); // set sp to sender sp __ jmp(rdi); // invocation counter overflow @@ -1382,7 +1453,6 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // Generate entries that will put a result type index into rcx void CppInterpreterGenerator::generate_deopt_handling() { - const Register state = rsi; Label return_from_deopt_common; // Generate entries that will put a result type index into rcx @@ -1449,51 +1519,50 @@ void CppInterpreterGenerator::generate_deopt_handling() { // __ bind(return_from_deopt_common); - __ leal(state, Address(rbp, -(int)sizeof(BytecodeInterpreter))); + __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter))); // setup rsp so we can push the "result" as needed. - __ movl(rsp, STATE(_stack)); // trim stack (is prepushed) - __ addl(rsp, wordSize); // undo prepush + __ movptr(rsp, STATE(_stack)); // trim stack (is prepushed) + __ addptr(rsp, wordSize); // undo prepush ExternalAddress tosca_to_stack((address)CppInterpreter::_tosca_to_stack); - // Address index(noreg, rcx, Address::times_4); - __ movptr(rcx, ArrayAddress(tosca_to_stack, Address(noreg, rcx, Address::times_4))); - // __ movl(rcx, Address(noreg, rcx, Address::times_4, int(AbstractInterpreter::_tosca_to_stack))); + // Address index(noreg, rcx, Address::times_ptr); + __ movptr(rcx, ArrayAddress(tosca_to_stack, Address(noreg, rcx, Address::times_ptr))); + // __ movl(rcx, Address(noreg, rcx, Address::times_ptr, int(AbstractInterpreter::_tosca_to_stack))); __ call(rcx); // call result converter __ movl(STATE(_msg), (int)BytecodeInterpreter::deopt_resume); - __ leal(rsp, Address(rsp, -wordSize)); // prepush stack (result if any already present) - __ movl(STATE(_stack), rsp); // inform interpreter of new stack depth (parameters removed, + __ lea(rsp, Address(rsp, -wordSize)); // prepush stack (result if any already present) + __ movptr(STATE(_stack), rsp); // inform interpreter of new stack depth (parameters removed, // result if any on stack already ) - __ movl(rsp, STATE(_stack_limit)); // restore expression stack to full depth + __ movptr(rsp, STATE(_stack_limit)); // restore expression stack to full depth } // Generate the code to handle a more_monitors message from the c++ interpreter void CppInterpreterGenerator::generate_more_monitors() { - const Register state = rsi; Label entry, loop; const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; - // 1. compute new pointers // rsp: old expression stack top - __ movl(rdx, STATE(_stack_base)); // rdx: old expression stack bottom - __ subl(rsp, entry_size); // move expression stack top limit - __ subl(STATE(_stack), entry_size); // update interpreter stack top - __ movl(STATE(_stack_limit), rsp); // inform interpreter - __ subl(rdx, entry_size); // move expression stack bottom - __ movl(STATE(_stack_base), rdx); // inform interpreter - __ movl(rcx, STATE(_stack)); // set start value for copy loop + // 1. compute new pointers // rsp: old expression stack top + __ movptr(rdx, STATE(_stack_base)); // rdx: old expression stack bottom + __ subptr(rsp, entry_size); // move expression stack top limit + __ subptr(STATE(_stack), entry_size); // update interpreter stack top + __ subptr(STATE(_stack_limit), entry_size); // inform interpreter + __ subptr(rdx, entry_size); // move expression stack bottom + __ movptr(STATE(_stack_base), rdx); // inform interpreter + __ movptr(rcx, STATE(_stack)); // set start value for copy loop __ jmp(entry); // 2. move expression stack contents __ bind(loop); - __ movl(rbx, Address(rcx, entry_size)); // load expression stack word from old location - __ movl(Address(rcx, 0), rbx); // and store it at new location - __ addl(rcx, wordSize); // advance to next word + __ movptr(rbx, Address(rcx, entry_size)); // load expression stack word from old location + __ movptr(Address(rcx, 0), rbx); // and store it at new location + __ addptr(rcx, wordSize); // advance to next word __ bind(entry); - __ cmpl(rcx, rdx); // check if bottom reached - __ jcc(Assembler::notEqual, loop); // if not at bottom then copy next word + __ cmpptr(rcx, rdx); // check if bottom reached + __ jcc(Assembler::notEqual, loop); // if not at bottom then copy next word // now zero the slot so we can find it. - __ movl(Address(rdx, BasicObjectLock::obj_offset_in_bytes()), (int) NULL); + __ movptr(Address(rdx, BasicObjectLock::obj_offset_in_bytes()), (int32_t) NULL_WORD); __ movl(STATE(_msg), (int)BytecodeInterpreter::got_monitors); } @@ -1517,7 +1586,7 @@ void CppInterpreterGenerator::generate_more_monitors() { // // rbx: methodOop // rcx: receiver - unused (retrieved from stack as needed) -// rsi: previous frame manager state (NULL from the call_stub/c1/c2) +// rsi/r13: previous frame manager state (NULL from the call_stub/c1/c2) // // // Stack layout at entry @@ -1539,7 +1608,7 @@ static address interpreter_frame_manager = NULL; address InterpreterGenerator::generate_normal_entry(bool synchronized) { // rbx: methodOop - // rsi: sender sp + // rsi/r13: sender sp // Because we redispatch "recursive" interpreter entries thru this same entry point // the "input" register usage is a little strange and not what you expect coming @@ -1562,12 +1631,11 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { if (UseFastAccessorMethods && !synchronized) __ bind(fast_accessor_slow_entry_path); Label dispatch_entry_2; - __ movl(rcx, rsi); - __ movl(rsi, 0); // no current activation + __ movptr(rcx, sender_sp_on_entry); + __ movptr(state, (int32_t)NULL_WORD); // no current activation __ jmp(dispatch_entry_2); - const Register state = rsi; // current activation object, valid on entry const Register locals = rdi; Label re_dispatch; @@ -1575,12 +1643,12 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { __ bind(re_dispatch); // save sender sp (doesn't include return address - __ leal(rcx, Address(rsp, wordSize)); + __ lea(rcx, Address(rsp, wordSize)); __ bind(dispatch_entry_2); // save sender sp - __ pushl(rcx); + __ push(rcx); const Address size_of_parameters(rbx, methodOopDesc::size_of_parameters_offset()); const Address size_of_locals (rbx, methodOopDesc::size_of_locals_offset()); @@ -1597,7 +1665,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { // rcx: size of parameters __ load_unsigned_word(rdx, size_of_locals); // get size of locals in words - __ subl(rdx, rcx); // rdx = no. of additional locals + __ subptr(rdx, rcx); // rdx = no. of additional locals // see if we've got enough room on the stack for locals plus overhead. generate_stack_overflow_check(); // C++ @@ -1609,26 +1677,26 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { // compute beginning of parameters (rdi) - __ leal(locals, Address(rsp, rcx, Address::times_4, wordSize)); + __ lea(locals, Address(rsp, rcx, Address::times_ptr, wordSize)); // save sender's sp // __ movl(rcx, rsp); // get sender's sp - __ popl(rcx); + __ pop(rcx); // get return address - __ popl(rax); + __ pop(rax); // rdx - # of additional locals // allocate space for locals // explicitly initialize locals { Label exit, loop; - __ testl(rdx, rdx); + __ testl(rdx, rdx); // (32bit ok) __ jcc(Assembler::lessEqual, exit); // do nothing if rdx <= 0 __ bind(loop); - __ pushl((int)NULL); // initialize local variables + __ push((int32_t)NULL_WORD); // initialize local variables __ decrement(rdx); // until everything initialized __ jcc(Assembler::greater, loop); __ bind(exit); @@ -1664,17 +1732,21 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { __ bind(call_interpreter_2); { - const Register thread = rcx; + const Register thread = NOT_LP64(rcx) LP64_ONLY(r15_thread); - __ pushl(state); // push arg to interpreter - __ movl(thread, STATE(_thread)); +#ifdef _LP64 + __ mov(c_rarg0, state); +#else + __ push(state); // push arg to interpreter + __ movptr(thread, STATE(_thread)); +#endif // _LP64 // We can setup the frame anchor with everything we want at this point // as we are thread_in_Java and no safepoints can occur until we go to // vm mode. We do have to clear flags on return from vm but that is it // - __ movl(Address(thread, JavaThread::last_Java_fp_offset()), rbp); - __ movl(Address(thread, JavaThread::last_Java_sp_offset()), rsp); + __ movptr(Address(thread, JavaThread::last_Java_fp_offset()), rbp); + __ movptr(Address(thread, JavaThread::last_Java_sp_offset()), rsp); // Call the interpreter @@ -1682,14 +1754,14 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { RuntimeAddress checking(CAST_FROM_FN_PTR(address, BytecodeInterpreter::runWithChecks)); __ call(JvmtiExport::can_post_interpreter_events() ? checking : normal); - __ popl(rax); // discard parameter to run + NOT_LP64(__ pop(rax);) // discard parameter to run // // state is preserved since it is callee saved // // reset_last_Java_frame - __ movl(thread, STATE(_thread)); + NOT_LP64(__ movl(thread, STATE(_thread));) __ reset_last_Java_frame(thread, true, true); } @@ -1703,15 +1775,15 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { Label bad_msg; Label do_OSR; - __ cmpl(rdx, (int)BytecodeInterpreter::call_method); + __ cmpl(rdx, (int32_t)BytecodeInterpreter::call_method); __ jcc(Assembler::equal, call_method); - __ cmpl(rdx, (int)BytecodeInterpreter::return_from_method); + __ cmpl(rdx, (int32_t)BytecodeInterpreter::return_from_method); __ jcc(Assembler::equal, return_from_interpreted_method); - __ cmpl(rdx, (int)BytecodeInterpreter::do_osr); + __ cmpl(rdx, (int32_t)BytecodeInterpreter::do_osr); __ jcc(Assembler::equal, do_OSR); - __ cmpl(rdx, (int)BytecodeInterpreter::throwing_exception); + __ cmpl(rdx, (int32_t)BytecodeInterpreter::throwing_exception); __ jcc(Assembler::equal, throw_exception); - __ cmpl(rdx, (int)BytecodeInterpreter::more_monitors); + __ cmpl(rdx, (int32_t)BytecodeInterpreter::more_monitors); __ jcc(Assembler::notEqual, bad_msg); // Allocate more monitor space, shuffle expression stack.... @@ -1724,8 +1796,8 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { unctrap_frame_manager_entry = __ pc(); // // Load the registers we need. - __ leal(state, Address(rbp, -(int)sizeof(BytecodeInterpreter))); - __ movl(rsp, STATE(_stack_limit)); // restore expression stack to full depth + __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter))); + __ movptr(rsp, STATE(_stack_limit)); // restore expression stack to full depth __ jmp(call_interpreter_2); @@ -1757,13 +1829,17 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { Label unwind_and_forward; // restore state pointer. - __ leal(state, Address(rbp, -sizeof(BytecodeInterpreter))); + __ lea(state, Address(rbp, -sizeof(BytecodeInterpreter))); - __ movl(rbx, STATE(_method)); // get method + __ movptr(rbx, STATE(_method)); // get method +#ifdef _LP64 + __ movptr(Address(r15_thread, Thread::pending_exception_offset()), rax); +#else __ movl(rcx, STATE(_thread)); // get thread // Store exception with interpreter will expect it - __ movl(Address(rcx, Thread::pending_exception_offset()), rax); + __ movptr(Address(rcx, Thread::pending_exception_offset()), rax); +#endif // _LP64 // is current frame vanilla or native? @@ -1779,11 +1855,11 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { // unwind rbp, return stack to unextended value and re-push return address - __ movl(rcx, STATE(_sender_sp)); + __ movptr(rcx, STATE(_sender_sp)); __ leave(); - __ popl(rdx); - __ movl(rsp, rcx); - __ pushl(rdx); + __ pop(rdx); + __ mov(rsp, rcx); + __ push(rdx); __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); // Return point from a call which returns a result in the native abi @@ -1801,8 +1877,8 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { // The FPU stack is clean if UseSSE >= 2 but must be cleaned in other cases if (UseSSE < 2) { - __ leal(state, Address(rbp, -sizeof(BytecodeInterpreter))); - __ movl(rbx, STATE(_result._to_call._callee)); // get method just executed + __ lea(state, Address(rbp, -sizeof(BytecodeInterpreter))); + __ movptr(rbx, STATE(_result._to_call._callee)); // get method just executed __ movl(rcx, Address(rbx, methodOopDesc::result_index_offset())); __ cmpl(rcx, AbstractInterpreter::BasicType_as_index(T_FLOAT)); // Result stub address array index __ jcc(Assembler::equal, do_float); @@ -1832,10 +1908,12 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { __ jmp(done_conv); } +#if 0 // emit a sentinel we can test for when converting an interpreter // entry point to a compiled entry point. __ a_long(Interpreter::return_sentinel); __ a_long((int)compiled_entry); +#endif // Return point to interpreter from compiled/native method @@ -1848,33 +1926,37 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { // calling convention left it (i.e. params may or may not be present) // Copy the result from tosca and place it on java expression stack. - // Restore rsi as compiled code may not preserve it + // Restore rsi/r13 as compiled code may not preserve it - __ leal(state, Address(rbp, -sizeof(BytecodeInterpreter))); + __ lea(state, Address(rbp, -sizeof(BytecodeInterpreter))); // restore stack to what we had when we left (in case i2c extended it) - __ movl(rsp, STATE(_stack)); - __ leal(rsp, Address(rsp, wordSize)); + __ movptr(rsp, STATE(_stack)); + __ lea(rsp, Address(rsp, wordSize)); // If there is a pending exception then we don't really have a result to process - __ movl(rcx, STATE(_thread)); // get thread - __ cmpl(Address(rcx, Thread::pending_exception_offset()), (int)NULL); +#ifdef _LP64 + __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); +#else + __ movptr(rcx, STATE(_thread)); // get thread + __ cmpptr(Address(rcx, Thread::pending_exception_offset()), (int32_t)NULL_WORD); +#endif / __LP64 __ jcc(Assembler::notZero, return_with_exception); // get method just executed - __ movl(rbx, STATE(_result._to_call._callee)); + __ movptr(rbx, STATE(_result._to_call._callee)); // callee left args on top of expression stack, remove them __ load_unsigned_word(rcx, Address(rbx, methodOopDesc::size_of_parameters_offset())); - __ leal(rsp, Address(rsp, rcx, Address::times_4)); + __ lea(rsp, Address(rsp, rcx, Address::times_ptr)); __ movl(rcx, Address(rbx, methodOopDesc::result_index_offset())); ExternalAddress tosca_to_stack((address)CppInterpreter::_tosca_to_stack); - // Address index(noreg, rax, Address::times_4); - __ movptr(rcx, ArrayAddress(tosca_to_stack, Address(noreg, rcx, Address::times_4))); - // __ movl(rcx, Address(noreg, rcx, Address::times_4, int(AbstractInterpreter::_tosca_to_stack))); + // Address index(noreg, rax, Address::times_ptr); + __ movptr(rcx, ArrayAddress(tosca_to_stack, Address(noreg, rcx, Address::times_ptr))); + // __ movl(rcx, Address(noreg, rcx, Address::times_ptr, int(AbstractInterpreter::_tosca_to_stack))); __ call(rcx); // call result converter __ jmp(resume_interpreter); @@ -1884,7 +1966,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { __ bind(return_with_exception); // Exception present, empty stack - __ movl(rsp, STATE(_stack_base)); + __ movptr(rsp, STATE(_stack_base)); __ jmp(resume_interpreter); // Return from interpreted method we return result appropriate to the caller (i.e. "recursive" @@ -1895,17 +1977,17 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { Label return_to_initial_caller; - __ movl(rbx, STATE(_method)); // get method just executed - __ cmpl(STATE(_prev_link), (int)NULL); // returning from "recursive" interpreter call? + __ movptr(rbx, STATE(_method)); // get method just executed + __ cmpptr(STATE(_prev_link), (int32_t)NULL_WORD); // returning from "recursive" interpreter call? __ movl(rax, Address(rbx, methodOopDesc::result_index_offset())); // get result type index __ jcc(Assembler::equal, return_to_initial_caller); // back to native code (call_stub/c1/c2) // Copy result to callers java stack ExternalAddress stack_to_stack((address)CppInterpreter::_stack_to_stack); - // Address index(noreg, rax, Address::times_4); + // Address index(noreg, rax, Address::times_ptr); - __ movptr(rax, ArrayAddress(stack_to_stack, Address(noreg, rax, Address::times_4))); - // __ movl(rax, Address(noreg, rax, Address::times_4, int(AbstractInterpreter::_stack_to_stack))); + __ movptr(rax, ArrayAddress(stack_to_stack, Address(noreg, rax, Address::times_ptr))); + // __ movl(rax, Address(noreg, rax, Address::times_ptr, int(AbstractInterpreter::_stack_to_stack))); __ call(rax); // call result converter Label unwind_recursive_activation; @@ -1915,9 +1997,9 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { // result converter left rax pointing to top of the java stack for method we are returning // to. Now all we must do is unwind the state from the completed call - __ movl(state, STATE(_prev_link)); // unwind state + __ movptr(state, STATE(_prev_link)); // unwind state __ leave(); // pop the frame - __ movl(rsp, rax); // unwind stack to remove args + __ mov(rsp, rax); // unwind stack to remove args // Resume the interpreter. The current frame contains the current interpreter // state object. @@ -1928,10 +2010,10 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { // state == interpreterState object for method we are resuming __ movl(STATE(_msg), (int)BytecodeInterpreter::method_resume); - __ leal(rsp, Address(rsp, -wordSize)); // prepush stack (result if any already present) - __ movl(STATE(_stack), rsp); // inform interpreter of new stack depth (parameters removed, + __ lea(rsp, Address(rsp, -wordSize)); // prepush stack (result if any already present) + __ movptr(STATE(_stack), rsp); // inform interpreter of new stack depth (parameters removed, // result if any on stack already ) - __ movl(rsp, STATE(_stack_limit)); // restore expression stack to full depth + __ movptr(rsp, STATE(_stack_limit)); // restore expression stack to full depth __ jmp(call_interpreter_2); // No need to bang // interpreter returning to native code (call_stub/c1/c2) @@ -1940,9 +2022,9 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { __ bind(return_to_initial_caller); ExternalAddress stack_to_native((address)CppInterpreter::_stack_to_native_abi); - // Address index(noreg, rax, Address::times_4); + // Address index(noreg, rax, Address::times_ptr); - __ movptr(rax, ArrayAddress(stack_to_native, Address(noreg, rax, Address::times_4))); + __ movptr(rax, ArrayAddress(stack_to_native, Address(noreg, rax, Address::times_ptr))); __ call(rax); // call result converter Label unwind_initial_activation; @@ -1964,11 +2046,11 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { // return restoring the stack to the original sender_sp value - __ movl(rcx, STATE(_sender_sp)); + __ movptr(rcx, STATE(_sender_sp)); __ leave(); - __ popl(rdi); // get return address + __ pop(rdi); // get return address // set stack to sender's sp - __ movl(rsp, rcx); + __ mov(rsp, rcx); __ jmp(rdi); // return to call_stub // OSR request, adjust return address to make current frame into adapter frame @@ -1982,17 +2064,16 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { // it or is it callstub/compiled? // Move buffer to the expected parameter location - __ movl(rcx, STATE(_result._osr._osr_buf)); + __ movptr(rcx, STATE(_result._osr._osr_buf)); - __ movl(rax, STATE(_result._osr._osr_entry)); + __ movptr(rax, STATE(_result._osr._osr_entry)); - __ cmpl(STATE(_prev_link), (int)NULL); // returning from "recursive" interpreter call? + __ cmpptr(STATE(_prev_link), (int32_t)NULL_WORD); // returning from "recursive" interpreter call? __ jcc(Assembler::equal, remove_initial_frame); // back to native code (call_stub/c1/c2) - // __ movl(state, STATE(_prev_link)); // unwind state - __ movl(rsi, STATE(_sender_sp)); // get sender's sp in expected register + __ movptr(sender_sp_on_entry, STATE(_sender_sp)); // get sender's sp in expected register __ leave(); // pop the frame - __ movl(rsp, rsi); // trim any stack expansion + __ mov(rsp, sender_sp_on_entry); // trim any stack expansion // We know we are calling compiled so push specialized return @@ -2006,14 +2087,14 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { __ bind(remove_initial_frame); - __ movl(rdx, STATE(_sender_sp)); + __ movptr(rdx, STATE(_sender_sp)); __ leave(); // get real return - __ popl(rsi); + __ pop(rsi); // set stack to sender's sp - __ movl(rsp, rdx); + __ mov(rsp, rdx); // repush real return - __ pushl(rsi); + __ push(rsi); // Enter OSR nmethod __ jmp(rax); @@ -2028,10 +2109,10 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { // stack points to next free location and not top element on expression stack // method expects sp to be pointing to topmost element - __ movl(rsp, STATE(_stack)); // pop args to c++ interpreter, set sp to java stack top - __ leal(rsp, Address(rsp, wordSize)); + __ movptr(rsp, STATE(_stack)); // pop args to c++ interpreter, set sp to java stack top + __ lea(rsp, Address(rsp, wordSize)); - __ movl(rbx, STATE(_result._to_call._callee)); // get method to execute + __ movptr(rbx, STATE(_result._to_call._callee)); // get method to execute // don't need a return address if reinvoking interpreter @@ -2047,13 +2128,13 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { __ cmpptr(STATE(_result._to_call._callee_entry_point), entry.addr()); // returning to interpreter? __ jcc(Assembler::equal, re_dispatch); // yes - __ popl(rax); // pop dummy address + __ pop(rax); // pop dummy address // get specialized entry - __ movl(rax, STATE(_result._to_call._callee_entry_point)); + __ movptr(rax, STATE(_result._to_call._callee_entry_point)); // set sender SP - __ movl(rsi, rsp); + __ mov(sender_sp_on_entry, rsp); // method uses specialized entry, push a return so we look like call stub setup // this path will handle fact that result is returned in registers and not @@ -2073,10 +2154,10 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { Label unwind_initial_with_pending_exception; __ bind(throw_exception); - __ cmpl(STATE(_prev_link), (int)NULL); // returning from recursive interpreter call? + __ cmpptr(STATE(_prev_link), (int32_t)NULL_WORD); // returning from recursive interpreter call? __ jcc(Assembler::equal, unwind_initial_with_pending_exception); // no, back to native code (call_stub/c1/c2) - __ movl(rax, STATE(_locals)); // pop parameters get new stack value - __ addl(rax, wordSize); // account for prepush before we return + __ movptr(rax, STATE(_locals)); // pop parameters get new stack value + __ addptr(rax, wordSize); // account for prepush before we return __ jmp(unwind_recursive_activation); __ bind(unwind_initial_with_pending_exception); diff --git a/hotspot/src/cpu/x86/vm/dump_x86_32.cpp b/hotspot/src/cpu/x86/vm/dump_x86_32.cpp index db80c6367f7..8bb427e3b89 100644 --- a/hotspot/src/cpu/x86/vm/dump_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/dump_x86_32.cpp @@ -98,24 +98,24 @@ void CompactingPermGenGen::generate_vtable_methods(void** vtbl_list, // table. #ifdef WIN32 - __ pushl(rcx); // save "this" + __ push(rcx); // save "this" #endif - __ movl(rcx, rax); - __ shrl(rcx, 8); // isolate vtable identifier. - __ shll(rcx, LogBytesPerWord); + __ mov(rcx, rax); + __ shrptr(rcx, 8); // isolate vtable identifier. + __ shlptr(rcx, LogBytesPerWord); Address index(noreg, rcx, Address::times_1); ExternalAddress vtbl((address)vtbl_list); __ movptr(rdx, ArrayAddress(vtbl, index)); // get correct vtable address. #ifdef WIN32 - __ popl(rcx); // restore "this" + __ pop(rcx); // restore "this" #else - __ movl(rcx, Address(rsp, 4)); // fetch "this" + __ movptr(rcx, Address(rsp, BytesPerWord)); // fetch "this" #endif - __ movl(Address(rcx, 0), rdx); // update vtable pointer. + __ movptr(Address(rcx, 0), rdx); // update vtable pointer. - __ andl(rax, 0x00ff); // isolate vtable method index - __ shll(rax, LogBytesPerWord); - __ addl(rax, rdx); // address of real method pointer. + __ andptr(rax, 0x00ff); // isolate vtable method index + __ shlptr(rax, LogBytesPerWord); + __ addptr(rax, rdx); // address of real method pointer. __ jmp(Address(rax, 0)); // get real method pointer. __ flush(); diff --git a/hotspot/src/cpu/x86/vm/dump_x86_64.cpp b/hotspot/src/cpu/x86/vm/dump_x86_64.cpp index 7e80bbeacf2..3a8b02e64e7 100644 --- a/hotspot/src/cpu/x86/vm/dump_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/dump_x86_64.cpp @@ -90,22 +90,22 @@ void CompactingPermGenGen::generate_vtable_methods(void** vtbl_list, // are on the stack and the "this" pointer is in c_rarg0. In addition, rax // was set (above) to the offset of the method in the table. - __ pushq(c_rarg1); // save & free register - __ pushq(c_rarg0); // save "this" - __ movq(c_rarg0, rax); - __ shrq(c_rarg0, 8); // isolate vtable identifier. - __ shlq(c_rarg0, LogBytesPerWord); + __ push(c_rarg1); // save & free register + __ push(c_rarg0); // save "this" + __ mov(c_rarg0, rax); + __ shrptr(c_rarg0, 8); // isolate vtable identifier. + __ shlptr(c_rarg0, LogBytesPerWord); __ lea(c_rarg1, ExternalAddress((address)vtbl_list)); // ptr to correct vtable list. - __ addq(c_rarg1, c_rarg0); // ptr to list entry. - __ movq(c_rarg1, Address(c_rarg1, 0)); // get correct vtable address. - __ popq(c_rarg0); // restore "this" - __ movq(Address(c_rarg0, 0), c_rarg1); // update vtable pointer. + __ addptr(c_rarg1, c_rarg0); // ptr to list entry. + __ movptr(c_rarg1, Address(c_rarg1, 0)); // get correct vtable address. + __ pop(c_rarg0); // restore "this" + __ movptr(Address(c_rarg0, 0), c_rarg1); // update vtable pointer. - __ andq(rax, 0x00ff); // isolate vtable method index - __ shlq(rax, LogBytesPerWord); - __ addq(rax, c_rarg1); // address of real method pointer. - __ popq(c_rarg1); // restore register. - __ movq(rax, Address(rax, 0)); // get real method pointer. + __ andptr(rax, 0x00ff); // isolate vtable method index + __ shlptr(rax, LogBytesPerWord); + __ addptr(rax, c_rarg1); // address of real method pointer. + __ pop(c_rarg1); // restore register. + __ movptr(rax, Address(rax, 0)); // get real method pointer. __ jmp(rax); // jump to the real method. __ flush(); diff --git a/hotspot/src/cpu/x86/vm/frame_x86.cpp b/hotspot/src/cpu/x86/vm/frame_x86.cpp index 9fe370e85de..4df2c039dc1 100644 --- a/hotspot/src/cpu/x86/vm/frame_x86.cpp +++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp @@ -217,7 +217,8 @@ bool frame::safe_for_sender(JavaThread *thread) { void frame::patch_pc(Thread* thread, address pc) { if (TracePcPatching) { - tty->print_cr("patch_pc at address 0x%x [0x%x -> 0x%x] ", &((address *)sp())[-1], ((address *)sp())[-1], pc); + tty->print_cr("patch_pc at address" INTPTR_FORMAT " [" INTPTR_FORMAT " -> " INTPTR_FORMAT "] ", + &((address *)sp())[-1], ((address *)sp())[-1], pc); } ((address *)sp())[-1] = pc; _cb = CodeCache::find_blob(pc); diff --git a/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp b/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp index 85a1944bd44..f06b40de350 100644 --- a/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp +++ b/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp @@ -159,7 +159,7 @@ inline intptr_t** frame::interpreter_frame_locals_addr() const { inline intptr_t* frame::interpreter_frame_bcx_addr() const { assert(is_interpreted_frame(), "must be interpreted"); - return (jint*) &(get_interpreterState()->_bcp); + return (intptr_t*) &(get_interpreterState()->_bcp); } @@ -179,7 +179,7 @@ inline methodOop* frame::interpreter_frame_method_addr() const { inline intptr_t* frame::interpreter_frame_mdx_addr() const { assert(is_interpreted_frame(), "must be interpreted"); - return (jint*) &(get_interpreterState()->_mdx); + return (intptr_t*) &(get_interpreterState()->_mdx); } // top of expression stack diff --git a/hotspot/src/cpu/x86/vm/icache_x86.cpp b/hotspot/src/cpu/x86/vm/icache_x86.cpp index 6a031f07413..f48926228b9 100644 --- a/hotspot/src/cpu/x86/vm/icache_x86.cpp +++ b/hotspot/src/cpu/x86/vm/icache_x86.cpp @@ -48,7 +48,7 @@ void ICacheStubGenerator::generate_icache_flush(ICache::flush_icache_stub_t* flu __ bind(flush_line); __ clflush(Address(addr, 0)); - __ addq(addr, ICache::line_size); + __ addptr(addr, ICache::line_size); __ decrementl(lines); __ jcc(Assembler::notZero, flush_line); @@ -60,7 +60,7 @@ void ICacheStubGenerator::generate_icache_flush(ICache::flush_icache_stub_t* flu const Address magic(rsp, 3*wordSize); __ lock(); __ addl(Address(rsp, 0), 0); #endif // AMD64 - __ movl(rax, magic); // Handshake with caller to make sure it happened! + __ movptr(rax, magic); // Handshake with caller to make sure it happened! __ ret(0); // Must be set here so StubCodeMark destructor can call the flush stub. diff --git a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp index 4b174357a2f..3e6e35eb9d4 100644 --- a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp @@ -29,8 +29,8 @@ // Implementation of InterpreterMacroAssembler #ifdef CC_INTERP void InterpreterMacroAssembler::get_method(Register reg) { - movl(reg, Address(rbp, -(sizeof(BytecodeInterpreter) + 2 * wordSize))); - movl(reg, Address(reg, byte_offset_of(BytecodeInterpreter, _method))); + movptr(reg, Address(rbp, -(sizeof(BytecodeInterpreter) + 2 * wordSize))); + movptr(reg, Address(reg, byte_offset_of(BytecodeInterpreter, _method))); } #endif // CC_INTERP @@ -53,7 +53,7 @@ void InterpreterMacroAssembler::call_VM_leaf_base( // when jvm built with ASSERTs. #ifdef ASSERT { Label L; - cmpl(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + cmpptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); jcc(Assembler::equal, L); stop("InterpreterMacroAssembler::call_VM_leaf_base: last_sp != NULL"); bind(L); @@ -79,7 +79,7 @@ void InterpreterMacroAssembler::call_VM_base( ) { #ifdef ASSERT { Label L; - cmpl(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + cmpptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); jcc(Assembler::equal, L); stop("InterpreterMacroAssembler::call_VM_base: last_sp != NULL"); bind(L); @@ -132,10 +132,11 @@ void InterpreterMacroAssembler::load_earlyret_value(TosState state) { const Address val_addr1(rcx, JvmtiThreadState::earlyret_value_offset() + in_ByteSize(wordSize)); switch (state) { - case atos: movl(rax, oop_addr); - movl(oop_addr, NULL_WORD); + case atos: movptr(rax, oop_addr); + movptr(oop_addr, (int32_t)NULL_WORD); verify_oop(rax, state); break; - case ltos: movl(rdx, val_addr1); // fall through + case ltos: + movl(rdx, val_addr1); // fall through case btos: // fall through case ctos: // fall through case stos: // fall through @@ -146,9 +147,9 @@ void InterpreterMacroAssembler::load_earlyret_value(TosState state) { default : ShouldNotReachHere(); } // Clean up tos value in the thread object - movl(tos_addr, (int) ilgl); - movl(val_addr, NULL_WORD); - movl(val_addr1, NULL_WORD); + movl(tos_addr, (int32_t) ilgl); + movptr(val_addr, (int32_t)NULL_WORD); + NOT_LP64(movl(val_addr1, (int32_t)NULL_WORD)); } @@ -156,8 +157,8 @@ void InterpreterMacroAssembler::check_and_handle_earlyret(Register java_thread) if (JvmtiExport::can_force_early_return()) { Label L; Register tmp = java_thread; - movl(tmp, Address(tmp, JavaThread::jvmti_thread_state_offset())); - testl(tmp, tmp); + movptr(tmp, Address(tmp, JavaThread::jvmti_thread_state_offset())); + testptr(tmp, tmp); jcc(Assembler::zero, L); // if (thread->jvmti_thread_state() == NULL) exit; // Initiate earlyret handling only if it is not already being processed. @@ -170,7 +171,7 @@ void InterpreterMacroAssembler::check_and_handle_earlyret(Register java_thread) // Call Interpreter::remove_activation_early_entry() to get the address of the // same-named entrypoint in the generated interpreter code. get_thread(java_thread); - movl(tmp, Address(java_thread, JavaThread::jvmti_thread_state_offset())); + movptr(tmp, Address(java_thread, JavaThread::jvmti_thread_state_offset())); pushl(Address(tmp, JvmtiThreadState::earlyret_tos_offset())); call_VM_leaf(CAST_FROM_FN_PTR(address, Interpreter::remove_activation_early_entry), 1); jmp(rax); @@ -183,7 +184,7 @@ void InterpreterMacroAssembler::check_and_handle_earlyret(Register java_thread) void InterpreterMacroAssembler::get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset) { assert(bcp_offset >= 0, "bcp is still pointing to start of bytecode"); movl(reg, Address(rsi, bcp_offset)); - bswap(reg); + bswapl(reg); shrl(reg, 16); } @@ -192,9 +193,9 @@ void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, Regis assert(bcp_offset > 0, "bcp is still pointing to start of bytecode"); assert(cache != index, "must use different registers"); load_unsigned_word(index, Address(rsi, bcp_offset)); - movl(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); + movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); assert(sizeof(ConstantPoolCacheEntry) == 4*wordSize, "adjust code below"); - shll(index, 2); // convert from field index to ConstantPoolCacheEntry index + shlptr(index, 2); // convert from field index to ConstantPoolCacheEntry index } @@ -206,10 +207,10 @@ void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache, R // convert from field index to ConstantPoolCacheEntry index // and from word offset to byte offset shll(tmp, 2 + LogBytesPerWord); - movl(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); + movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); // skip past the header - addl(cache, in_bytes(constantPoolCacheOopDesc::base_offset())); - addl(cache, tmp); // construct pointer to cache entry + addptr(cache, in_bytes(constantPoolCacheOopDesc::base_offset())); + addptr(cache, tmp); // construct pointer to cache entry } @@ -232,22 +233,22 @@ void InterpreterMacroAssembler::gen_subtype_check( Register Rsub_klass, Label &o // if the super-klass is an interface or exceptionally deep in the Java // hierarchy and we have to scan the secondary superclass list the hard way. // See if we get an immediate positive hit - cmpl( rax, Address(Rsub_klass,rcx,Address::times_1) ); + cmpptr( rax, Address(Rsub_klass,rcx,Address::times_1) ); jcc( Assembler::equal,ok_is_subtype ); // Check for immediate negative hit cmpl( rcx, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() ); jcc( Assembler::notEqual, not_subtype ); // Check for self - cmpl( Rsub_klass, rax ); + cmpptr( Rsub_klass, rax ); jcc( Assembler::equal, ok_is_subtype ); // Now do a linear scan of the secondary super-klass chain. - movl( rdi, Address(Rsub_klass, sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes()) ); + movptr( rdi, Address(Rsub_klass, sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes()) ); // EDI holds the objArrayOop of secondary supers. movl( rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes()));// Load the array length // Skip to start of data; also clear Z flag incase ECX is zero - addl( rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT) ); + addptr( rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT) ); // Scan ECX words at [EDI] for occurance of EAX // Set NZ/Z based on last compare repne_scan(); @@ -255,7 +256,7 @@ void InterpreterMacroAssembler::gen_subtype_check( Register Rsub_klass, Label &o // Not equal? jcc( Assembler::notEqual, not_subtype ); // Must be equal but missed in cache. Update cache. - movl( Address(Rsub_klass, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()), rax ); + movptr( Address(Rsub_klass, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()), rax ); jmp( ok_is_subtype ); bind(not_subtype); @@ -276,7 +277,6 @@ void InterpreterMacroAssembler::d2ieee() { fld_d(Address(rsp, 0)); } } -#endif // CC_INTERP // Java Expression Stack @@ -284,11 +284,11 @@ void InterpreterMacroAssembler::d2ieee() { void InterpreterMacroAssembler::verify_stack_tag(frame::Tag t) { if (TaggedStackInterpreter) { Label okay; - cmpl(Address(rsp, wordSize), (int)t); + cmpptr(Address(rsp, wordSize), (int32_t)t); jcc(Assembler::equal, okay); // Also compare if the stack value is zero, then the tag might // not have been set coming from deopt. - cmpl(Address(rsp, 0), 0); + cmpptr(Address(rsp, 0), 0); jcc(Assembler::equal, okay); stop("Java Expression stack tag value is bad"); bind(okay); @@ -298,43 +298,43 @@ void InterpreterMacroAssembler::verify_stack_tag(frame::Tag t) { void InterpreterMacroAssembler::pop_ptr(Register r) { debug_only(verify_stack_tag(frame::TagReference)); - popl(r); - if (TaggedStackInterpreter) addl(rsp, 1 * wordSize); + pop(r); + if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); } void InterpreterMacroAssembler::pop_ptr(Register r, Register tag) { - popl(r); + pop(r); // Tag may not be reference for jsr, can be returnAddress - if (TaggedStackInterpreter) popl(tag); + if (TaggedStackInterpreter) pop(tag); } void InterpreterMacroAssembler::pop_i(Register r) { debug_only(verify_stack_tag(frame::TagValue)); - popl(r); - if (TaggedStackInterpreter) addl(rsp, 1 * wordSize); + pop(r); + if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); } void InterpreterMacroAssembler::pop_l(Register lo, Register hi) { debug_only(verify_stack_tag(frame::TagValue)); - popl(lo); - if (TaggedStackInterpreter) addl(rsp, 1 * wordSize); + pop(lo); + if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); debug_only(verify_stack_tag(frame::TagValue)); - popl(hi); - if (TaggedStackInterpreter) addl(rsp, 1 * wordSize); + pop(hi); + if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); } void InterpreterMacroAssembler::pop_f() { debug_only(verify_stack_tag(frame::TagValue)); fld_s(Address(rsp, 0)); - addl(rsp, 1 * wordSize); - if (TaggedStackInterpreter) addl(rsp, 1 * wordSize); + addptr(rsp, 1 * wordSize); + if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); } void InterpreterMacroAssembler::pop_d() { // Write double to stack contiguously and load into ST0 pop_dtos_to_rsp(); fld_d(Address(rsp, 0)); - addl(rsp, 2 * wordSize); + addptr(rsp, 2 * wordSize); } @@ -344,22 +344,22 @@ void InterpreterMacroAssembler::pop_dtos_to_rsp() { if (TaggedStackInterpreter) { // Pop double value into scratch registers debug_only(verify_stack_tag(frame::TagValue)); - popl(rax); - addl(rsp, 1* wordSize); + pop(rax); + addptr(rsp, 1* wordSize); debug_only(verify_stack_tag(frame::TagValue)); - popl(rdx); - addl(rsp, 1* wordSize); - pushl(rdx); - pushl(rax); + pop(rdx); + addptr(rsp, 1* wordSize); + push(rdx); + push(rax); } } void InterpreterMacroAssembler::pop_ftos_to_rsp() { if (TaggedStackInterpreter) { debug_only(verify_stack_tag(frame::TagValue)); - popl(rax); - addl(rsp, 1 * wordSize); - pushl(rax); // ftos is at rsp + pop(rax); + addptr(rsp, 1 * wordSize); + push(rax); // ftos is at rsp } } @@ -380,31 +380,31 @@ void InterpreterMacroAssembler::pop(TosState state) { } void InterpreterMacroAssembler::push_ptr(Register r) { - if (TaggedStackInterpreter) pushl(frame::TagReference); - pushl(r); + if (TaggedStackInterpreter) push(frame::TagReference); + push(r); } void InterpreterMacroAssembler::push_ptr(Register r, Register tag) { - if (TaggedStackInterpreter) pushl(tag); // tag first - pushl(r); + if (TaggedStackInterpreter) push(tag); // tag first + push(r); } void InterpreterMacroAssembler::push_i(Register r) { - if (TaggedStackInterpreter) pushl(frame::TagValue); - pushl(r); + if (TaggedStackInterpreter) push(frame::TagValue); + push(r); } void InterpreterMacroAssembler::push_l(Register lo, Register hi) { - if (TaggedStackInterpreter) pushl(frame::TagValue); - pushl(hi); - if (TaggedStackInterpreter) pushl(frame::TagValue); - pushl(lo); + if (TaggedStackInterpreter) push(frame::TagValue); + push(hi); + if (TaggedStackInterpreter) push(frame::TagValue); + push(lo); } void InterpreterMacroAssembler::push_f() { - if (TaggedStackInterpreter) pushl(frame::TagValue); + if (TaggedStackInterpreter) push(frame::TagValue); // Do not schedule for no AGI! Never write beyond rsp! - subl(rsp, 1 * wordSize); + subptr(rsp, 1 * wordSize); fstp_s(Address(rsp, 0)); } @@ -415,8 +415,8 @@ void InterpreterMacroAssembler::push_d(Register r) { // high // tag // low - pushl(frame::TagValue); - subl(rsp, 3 * wordSize); + push(frame::TagValue); + subptr(rsp, 3 * wordSize); fstp_d(Address(rsp, 0)); // move high word up to slot n-1 movl(r, Address(rsp, 1*wordSize)); @@ -425,7 +425,7 @@ void InterpreterMacroAssembler::push_d(Register r) { movl(Address(rsp, 1*wordSize), frame::TagValue); } else { // Do not schedule for no AGI! Never write beyond rsp! - subl(rsp, 2 * wordSize); + subptr(rsp, 2 * wordSize); fstp_d(Address(rsp, 0)); } } @@ -447,22 +447,21 @@ void InterpreterMacroAssembler::push(TosState state) { } } -#ifndef CC_INTERP // Tagged stack helpers for swap and dup void InterpreterMacroAssembler::load_ptr_and_tag(int n, Register val, Register tag) { - movl(val, Address(rsp, Interpreter::expr_offset_in_bytes(n))); + movptr(val, Address(rsp, Interpreter::expr_offset_in_bytes(n))); if (TaggedStackInterpreter) { - movl(tag, Address(rsp, Interpreter::expr_tag_offset_in_bytes(n))); + movptr(tag, Address(rsp, Interpreter::expr_tag_offset_in_bytes(n))); } } void InterpreterMacroAssembler::store_ptr_and_tag(int n, Register val, Register tag) { - movl(Address(rsp, Interpreter::expr_offset_in_bytes(n)), val); + movptr(Address(rsp, Interpreter::expr_offset_in_bytes(n)), val); if (TaggedStackInterpreter) { - movl(Address(rsp, Interpreter::expr_tag_offset_in_bytes(n)), tag); + movptr(Address(rsp, Interpreter::expr_tag_offset_in_bytes(n)), tag); } } @@ -471,10 +470,10 @@ void InterpreterMacroAssembler::store_ptr_and_tag(int n, Register val, void InterpreterMacroAssembler::tag_local(frame::Tag tag, int n) { if (TaggedStackInterpreter) { if (tag == frame::TagCategory2) { - movl(Address(rdi, Interpreter::local_tag_offset_in_bytes(n+1)), (int)frame::TagValue); - movl(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int)frame::TagValue); + movptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n+1)), (int32_t)frame::TagValue); + movptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)frame::TagValue); } else { - movl(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int)tag); + movptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)tag); } } } @@ -482,13 +481,13 @@ void InterpreterMacroAssembler::tag_local(frame::Tag tag, int n) { void InterpreterMacroAssembler::tag_local(frame::Tag tag, Register idx) { if (TaggedStackInterpreter) { if (tag == frame::TagCategory2) { - movl(Address(rdi, idx, Interpreter::stackElementScale(), - Interpreter::local_tag_offset_in_bytes(1)), (int)frame::TagValue); - movl(Address(rdi, idx, Interpreter::stackElementScale(), - Interpreter::local_tag_offset_in_bytes(0)), (int)frame::TagValue); + movptr(Address(rdi, idx, Interpreter::stackElementScale(), + Interpreter::local_tag_offset_in_bytes(1)), (int32_t)frame::TagValue); + movptr(Address(rdi, idx, Interpreter::stackElementScale(), + Interpreter::local_tag_offset_in_bytes(0)), (int32_t)frame::TagValue); } else { - movl(Address(rdi, idx, Interpreter::stackElementScale(), - Interpreter::local_tag_offset_in_bytes(0)), (int)tag); + movptr(Address(rdi, idx, Interpreter::stackElementScale(), + Interpreter::local_tag_offset_in_bytes(0)), (int32_t)tag); } } } @@ -496,7 +495,7 @@ void InterpreterMacroAssembler::tag_local(frame::Tag tag, Register idx) { void InterpreterMacroAssembler::tag_local(Register tag, Register idx) { if (TaggedStackInterpreter) { // can only be TagValue or TagReference - movl(Address(rdi, idx, Interpreter::stackElementScale(), + movptr(Address(rdi, idx, Interpreter::stackElementScale(), Interpreter::local_tag_offset_in_bytes(0)), tag); } } @@ -505,7 +504,7 @@ void InterpreterMacroAssembler::tag_local(Register tag, Register idx) { void InterpreterMacroAssembler::tag_local(Register tag, int n) { if (TaggedStackInterpreter) { // can only be TagValue or TagReference - movl(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), tag); + movptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), tag); } } @@ -516,17 +515,17 @@ void InterpreterMacroAssembler::verify_local_tag(frame::Tag tag, int n) { if (tag == frame::TagCategory2) { Label nbl; t = frame::TagValue; // change to what is stored in locals - cmpl(Address(rdi, Interpreter::local_tag_offset_in_bytes(n+1)), (int)t); + cmpptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n+1)), (int32_t)t); jcc(Assembler::equal, nbl); stop("Local tag is bad for long/double"); bind(nbl); } Label notBad; - cmpl(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int)t); + cmpptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)t); jcc(Assembler::equal, notBad); // Also compare if the local value is zero, then the tag might // not have been set coming from deopt. - cmpl(Address(rdi, Interpreter::local_offset_in_bytes(n)), 0); + cmpptr(Address(rdi, Interpreter::local_offset_in_bytes(n)), 0); jcc(Assembler::equal, notBad); stop("Local tag is bad"); bind(notBad); @@ -539,19 +538,19 @@ void InterpreterMacroAssembler::verify_local_tag(frame::Tag tag, Register idx) { if (tag == frame::TagCategory2) { Label nbl; t = frame::TagValue; // change to what is stored in locals - cmpl(Address(rdi, idx, Interpreter::stackElementScale(), - Interpreter::local_tag_offset_in_bytes(1)), (int)t); + cmpptr(Address(rdi, idx, Interpreter::stackElementScale(), + Interpreter::local_tag_offset_in_bytes(1)), (int32_t)t); jcc(Assembler::equal, nbl); stop("Local tag is bad for long/double"); bind(nbl); } Label notBad; cmpl(Address(rdi, idx, Interpreter::stackElementScale(), - Interpreter::local_tag_offset_in_bytes(0)), (int)t); + Interpreter::local_tag_offset_in_bytes(0)), (int32_t)t); jcc(Assembler::equal, notBad); // Also compare if the local value is zero, then the tag might // not have been set coming from deopt. - cmpl(Address(rdi, idx, Interpreter::stackElementScale(), + cmpptr(Address(rdi, idx, Interpreter::stackElementScale(), Interpreter::local_offset_in_bytes(0)), 0); jcc(Assembler::equal, notBad); stop("Local tag is bad"); @@ -567,22 +566,22 @@ void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point) { void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, Register arg_1) { - pushl(arg_1); + push(arg_1); MacroAssembler::call_VM_leaf_base(entry_point, 1); } void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, Register arg_1, Register arg_2) { - pushl(arg_2); - pushl(arg_1); + push(arg_2); + push(arg_1); MacroAssembler::call_VM_leaf_base(entry_point, 2); } void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, Register arg_1, Register arg_2, Register arg_3) { - pushl(arg_3); - pushl(arg_2); - pushl(arg_1); + push(arg_3); + push(arg_2); + push(arg_1); MacroAssembler::call_VM_leaf_base(entry_point, 3); } @@ -591,9 +590,9 @@ void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, Register // in this thread in which case we must call the i2i entry void InterpreterMacroAssembler::jump_from_interpreted(Register method, Register temp) { // set sender sp - leal(rsi, Address(rsp, wordSize)); + lea(rsi, Address(rsp, wordSize)); // record last_sp - movl(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), rsi); + movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), rsi); if (JvmtiExport::can_post_interpreter_events()) { Label run_compiled_code; @@ -629,16 +628,16 @@ void InterpreterMacroAssembler::dispatch_base(TosState state, address* table, verify_FPU(1, state); if (VerifyActivationFrameSize) { Label L; - movl(rcx, rbp); - subl(rcx, rsp); + mov(rcx, rbp); + subptr(rcx, rsp); int min_frame_size = (frame::link_offset - frame::interpreter_frame_initial_sp_offset) * wordSize; - cmpl(rcx, min_frame_size); + cmpptr(rcx, min_frame_size); jcc(Assembler::greaterEqual, L); stop("broken stack frame"); bind(L); } if (verifyoop) verify_oop(rax, state); - Address index(noreg, rbx, Address::times_4); + Address index(noreg, rbx, Address::times_ptr); ExternalAddress tbl((address)table); ArrayAddress dispatch(tbl, index); jump(dispatch); @@ -700,10 +699,10 @@ void InterpreterMacroAssembler::remove_activation(TosState state, Register ret_a in_bytes(JavaThread::do_not_unlock_if_synchronized_offset())); movbool(rbx, do_not_unlock_if_synchronized); - movl(rdi,rbx); + mov(rdi,rbx); movbool(do_not_unlock_if_synchronized, false); // reset the flag - movl(rbx, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); // get method access flags + movptr(rbx, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); // get method access flags movl(rcx, Address(rbx, methodOopDesc::access_flags_offset())); testl(rcx, JVM_ACC_SYNCHRONIZED); @@ -711,7 +710,7 @@ void InterpreterMacroAssembler::remove_activation(TosState state, Register ret_a // Don't unlock anything if the _do_not_unlock_if_synchronized flag // is set. - movl(rcx,rdi); + mov(rcx,rdi); testbool(rcx); jcc(Assembler::notZero, no_unlock); @@ -721,11 +720,11 @@ void InterpreterMacroAssembler::remove_activation(TosState state, Register ret_a // BasicObjectLock will be first in list, since this is a synchronized method. However, need // to check that the object has not been unlocked by an explicit monitorexit bytecode. const Address monitor(rbp, frame::interpreter_frame_initial_sp_offset * wordSize - (int)sizeof(BasicObjectLock)); - leal (rdx, monitor); // address of first monitor + lea (rdx, monitor); // address of first monitor - movl (rax, Address(rdx, BasicObjectLock::obj_offset_in_bytes())); - testl (rax, rax); - jcc (Assembler::notZero, unlock); + movptr (rax, Address(rdx, BasicObjectLock::obj_offset_in_bytes())); + testptr(rax, rax); + jcc (Assembler::notZero, unlock); pop(state); if (throw_monitor_exception) { @@ -762,8 +761,8 @@ void InterpreterMacroAssembler::remove_activation(TosState state, Register ret_a const Address monitor_block_bot(rbp, frame::interpreter_frame_initial_sp_offset * wordSize); bind(restart); - movl(rcx, monitor_block_top); // points to current entry, starting with top-most entry - leal(rbx, monitor_block_bot); // points to word before bottom of monitor block + movptr(rcx, monitor_block_top); // points to current entry, starting with top-most entry + lea(rbx, monitor_block_bot); // points to word before bottom of monitor block jmp(entry); // Entry already locked, need to throw exception @@ -780,7 +779,7 @@ void InterpreterMacroAssembler::remove_activation(TosState state, Register ret_a // Unlock does not block, so don't have to worry about the frame push(state); - movl(rdx, rcx); + mov(rdx, rcx); unlock_object(rdx); pop(state); @@ -793,12 +792,12 @@ void InterpreterMacroAssembler::remove_activation(TosState state, Register ret_a } bind(loop); - cmpl(Address(rcx, BasicObjectLock::obj_offset_in_bytes()), NULL_WORD); // check if current entry is used + cmpptr(Address(rcx, BasicObjectLock::obj_offset_in_bytes()), (int32_t)NULL_WORD); // check if current entry is used jcc(Assembler::notEqual, exception); - addl(rcx, entry_size); // otherwise advance to next entry + addptr(rcx, entry_size); // otherwise advance to next entry bind(entry); - cmpl(rcx, rbx); // check if bottom reached + cmpptr(rcx, rbx); // check if bottom reached jcc(Assembler::notEqual, loop); // if not at bottom then check this entry } @@ -812,22 +811,22 @@ void InterpreterMacroAssembler::remove_activation(TosState state, Register ret_a } // remove activation - movl(rbx, Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); // get sender sp + movptr(rbx, Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); // get sender sp leave(); // remove frame anchor - popl(ret_addr); // get return address - movl(rsp, rbx); // set sp to sender sp + pop(ret_addr); // get return address + mov(rsp, rbx); // set sp to sender sp if (UseSSE) { // float and double are returned in xmm register in SSE-mode if (state == ftos && UseSSE >= 1) { - subl(rsp, wordSize); + subptr(rsp, wordSize); fstp_s(Address(rsp, 0)); movflt(xmm0, Address(rsp, 0)); - addl(rsp, wordSize); + addptr(rsp, wordSize); } else if (state == dtos && UseSSE >= 2) { - subl(rsp, 2*wordSize); + subptr(rsp, 2*wordSize); fstp_d(Address(rsp, 0)); movdbl(xmm0, Address(rsp, 0)); - addl(rsp, 2*wordSize); + addptr(rsp, 2*wordSize); } } } @@ -858,7 +857,7 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg) { Label slow_case; // Load object pointer into obj_reg %rcx - movl(obj_reg, Address(lock_reg, obj_offset)); + movptr(obj_reg, Address(lock_reg, obj_offset)); if (UseBiasedLocking) { // Note: we use noreg for the temporary register since it's hard @@ -867,19 +866,19 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg) { } // Load immediate 1 into swap_reg %rax, - movl(swap_reg, 1); + movptr(swap_reg, (int32_t)1); // Load (object->mark() | 1) into swap_reg %rax, - orl(swap_reg, Address(obj_reg, 0)); + orptr(swap_reg, Address(obj_reg, 0)); // Save (object->mark() | 1) into BasicLock's displaced header - movl(Address(lock_reg, mark_offset), swap_reg); + movptr(Address(lock_reg, mark_offset), swap_reg); assert(lock_offset == 0, "displached header must be first word in BasicObjectLock"); if (os::is_MP()) { lock(); } - cmpxchg(lock_reg, Address(obj_reg, 0)); + cmpxchgptr(lock_reg, Address(obj_reg, 0)); if (PrintBiasedLockingStatistics) { cond_inc32(Assembler::zero, ExternalAddress((address) BiasedLocking::fast_path_entry_count_addr())); @@ -895,11 +894,11 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg) { // assuming both stack pointer and pagesize have their // least significant 2 bits clear. // NOTE: the oopMark is in swap_reg %rax, as the result of cmpxchg - subl(swap_reg, rsp); - andl(swap_reg, 3 - os::vm_page_size()); + subptr(swap_reg, rsp); + andptr(swap_reg, 3 - os::vm_page_size()); // Save the test result, for recursive case, the result is zero - movl(Address(lock_reg, mark_offset), swap_reg); + movptr(Address(lock_reg, mark_offset), swap_reg); if (PrintBiasedLockingStatistics) { cond_inc32(Assembler::zero, @@ -939,36 +938,36 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg) { // Convert from BasicObjectLock structure to object and BasicLock structure // Store the BasicLock address into %rax, - leal(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset_in_bytes())); + lea(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset_in_bytes())); // Load oop into obj_reg(%rcx) - movl(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes ())); + movptr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes ())); // Free entry - movl(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), NULL_WORD); + movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), (int32_t)NULL_WORD); if (UseBiasedLocking) { biased_locking_exit(obj_reg, header_reg, done); } // Load the old header from BasicLock structure - movl(header_reg, Address(swap_reg, BasicLock::displaced_header_offset_in_bytes())); + movptr(header_reg, Address(swap_reg, BasicLock::displaced_header_offset_in_bytes())); // Test for recursion - testl(header_reg, header_reg); + testptr(header_reg, header_reg); // zero for recursive case jcc(Assembler::zero, done); // Atomic swap back the old header if (os::is_MP()) lock(); - cmpxchg(header_reg, Address(obj_reg, 0)); + cmpxchgptr(header_reg, Address(obj_reg, 0)); // zero for recursive case jcc(Assembler::zero, done); // Call the runtime routine for slow case. - movl(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), obj_reg); // restore obj + movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), obj_reg); // restore obj call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg); bind(done); @@ -983,8 +982,8 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg) { // Test ImethodDataPtr. If it is null, continue at the specified label void InterpreterMacroAssembler::test_method_data_pointer(Register mdp, Label& zero_continue) { assert(ProfileInterpreter, "must be profiling interpreter"); - movl(mdp, Address(rbp, frame::interpreter_frame_mdx_offset * wordSize)); - testl(mdp, mdp); + movptr(mdp, Address(rbp, frame::interpreter_frame_mdx_offset * wordSize)); + testptr(mdp, mdp); jcc(Assembler::zero, zero_continue); } @@ -993,13 +992,13 @@ void InterpreterMacroAssembler::test_method_data_pointer(Register mdp, Label& ze void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() { assert(ProfileInterpreter, "must be profiling interpreter"); Label zero_continue; - pushl(rax); - pushl(rbx); + push(rax); + push(rbx); get_method(rbx); // Test MDO to avoid the call if it is NULL. - movl(rax, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); - testl(rax, rax); + movptr(rax, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); + testptr(rax, rax); jcc(Assembler::zero, zero_continue); // rbx,: method @@ -1007,53 +1006,55 @@ void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() { call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::bcp_to_di), rbx, rsi); // rax,: mdi - movl(rbx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); - testl(rbx, rbx); + movptr(rbx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); + testptr(rbx, rbx); jcc(Assembler::zero, zero_continue); - addl(rbx, in_bytes(methodDataOopDesc::data_offset())); - addl(rbx, rax); - movl(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rbx); + addptr(rbx, in_bytes(methodDataOopDesc::data_offset())); + addptr(rbx, rax); + movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rbx); bind(zero_continue); - popl(rbx); - popl(rax); + pop(rbx); + pop(rax); } void InterpreterMacroAssembler::verify_method_data_pointer() { assert(ProfileInterpreter, "must be profiling interpreter"); #ifdef ASSERT Label verify_continue; - pushl(rax); - pushl(rbx); - pushl(rcx); - pushl(rdx); + push(rax); + push(rbx); + push(rcx); + push(rdx); test_method_data_pointer(rcx, verify_continue); // If mdp is zero, continue get_method(rbx); // If the mdp is valid, it will point to a DataLayout header which is // consistent with the bcp. The converse is highly probable also. load_unsigned_word(rdx, Address(rcx, in_bytes(DataLayout::bci_offset()))); - addl(rdx, Address(rbx, methodOopDesc::const_offset())); - leal(rdx, Address(rdx, constMethodOopDesc::codes_offset())); - cmpl(rdx, rsi); + addptr(rdx, Address(rbx, methodOopDesc::const_offset())); + lea(rdx, Address(rdx, constMethodOopDesc::codes_offset())); + cmpptr(rdx, rsi); jcc(Assembler::equal, verify_continue); // rbx,: method // rsi: bcp // rcx: mdp call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::verify_mdp), rbx, rsi, rcx); bind(verify_continue); - popl(rdx); - popl(rcx); - popl(rbx); - popl(rax); + pop(rdx); + pop(rcx); + pop(rbx); + pop(rax); #endif // ASSERT } void InterpreterMacroAssembler::set_mdp_data_at(Register mdp_in, int constant, Register value) { + // %%% this seems to be used to store counter data which is surely 32bits + // however 64bit side stores 64 bits which seems wrong assert(ProfileInterpreter, "must be profiling interpreter"); Address data(mdp_in, constant); - movl(data, value); + movptr(data, value); } @@ -1073,6 +1074,7 @@ void InterpreterMacroAssembler::increment_mdp_data_at(Address data, assert( DataLayout::counter_increment==1, "flow-free idiom only works with 1" ); assert(ProfileInterpreter, "must be profiling interpreter"); + // %%% 64bit treats this as 64 bit which seems unlikely if (decrement) { // Decrement the register. Set condition codes. addl(data, -DataLayout::counter_increment); @@ -1119,11 +1121,11 @@ void InterpreterMacroAssembler::test_mdp_data_at(Register mdp_in, Label& not_equal_continue) { assert(ProfileInterpreter, "must be profiling interpreter"); if (test_value_out == noreg) { - cmpl(value, Address(mdp_in, offset)); + cmpptr(value, Address(mdp_in, offset)); } else { // Put the test value into a register, so caller can use it: - movl(test_value_out, Address(mdp_in, offset)); - cmpl(test_value_out, value); + movptr(test_value_out, Address(mdp_in, offset)); + cmpptr(test_value_out, value); } jcc(Assembler::notEqual, not_equal_continue); } @@ -1132,31 +1134,31 @@ void InterpreterMacroAssembler::test_mdp_data_at(Register mdp_in, void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in, int offset_of_disp) { assert(ProfileInterpreter, "must be profiling interpreter"); Address disp_address(mdp_in, offset_of_disp); - addl(mdp_in,disp_address); - movl(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); + addptr(mdp_in,disp_address); + movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); } void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in, Register reg, int offset_of_disp) { assert(ProfileInterpreter, "must be profiling interpreter"); Address disp_address(mdp_in, reg, Address::times_1, offset_of_disp); - addl(mdp_in, disp_address); - movl(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); + addptr(mdp_in, disp_address); + movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); } void InterpreterMacroAssembler::update_mdp_by_constant(Register mdp_in, int constant) { assert(ProfileInterpreter, "must be profiling interpreter"); - addl(mdp_in, constant); - movl(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); + addptr(mdp_in, constant); + movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); } void InterpreterMacroAssembler::update_mdp_for_ret(Register return_bci) { assert(ProfileInterpreter, "must be profiling interpreter"); - pushl(return_bci); // save/restore across call_VM + push(return_bci); // save/restore across call_VM call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::update_mdp_for_ret), return_bci); - popl(return_bci); + pop(return_bci); } @@ -1172,6 +1174,8 @@ void InterpreterMacroAssembler::profile_taken_branch(Register mdp, Register bump // We inline increment_mdp_data_at to return bumped_count in a register //increment_mdp_data_at(mdp, in_bytes(JumpData::taken_offset())); Address data(mdp, in_bytes(JumpData::taken_offset())); + + // %%% 64bit treats these cells as 64 bit but they seem to be 32 bit movl(bumped_count,data); assert( DataLayout::counter_increment==1, "flow-free idiom only works with 1" ); addl(bumped_count, DataLayout::counter_increment); @@ -1289,7 +1293,7 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper( if (row == start_row) { // Failed the equality check on receiver[n]... Test for null. - testl(reg2, reg2); + testptr(reg2, reg2); if (start_row == last_row) { // The only thing left to do is handle the null case. jcc(Assembler::notZero, done); @@ -1315,7 +1319,7 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper( int recvr_offset = in_bytes(VirtualCallData::receiver_offset(start_row)); set_mdp_data_at(mdp, recvr_offset, receiver); int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row)); - movl(reg2, DataLayout::counter_increment); + movptr(reg2, (int32_t)DataLayout::counter_increment); set_mdp_data_at(mdp, count_offset, reg2); jmp(done); } @@ -1454,9 +1458,11 @@ void InterpreterMacroAssembler::profile_switch_case(Register index, Register mdp test_method_data_pointer(mdp, profile_continue); // Build the base (index * per_case_size_in_bytes()) + case_array_offset_in_bytes() - movl(reg2, in_bytes(MultiBranchData::per_case_size())); - imull(index, reg2); - addl(index, in_bytes(MultiBranchData::case_array_offset())); + movptr(reg2, (int32_t)in_bytes(MultiBranchData::per_case_size())); + // index is positive and so should have correct value if this code were + // used on 64bits + imulptr(index, reg2); + addptr(index, in_bytes(MultiBranchData::case_array_offset())); // Update the case count increment_mdp_data_at(mdp, index, in_bytes(MultiBranchData::relative_count_offset())); @@ -1535,12 +1541,12 @@ void InterpreterMacroAssembler::notify_method_exit( { SkipIfEqual skip_if(this, &DTraceMethodProbes, 0); - push(state); + NOT_CC_INTERP(push(state)); get_thread(rbx); get_method(rcx); call_VM_leaf( CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), rbx, rcx); - pop(state); + NOT_CC_INTERP(pop(state)); } } diff --git a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp index 10cf8140a22..be3dee6620a 100644 --- a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp +++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp @@ -65,15 +65,15 @@ class InterpreterMacroAssembler: public MacroAssembler { #else - void save_bcp() { movl(Address(rbp, frame::interpreter_frame_bcx_offset * wordSize), rsi); } - void restore_bcp() { movl(rsi, Address(rbp, frame::interpreter_frame_bcx_offset * wordSize)); } - void restore_locals() { movl(rdi, Address(rbp, frame::interpreter_frame_locals_offset * wordSize)); } + void save_bcp() { movptr(Address(rbp, frame::interpreter_frame_bcx_offset * wordSize), rsi); } + void restore_bcp() { movptr(rsi, Address(rbp, frame::interpreter_frame_bcx_offset * wordSize)); } + void restore_locals() { movptr(rdi, Address(rbp, frame::interpreter_frame_locals_offset * wordSize)); } // Helpers for runtime call arguments/results - void get_method(Register reg) { movl(reg, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); } - void get_constant_pool(Register reg) { get_method(reg); movl(reg, Address(reg, methodOopDesc::constants_offset())); } - void get_constant_pool_cache(Register reg) { get_constant_pool(reg); movl(reg, Address(reg, constantPoolOopDesc::cache_offset_in_bytes())); } - void get_cpool_and_tags(Register cpool, Register tags) { get_constant_pool(cpool); movl(tags, Address(cpool, constantPoolOopDesc::tags_offset_in_bytes())); + void get_method(Register reg) { movptr(reg, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); } + void get_constant_pool(Register reg) { get_method(reg); movptr(reg, Address(reg, methodOopDesc::constants_offset())); } + void get_constant_pool_cache(Register reg) { get_constant_pool(reg); movptr(reg, Address(reg, constantPoolOopDesc::cache_offset_in_bytes())); } + void get_cpool_and_tags(Register cpool, Register tags) { get_constant_pool(cpool); movptr(tags, Address(cpool, constantPoolOopDesc::tags_offset_in_bytes())); } void get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset); void get_cache_and_index_at_bcp(Register cache, Register index, int bcp_offset); @@ -82,8 +82,6 @@ class InterpreterMacroAssembler: public MacroAssembler { // Expression stack void f2ieee(); // truncate ftos to 32bits void d2ieee(); // truncate dtos to 64bits -#endif // CC_INTERP - void pop_ptr(Register r = rax); void pop_ptr(Register r, Register tag); @@ -104,14 +102,25 @@ class InterpreterMacroAssembler: public MacroAssembler { void pop(TosState state); // transition vtos -> state void push(TosState state); // transition state -> vtos + void pop(Register r ) { ((MacroAssembler*)this)->pop(r); } + + void push(Register r ) { ((MacroAssembler*)this)->push(r); } + void push(int32_t imm ) { ((MacroAssembler*)this)->push(imm); } + + // These are dummies to prevent surprise implicit conversions to Register + void pop(void* v ); // Add unimplemented ambiguous method + void push(void* v ); // Add unimplemented ambiguous method + DEBUG_ONLY(void verify_stack_tag(frame::Tag t);) +#endif // CC_INTERP + #ifndef CC_INTERP void empty_expression_stack() { - movl(rsp, Address(rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize)); + movptr(rsp, Address(rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize)); // NULL last_sp until next java call - movl(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); } // Tagged stack helpers for swap and dup diff --git a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp index 4756a2587be..75ca463ace0 100644 --- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp @@ -28,6 +28,15 @@ // Implementation of InterpreterMacroAssembler +#ifdef CC_INTERP +void InterpreterMacroAssembler::get_method(Register reg) { + movptr(reg, Address(rbp, -(sizeof(BytecodeInterpreter) + 2 * wordSize))); + movptr(reg, Address(reg, byte_offset_of(BytecodeInterpreter, _method))); +} +#endif // CC_INTERP + +#ifndef CC_INTERP + void InterpreterMacroAssembler::call_VM_leaf_base(address entry_point, int number_of_arguments) { // interpreter specific @@ -39,7 +48,7 @@ void InterpreterMacroAssembler::call_VM_leaf_base(address entry_point, save_bcp(); { Label L; - cmpq(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int)NULL_WORD); + cmpptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); jcc(Assembler::equal, L); stop("InterpreterMacroAssembler::call_VM_leaf_base:" " last_sp != NULL"); @@ -52,7 +61,7 @@ void InterpreterMacroAssembler::call_VM_leaf_base(address entry_point, #ifdef ASSERT { Label L; - cmpq(r13, Address(rbp, frame::interpreter_frame_bcx_offset * wordSize)); + cmpptr(r13, Address(rbp, frame::interpreter_frame_bcx_offset * wordSize)); jcc(Assembler::equal, L); stop("InterpreterMacroAssembler::call_VM_leaf_base:" " r13 not callee saved?"); @@ -60,7 +69,7 @@ void InterpreterMacroAssembler::call_VM_leaf_base(address entry_point, } { Label L; - cmpq(r14, Address(rbp, frame::interpreter_frame_locals_offset * wordSize)); + cmpptr(r14, Address(rbp, frame::interpreter_frame_locals_offset * wordSize)); jcc(Assembler::equal, L); stop("InterpreterMacroAssembler::call_VM_leaf_base:" " r14 not callee saved?"); @@ -86,7 +95,7 @@ void InterpreterMacroAssembler::call_VM_base(Register oop_result, #ifdef ASSERT { Label L; - cmpq(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int)NULL_WORD); + cmpptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); jcc(Assembler::equal, L); stop("InterpreterMacroAssembler::call_VM_leaf_base:" " last_sp != NULL"); @@ -127,15 +136,15 @@ void InterpreterMacroAssembler::check_and_handle_popframe(Register java_thread) void InterpreterMacroAssembler::load_earlyret_value(TosState state) { - movq(rcx, Address(r15_thread, JavaThread::jvmti_thread_state_offset())); + movptr(rcx, Address(r15_thread, JavaThread::jvmti_thread_state_offset())); const Address tos_addr(rcx, JvmtiThreadState::earlyret_tos_offset()); const Address oop_addr(rcx, JvmtiThreadState::earlyret_oop_offset()); const Address val_addr(rcx, JvmtiThreadState::earlyret_value_offset()); switch (state) { - case atos: movq(rax, oop_addr); - movptr(oop_addr, NULL_WORD); + case atos: movptr(rax, oop_addr); + movptr(oop_addr, (int32_t)NULL_WORD); verify_oop(rax, state); break; - case ltos: movq(rax, val_addr); break; + case ltos: movptr(rax, val_addr); break; case btos: // fall through case ctos: // fall through case stos: // fall through @@ -147,15 +156,15 @@ void InterpreterMacroAssembler::load_earlyret_value(TosState state) { } // Clean up tos value in the thread object movl(tos_addr, (int) ilgl); - movl(val_addr, (int) NULL_WORD); + movl(val_addr, (int32_t) NULL_WORD); } void InterpreterMacroAssembler::check_and_handle_earlyret(Register java_thread) { if (JvmtiExport::can_force_early_return()) { Label L; - movq(c_rarg0, Address(r15_thread, JavaThread::jvmti_thread_state_offset())); - testq(c_rarg0, c_rarg0); + movptr(c_rarg0, Address(r15_thread, JavaThread::jvmti_thread_state_offset())); + testptr(c_rarg0, c_rarg0); jcc(Assembler::zero, L); // if (thread->jvmti_thread_state() == NULL) exit; // Initiate earlyret handling only if it is not already being processed. @@ -167,7 +176,7 @@ void InterpreterMacroAssembler::check_and_handle_earlyret(Register java_thread) // Call Interpreter::remove_activation_early_entry() to get the address of the // same-named entrypoint in the generated interpreter code. - movq(c_rarg0, Address(r15_thread, JavaThread::jvmti_thread_state_offset())); + movptr(c_rarg0, Address(r15_thread, JavaThread::jvmti_thread_state_offset())); movl(c_rarg0, Address(c_rarg0, JvmtiThreadState::earlyret_tos_offset())); call_VM_leaf(CAST_FROM_FN_PTR(address, Interpreter::remove_activation_early_entry), c_rarg0); jmp(rax); @@ -192,7 +201,7 @@ void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, assert(bcp_offset > 0, "bcp is still pointing to start of bytecode"); assert(cache != index, "must use different registers"); load_unsigned_word(index, Address(r13, bcp_offset)); - movq(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); + movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below"); // convert from field index to ConstantPoolCacheEntry index shll(index, 2); @@ -209,10 +218,10 @@ void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache, // convert from field index to ConstantPoolCacheEntry index // and from word offset to byte offset shll(tmp, 2 + LogBytesPerWord); - movq(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); + movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); // skip past the header - addq(cache, in_bytes(constantPoolCacheOopDesc::base_offset())); - addq(cache, tmp); // construct pointer to cache entry + addptr(cache, in_bytes(constantPoolCacheOopDesc::base_offset())); + addptr(cache, tmp); // construct pointer to cache entry } @@ -247,24 +256,24 @@ void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass, // exceptionally deep in the Java hierarchy and we have to scan the // secondary superclass list the hard way. See if we get an // immediate positive hit - cmpq(rax, Address(Rsub_klass, rcx, Address::times_1)); + cmpptr(rax, Address(Rsub_klass, rcx, Address::times_1)); jcc(Assembler::equal,ok_is_subtype); // Check for immediate negative hit cmpl(rcx, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()); jcc( Assembler::notEqual, not_subtype ); // Check for self - cmpq(Rsub_klass, rax); + cmpptr(Rsub_klass, rax); jcc(Assembler::equal, ok_is_subtype); // Now do a linear scan of the secondary super-klass chain. - movq(rdi, Address(Rsub_klass, sizeof(oopDesc) + - Klass::secondary_supers_offset_in_bytes())); + movptr(rdi, Address(Rsub_klass, sizeof(oopDesc) + + Klass::secondary_supers_offset_in_bytes())); // rdi holds the objArrayOop of secondary supers. // Load the array length movl(rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes())); // Skip to start of data; also clear Z flag incase rcx is zero - addq(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + addptr(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); // Scan rcx words at [rdi] for occurance of rax // Set NZ/Z based on last compare @@ -272,30 +281,31 @@ void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass, // and we store values in objArrays always encoded, thus we need to encode value // before repne if (UseCompressedOops) { - pushq(rax); + push(rax); encode_heap_oop(rax); repne_scanl(); // Not equal? jcc(Assembler::notEqual, not_subtype_pop); // restore heap oop here for movq - popq(rax); + pop(rax); } else { - repne_scanq(); + repne_scan(); jcc(Assembler::notEqual, not_subtype); } // Must be equal but missed in cache. Update cache. - movq(Address(Rsub_klass, sizeof(oopDesc) + + movptr(Address(Rsub_klass, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()), rax); jmp(ok_is_subtype); bind(not_subtype_pop); // restore heap oop here for miss - if (UseCompressedOops) popq(rax); + if (UseCompressedOops) pop(rax); bind(not_subtype); profile_typecheck_failed(rcx); // blows rcx } + // Java Expression Stack #ifdef ASSERT @@ -307,17 +317,17 @@ void InterpreterMacroAssembler::verify_stack_tag(frame::Tag t) { if (t == frame::TagCategory2) { tag = frame::TagValue; Label hokay; - cmpq(Address(rsp, 3*wordSize), (int)tag); + cmpptr(Address(rsp, 3*wordSize), (int32_t)tag); jcc(Assembler::equal, hokay); stop("Java Expression stack tag high value is bad"); bind(hokay); } Label okay; - cmpq(Address(rsp, wordSize), (int)tag); + cmpptr(Address(rsp, wordSize), (int32_t)tag); jcc(Assembler::equal, okay); // Also compare if the stack value is zero, then the tag might // not have been set coming from deopt. - cmpq(Address(rsp, 0), 0); + cmpptr(Address(rsp, 0), 0); jcc(Assembler::equal, okay); stop("Java Expression stack tag value is bad"); bind(okay); @@ -327,83 +337,83 @@ void InterpreterMacroAssembler::verify_stack_tag(frame::Tag t) { void InterpreterMacroAssembler::pop_ptr(Register r) { debug_only(verify_stack_tag(frame::TagReference)); - popq(r); - if (TaggedStackInterpreter) addq(rsp, 1 * wordSize); + pop(r); + if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); } void InterpreterMacroAssembler::pop_ptr(Register r, Register tag) { - popq(r); - if (TaggedStackInterpreter) popq(tag); + pop(r); + if (TaggedStackInterpreter) pop(tag); } void InterpreterMacroAssembler::pop_i(Register r) { - // XXX can't use popq currently, upper half non clean + // XXX can't use pop currently, upper half non clean debug_only(verify_stack_tag(frame::TagValue)); movl(r, Address(rsp, 0)); - addq(rsp, wordSize); - if (TaggedStackInterpreter) addq(rsp, 1 * wordSize); + addptr(rsp, wordSize); + if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); } void InterpreterMacroAssembler::pop_l(Register r) { debug_only(verify_stack_tag(frame::TagCategory2)); movq(r, Address(rsp, 0)); - addq(rsp, 2 * Interpreter::stackElementSize()); + addptr(rsp, 2 * Interpreter::stackElementSize()); } void InterpreterMacroAssembler::pop_f(XMMRegister r) { debug_only(verify_stack_tag(frame::TagValue)); movflt(r, Address(rsp, 0)); - addq(rsp, wordSize); - if (TaggedStackInterpreter) addq(rsp, 1 * wordSize); + addptr(rsp, wordSize); + if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); } void InterpreterMacroAssembler::pop_d(XMMRegister r) { debug_only(verify_stack_tag(frame::TagCategory2)); movdbl(r, Address(rsp, 0)); - addq(rsp, 2 * Interpreter::stackElementSize()); + addptr(rsp, 2 * Interpreter::stackElementSize()); } void InterpreterMacroAssembler::push_ptr(Register r) { - if (TaggedStackInterpreter) pushq(frame::TagReference); - pushq(r); + if (TaggedStackInterpreter) push(frame::TagReference); + push(r); } void InterpreterMacroAssembler::push_ptr(Register r, Register tag) { - if (TaggedStackInterpreter) pushq(tag); - pushq(r); + if (TaggedStackInterpreter) push(tag); + push(r); } void InterpreterMacroAssembler::push_i(Register r) { - if (TaggedStackInterpreter) pushq(frame::TagValue); - pushq(r); + if (TaggedStackInterpreter) push(frame::TagValue); + push(r); } void InterpreterMacroAssembler::push_l(Register r) { if (TaggedStackInterpreter) { - pushq(frame::TagValue); - subq(rsp, 1 * wordSize); - pushq(frame::TagValue); - subq(rsp, 1 * wordSize); + push(frame::TagValue); + subptr(rsp, 1 * wordSize); + push(frame::TagValue); + subptr(rsp, 1 * wordSize); } else { - subq(rsp, 2 * wordSize); + subptr(rsp, 2 * wordSize); } movq(Address(rsp, 0), r); } void InterpreterMacroAssembler::push_f(XMMRegister r) { - if (TaggedStackInterpreter) pushq(frame::TagValue); - subq(rsp, wordSize); + if (TaggedStackInterpreter) push(frame::TagValue); + subptr(rsp, wordSize); movflt(Address(rsp, 0), r); } void InterpreterMacroAssembler::push_d(XMMRegister r) { if (TaggedStackInterpreter) { - pushq(frame::TagValue); - subq(rsp, 1 * wordSize); - pushq(frame::TagValue); - subq(rsp, 1 * wordSize); + push(frame::TagValue); + subptr(rsp, 1 * wordSize); + push(frame::TagValue); + subptr(rsp, 1 * wordSize); } else { - subq(rsp, 2 * wordSize); + subptr(rsp, 2 * wordSize); } movdbl(Address(rsp, 0), r); } @@ -441,20 +451,22 @@ void InterpreterMacroAssembler::push(TosState state) { } + + // Tagged stack helpers for swap and dup void InterpreterMacroAssembler::load_ptr_and_tag(int n, Register val, Register tag) { - movq(val, Address(rsp, Interpreter::expr_offset_in_bytes(n))); + movptr(val, Address(rsp, Interpreter::expr_offset_in_bytes(n))); if (TaggedStackInterpreter) { - movq(tag, Address(rsp, Interpreter::expr_tag_offset_in_bytes(n))); + movptr(tag, Address(rsp, Interpreter::expr_tag_offset_in_bytes(n))); } } void InterpreterMacroAssembler::store_ptr_and_tag(int n, Register val, Register tag) { - movq(Address(rsp, Interpreter::expr_offset_in_bytes(n)), val); + movptr(Address(rsp, Interpreter::expr_offset_in_bytes(n)), val); if (TaggedStackInterpreter) { - movq(Address(rsp, Interpreter::expr_tag_offset_in_bytes(n)), tag); + movptr(Address(rsp, Interpreter::expr_tag_offset_in_bytes(n)), tag); } } @@ -463,12 +475,12 @@ void InterpreterMacroAssembler::store_ptr_and_tag(int n, Register val, void InterpreterMacroAssembler::tag_local(frame::Tag tag, int n) { if (TaggedStackInterpreter) { if (tag == frame::TagCategory2) { - mov64(Address(r14, Interpreter::local_tag_offset_in_bytes(n+1)), - (intptr_t)frame::TagValue); - mov64(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), - (intptr_t)frame::TagValue); + movptr(Address(r14, Interpreter::local_tag_offset_in_bytes(n+1)), + (int32_t)frame::TagValue); + movptr(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), + (int32_t)frame::TagValue); } else { - mov64(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), (intptr_t)tag); + movptr(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)tag); } } } @@ -476,13 +488,13 @@ void InterpreterMacroAssembler::tag_local(frame::Tag tag, int n) { void InterpreterMacroAssembler::tag_local(frame::Tag tag, Register idx) { if (TaggedStackInterpreter) { if (tag == frame::TagCategory2) { - mov64(Address(r14, idx, Address::times_8, - Interpreter::local_tag_offset_in_bytes(1)), (intptr_t)frame::TagValue); - mov64(Address(r14, idx, Address::times_8, - Interpreter::local_tag_offset_in_bytes(0)), (intptr_t)frame::TagValue); + movptr(Address(r14, idx, Address::times_8, + Interpreter::local_tag_offset_in_bytes(1)), (int32_t)frame::TagValue); + movptr(Address(r14, idx, Address::times_8, + Interpreter::local_tag_offset_in_bytes(0)), (int32_t)frame::TagValue); } else { - mov64(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(0)), - (intptr_t)tag); + movptr(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(0)), + (int32_t)tag); } } } @@ -490,7 +502,7 @@ void InterpreterMacroAssembler::tag_local(frame::Tag tag, Register idx) { void InterpreterMacroAssembler::tag_local(Register tag, Register idx) { if (TaggedStackInterpreter) { // can only be TagValue or TagReference - movq(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(0)), tag); + movptr(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(0)), tag); } } @@ -498,7 +510,7 @@ void InterpreterMacroAssembler::tag_local(Register tag, Register idx) { void InterpreterMacroAssembler::tag_local(Register tag, int n) { if (TaggedStackInterpreter) { // can only be TagValue or TagReference - movq(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), tag); + movptr(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), tag); } } @@ -509,17 +521,17 @@ void InterpreterMacroAssembler::verify_local_tag(frame::Tag tag, int n) { if (tag == frame::TagCategory2) { Label nbl; t = frame::TagValue; // change to what is stored in locals - cmpq(Address(r14, Interpreter::local_tag_offset_in_bytes(n+1)), (int)t); + cmpptr(Address(r14, Interpreter::local_tag_offset_in_bytes(n+1)), (int32_t)t); jcc(Assembler::equal, nbl); stop("Local tag is bad for long/double"); bind(nbl); } Label notBad; - cmpq(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), (int)t); + cmpq(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)t); jcc(Assembler::equal, notBad); // Also compare if the local value is zero, then the tag might // not have been set coming from deopt. - cmpq(Address(r14, Interpreter::local_offset_in_bytes(n)), 0); + cmpptr(Address(r14, Interpreter::local_offset_in_bytes(n)), 0); jcc(Assembler::equal, notBad); stop("Local tag is bad"); bind(notBad); @@ -532,17 +544,17 @@ void InterpreterMacroAssembler::verify_local_tag(frame::Tag tag, Register idx) { if (tag == frame::TagCategory2) { Label nbl; t = frame::TagValue; // change to what is stored in locals - cmpq(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(1)), (int)t); + cmpptr(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(1)), (int32_t)t); jcc(Assembler::equal, nbl); stop("Local tag is bad for long/double"); bind(nbl); } Label notBad; - cmpq(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(0)), (int)t); + cmpptr(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(0)), (int32_t)t); jcc(Assembler::equal, notBad); // Also compare if the local value is zero, then the tag might // not have been set coming from deopt. - cmpq(Address(r14, idx, Address::times_8, Interpreter::local_offset_in_bytes(0)), 0); + cmpptr(Address(r14, idx, Address::times_8, Interpreter::local_offset_in_bytes(0)), 0); jcc(Assembler::equal, notBad); stop("Local tag is bad"); bind(notBad); @@ -559,7 +571,7 @@ void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point) { void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, Register arg_1) { if (c_rarg0 != arg_1) { - movq(c_rarg0, arg_1); + mov(c_rarg0, arg_1); } MacroAssembler::call_VM_leaf_base(entry_point, 1); } @@ -571,10 +583,10 @@ void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, assert(c_rarg0 != arg_2, "smashed argument"); assert(c_rarg1 != arg_1, "smashed argument"); if (c_rarg0 != arg_1) { - movq(c_rarg0, arg_1); + mov(c_rarg0, arg_1); } if (c_rarg1 != arg_2) { - movq(c_rarg1, arg_2); + mov(c_rarg1, arg_2); } MacroAssembler::call_VM_leaf_base(entry_point, 2); } @@ -590,13 +602,13 @@ void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, assert(c_rarg2 != arg_1, "smashed argument"); assert(c_rarg2 != arg_2, "smashed argument"); if (c_rarg0 != arg_1) { - movq(c_rarg0, arg_1); + mov(c_rarg0, arg_1); } if (c_rarg1 != arg_2) { - movq(c_rarg1, arg_2); + mov(c_rarg1, arg_2); } if (c_rarg2 != arg_3) { - movq(c_rarg2, arg_3); + mov(c_rarg2, arg_3); } MacroAssembler::call_VM_leaf_base(entry_point, 3); } @@ -605,9 +617,9 @@ void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, // in this thread in which case we must call the i2i entry void InterpreterMacroAssembler::jump_from_interpreted(Register method, Register temp) { // set sender sp - leaq(r13, Address(rsp, wordSize)); + lea(r13, Address(rsp, wordSize)); // record last_sp - movq(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), r13); + movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), r13); if (JvmtiExport::can_post_interpreter_events()) { Label run_compiled_code; @@ -644,12 +656,12 @@ void InterpreterMacroAssembler::dispatch_base(TosState state, verify_FPU(1, state); if (VerifyActivationFrameSize) { Label L; - movq(rcx, rbp); - subq(rcx, rsp); - int min_frame_size = + mov(rcx, rbp); + subptr(rcx, rsp); + int32_t min_frame_size = (frame::link_offset - frame::interpreter_frame_initial_sp_offset) * wordSize; - cmpq(rcx, min_frame_size); + cmpptr(rcx, (int32_t)min_frame_size); jcc(Assembler::greaterEqual, L); stop("broken stack frame"); bind(L); @@ -678,7 +690,7 @@ void InterpreterMacroAssembler::dispatch_next(TosState state, int step) { // load next bytecode (load before advancing r13 to prevent AGI) load_unsigned_byte(rbx, Address(r13, step)); // advance r13 - incrementq(r13, step); + increment(r13, step); dispatch_base(state, Interpreter::dispatch_table(state)); } @@ -718,7 +730,7 @@ void InterpreterMacroAssembler::remove_activation( movbool(do_not_unlock_if_synchronized, false); // reset the flag // get method access flags - movq(rbx, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); + movptr(rbx, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); movl(rcx, Address(rbx, methodOopDesc::access_flags_offset())); testl(rcx, JVM_ACC_SYNCHRONIZED); jcc(Assembler::zero, unlocked); @@ -738,10 +750,10 @@ void InterpreterMacroAssembler::remove_activation( wordSize - (int) sizeof(BasicObjectLock)); // We use c_rarg1 so that if we go slow path it will be the correct // register for unlock_object to pass to VM directly - leaq(c_rarg1, monitor); // address of first monitor + lea(c_rarg1, monitor); // address of first monitor - movq(rax, Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes())); - testq(rax, rax); + movptr(rax, Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes())); + testptr(rax, rax); jcc(Assembler::notZero, unlock); pop(state); @@ -783,9 +795,9 @@ void InterpreterMacroAssembler::remove_activation( bind(restart); // We use c_rarg1 so that if we go slow path it will be the correct // register for unlock_object to pass to VM directly - movq(c_rarg1, monitor_block_top); // points to current entry, starting + movptr(c_rarg1, monitor_block_top); // points to current entry, starting // with top-most entry - leaq(rbx, monitor_block_bot); // points to word before bottom of + lea(rbx, monitor_block_bot); // points to word before bottom of // monitor block jmp(entry); @@ -818,12 +830,12 @@ void InterpreterMacroAssembler::remove_activation( bind(loop); // check if current entry is used - cmpq(Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes()), (int) NULL); + cmpptr(Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes()), (int32_t) NULL); jcc(Assembler::notEqual, exception); - addq(c_rarg1, entry_size); // otherwise advance to next entry + addptr(c_rarg1, entry_size); // otherwise advance to next entry bind(entry); - cmpq(c_rarg1, rbx); // check if bottom reached + cmpptr(c_rarg1, rbx); // check if bottom reached jcc(Assembler::notEqual, loop); // if not at bottom then check this entry } @@ -838,13 +850,15 @@ void InterpreterMacroAssembler::remove_activation( // remove activation // get sender sp - movq(rbx, - Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); + movptr(rbx, + Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); leave(); // remove frame anchor - popq(ret_addr); // get return address - movq(rsp, rbx); // set sp to sender sp + pop(ret_addr); // get return address + mov(rsp, rbx); // set sp to sender sp } +#endif // C_INTERP + // Lock object // // Args: @@ -875,7 +889,7 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg) { Label slow_case; // Load object pointer into obj_reg %c_rarg3 - movq(obj_reg, Address(lock_reg, obj_offset)); + movptr(obj_reg, Address(lock_reg, obj_offset)); if (UseBiasedLocking) { biased_locking_enter(lock_reg, obj_reg, swap_reg, rscratch1, false, done, &slow_case); @@ -885,16 +899,16 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg) { movl(swap_reg, 1); // Load (object->mark() | 1) into swap_reg %rax - orq(swap_reg, Address(obj_reg, 0)); + orptr(swap_reg, Address(obj_reg, 0)); // Save (object->mark() | 1) into BasicLock's displaced header - movq(Address(lock_reg, mark_offset), swap_reg); + movptr(Address(lock_reg, mark_offset), swap_reg); assert(lock_offset == 0, "displached header must be first word in BasicObjectLock"); if (os::is_MP()) lock(); - cmpxchgq(lock_reg, Address(obj_reg, 0)); + cmpxchgptr(lock_reg, Address(obj_reg, 0)); if (PrintBiasedLockingStatistics) { cond_inc32(Assembler::zero, ExternalAddress((address) BiasedLocking::fast_path_entry_count_addr())); @@ -910,11 +924,11 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg) { // assuming both stack pointer and pagesize have their // least significant 3 bits clear. // NOTE: the oopMark is in swap_reg %rax as the result of cmpxchg - subq(swap_reg, rsp); - andq(swap_reg, 7 - os::vm_page_size()); + subptr(swap_reg, rsp); + andptr(swap_reg, 7 - os::vm_page_size()); // Save the test result, for recursive case, the result is zero - movq(Address(lock_reg, mark_offset), swap_reg); + movptr(Address(lock_reg, mark_offset), swap_reg); if (PrintBiasedLockingStatistics) { cond_inc32(Assembler::zero, @@ -963,37 +977,37 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg) { // Convert from BasicObjectLock structure to object and BasicLock // structure Store the BasicLock address into %rax - leaq(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset_in_bytes())); + lea(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset_in_bytes())); // Load oop into obj_reg(%c_rarg3) - movq(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes())); + movptr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes())); // Free entry - movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), NULL_WORD); + movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), (int32_t)NULL_WORD); if (UseBiasedLocking) { biased_locking_exit(obj_reg, header_reg, done); } // Load the old header from BasicLock structure - movq(header_reg, Address(swap_reg, - BasicLock::displaced_header_offset_in_bytes())); + movptr(header_reg, Address(swap_reg, + BasicLock::displaced_header_offset_in_bytes())); // Test for recursion - testq(header_reg, header_reg); + testptr(header_reg, header_reg); // zero for recursive case jcc(Assembler::zero, done); // Atomic swap back the old header if (os::is_MP()) lock(); - cmpxchgq(header_reg, Address(obj_reg, 0)); + cmpxchgptr(header_reg, Address(obj_reg, 0)); // zero for recursive case jcc(Assembler::zero, done); // Call the runtime routine for slow case. - movq(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), + movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), obj_reg); // restore obj call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), @@ -1005,12 +1019,13 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg) { } } +#ifndef CC_INTERP void InterpreterMacroAssembler::test_method_data_pointer(Register mdp, Label& zero_continue) { assert(ProfileInterpreter, "must be profiling interpreter"); - movq(mdp, Address(rbp, frame::interpreter_frame_mdx_offset * wordSize)); - testq(mdp, mdp); + movptr(mdp, Address(rbp, frame::interpreter_frame_mdx_offset * wordSize)); + testptr(mdp, mdp); jcc(Assembler::zero, zero_continue); } @@ -1019,13 +1034,13 @@ void InterpreterMacroAssembler::test_method_data_pointer(Register mdp, void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() { assert(ProfileInterpreter, "must be profiling interpreter"); Label zero_continue; - pushq(rax); - pushq(rbx); + push(rax); + push(rbx); get_method(rbx); // Test MDO to avoid the call if it is NULL. - movq(rax, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); - testq(rax, rax); + movptr(rax, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); + testptr(rax, rax); jcc(Assembler::zero, zero_continue); // rbx: method @@ -1033,26 +1048,26 @@ void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() { call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::bcp_to_di), rbx, r13); // rax: mdi - movq(rbx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); - testq(rbx, rbx); + movptr(rbx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); + testptr(rbx, rbx); jcc(Assembler::zero, zero_continue); - addq(rbx, in_bytes(methodDataOopDesc::data_offset())); - addq(rbx, rax); - movq(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rbx); + addptr(rbx, in_bytes(methodDataOopDesc::data_offset())); + addptr(rbx, rax); + movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rbx); bind(zero_continue); - popq(rbx); - popq(rax); + pop(rbx); + pop(rax); } void InterpreterMacroAssembler::verify_method_data_pointer() { assert(ProfileInterpreter, "must be profiling interpreter"); #ifdef ASSERT Label verify_continue; - pushq(rax); - pushq(rbx); - pushq(c_rarg3); - pushq(c_rarg2); + push(rax); + push(rbx); + push(c_rarg3); + push(c_rarg2); test_method_data_pointer(c_rarg3, verify_continue); // If mdp is zero, continue get_method(rbx); @@ -1060,9 +1075,9 @@ void InterpreterMacroAssembler::verify_method_data_pointer() { // consistent with the bcp. The converse is highly probable also. load_unsigned_word(c_rarg2, Address(c_rarg3, in_bytes(DataLayout::bci_offset()))); - addq(c_rarg2, Address(rbx, methodOopDesc::const_offset())); - leaq(c_rarg2, Address(c_rarg2, constMethodOopDesc::codes_offset())); - cmpq(c_rarg2, r13); + addptr(c_rarg2, Address(rbx, methodOopDesc::const_offset())); + lea(c_rarg2, Address(c_rarg2, constMethodOopDesc::codes_offset())); + cmpptr(c_rarg2, r13); jcc(Assembler::equal, verify_continue); // rbx: method // r13: bcp @@ -1070,10 +1085,10 @@ void InterpreterMacroAssembler::verify_method_data_pointer() { call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::verify_mdp), rbx, r13, c_rarg3); bind(verify_continue); - popq(c_rarg2); - popq(c_rarg3); - popq(rbx); - popq(rax); + pop(c_rarg2); + pop(c_rarg3); + pop(rbx); + pop(rax); #endif // ASSERT } @@ -1083,7 +1098,7 @@ void InterpreterMacroAssembler::set_mdp_data_at(Register mdp_in, Register value) { assert(ProfileInterpreter, "must be profiling interpreter"); Address data(mdp_in, constant); - movq(data, value); + movptr(data, value); } @@ -1099,22 +1114,24 @@ void InterpreterMacroAssembler::increment_mdp_data_at(Register mdp_in, void InterpreterMacroAssembler::increment_mdp_data_at(Address data, bool decrement) { assert(ProfileInterpreter, "must be profiling interpreter"); + // %%% this does 64bit counters at best it is wasting space + // at worst it is a rare bug when counters overflow if (decrement) { // Decrement the register. Set condition codes. - addq(data, -DataLayout::counter_increment); + addptr(data, (int32_t) -DataLayout::counter_increment); // If the decrement causes the counter to overflow, stay negative Label L; jcc(Assembler::negative, L); - addq(data, DataLayout::counter_increment); + addptr(data, (int32_t) DataLayout::counter_increment); bind(L); } else { assert(DataLayout::counter_increment == 1, "flow-free idiom only works with 1"); // Increment the register. Set carry flag. - addq(data, DataLayout::counter_increment); + addptr(data, DataLayout::counter_increment); // If the increment causes the counter to overflow, pull back by 1. - sbbq(data, 0); + sbbptr(data, (int32_t)0); } } @@ -1146,11 +1163,11 @@ void InterpreterMacroAssembler::test_mdp_data_at(Register mdp_in, Label& not_equal_continue) { assert(ProfileInterpreter, "must be profiling interpreter"); if (test_value_out == noreg) { - cmpq(value, Address(mdp_in, offset)); + cmpptr(value, Address(mdp_in, offset)); } else { // Put the test value into a register, so caller can use it: - movq(test_value_out, Address(mdp_in, offset)); - cmpq(test_value_out, value); + movptr(test_value_out, Address(mdp_in, offset)); + cmpptr(test_value_out, value); } jcc(Assembler::notEqual, not_equal_continue); } @@ -1160,8 +1177,8 @@ void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in, int offset_of_disp) { assert(ProfileInterpreter, "must be profiling interpreter"); Address disp_address(mdp_in, offset_of_disp); - addq(mdp_in, disp_address); - movq(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); + addptr(mdp_in, disp_address); + movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); } @@ -1170,26 +1187,26 @@ void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in, int offset_of_disp) { assert(ProfileInterpreter, "must be profiling interpreter"); Address disp_address(mdp_in, reg, Address::times_1, offset_of_disp); - addq(mdp_in, disp_address); - movq(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); + addptr(mdp_in, disp_address); + movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); } void InterpreterMacroAssembler::update_mdp_by_constant(Register mdp_in, int constant) { assert(ProfileInterpreter, "must be profiling interpreter"); - addq(mdp_in, constant); - movq(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); + addptr(mdp_in, constant); + movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); } void InterpreterMacroAssembler::update_mdp_for_ret(Register return_bci) { assert(ProfileInterpreter, "must be profiling interpreter"); - pushq(return_bci); // save/restore across call_VM + push(return_bci); // save/restore across call_VM call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::update_mdp_for_ret), return_bci); - popq(return_bci); + pop(return_bci); } @@ -1206,12 +1223,12 @@ void InterpreterMacroAssembler::profile_taken_branch(Register mdp, // We inline increment_mdp_data_at to return bumped_count in a register //increment_mdp_data_at(mdp, in_bytes(JumpData::taken_offset())); Address data(mdp, in_bytes(JumpData::taken_offset())); - movq(bumped_count, data); + movptr(bumped_count, data); assert(DataLayout::counter_increment == 1, "flow-free idiom only works with 1"); - addq(bumped_count, DataLayout::counter_increment); - sbbq(bumped_count, 0); - movq(data, bumped_count); // Store back out + addptr(bumped_count, DataLayout::counter_increment); + sbbptr(bumped_count, 0); + movptr(data, bumped_count); // Store back out // The method data pointer needs to be updated to reflect the new target. update_mdp_by_offset(mdp, in_bytes(JumpData::displacement_offset())); @@ -1339,7 +1356,7 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper( if (test_for_null_also) { // Failed the equality check on receiver[n]... Test for null. - testq(reg2, reg2); + testptr(reg2, reg2); if (start_row == last_row) { // The only thing left to do is handle the null case. jcc(Assembler::notZero, done); @@ -1535,8 +1552,8 @@ void InterpreterMacroAssembler::profile_switch_case(Register index, // Build the base (index * per_case_size_in_bytes()) + // case_array_offset_in_bytes() movl(reg2, in_bytes(MultiBranchData::per_case_size())); - imulq(index, reg2); // XXX l ? - addq(index, in_bytes(MultiBranchData::case_array_offset())); // XXX l ? + imulptr(index, reg2); // XXX l ? + addptr(index, in_bytes(MultiBranchData::case_array_offset())); // XXX l ? // Update the case count increment_mdp_data_at(mdp, @@ -1554,6 +1571,7 @@ void InterpreterMacroAssembler::profile_switch_case(Register index, } + void InterpreterMacroAssembler::verify_oop(Register reg, TosState state) { if (state == atos) { MacroAssembler::verify_oop(reg); @@ -1562,6 +1580,7 @@ void InterpreterMacroAssembler::verify_oop(Register reg, TosState state) { void InterpreterMacroAssembler::verify_FPU(int stack_depth, TosState state) { } +#endif // !CC_INTERP void InterpreterMacroAssembler::notify_method_entry() { @@ -1598,22 +1617,25 @@ void InterpreterMacroAssembler::notify_method_exit( // method result is saved across the call to post_method_exit. If this // is changed then the interpreter_frame_result implementation will // need to be updated too. - push(state); + + // For c++ interpreter the result is always stored at a known location in the frame + // template interpreter will leave it on the top of the stack. + NOT_CC_INTERP(push(state);) movl(rdx, Address(r15_thread, JavaThread::interp_only_mode_offset())); testl(rdx, rdx); jcc(Assembler::zero, L); call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_method_exit)); bind(L); - pop(state); + NOT_CC_INTERP(pop(state)); } { SkipIfEqual skip(this, &DTraceMethodProbes, false); - push(state); + NOT_CC_INTERP(push(state)); get_method(c_rarg1); call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), r15_thread, c_rarg1); - pop(state); + NOT_CC_INTERP(pop(state)); } } diff --git a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp index 3b1baa258cf..3267b482981 100644 --- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp +++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp @@ -25,8 +25,8 @@ // This file specializes the assember with interpreter-specific macros -class InterpreterMacroAssembler - : public MacroAssembler { +class InterpreterMacroAssembler: public MacroAssembler { +#ifndef CC_INTERP protected: // Interpreter specific version of call_VM_base virtual void call_VM_leaf_base(address entry_point, @@ -44,52 +44,53 @@ class InterpreterMacroAssembler // base routine for all dispatches void dispatch_base(TosState state, address* table, bool verifyoop = true); +#endif // CC_INTERP public: - InterpreterMacroAssembler(CodeBuffer* code) - : MacroAssembler(code) - {} + InterpreterMacroAssembler(CodeBuffer* code) : MacroAssembler(code) {} void load_earlyret_value(TosState state); +#ifdef CC_INTERP + void save_bcp() { /* not needed in c++ interpreter and harmless */ } + void restore_bcp() { /* not needed in c++ interpreter and harmless */ } + + // Helpers for runtime call arguments/results + void get_method(Register reg); + +#else + // Interpreter-specific registers - void save_bcp() - { - movq(Address(rbp, frame::interpreter_frame_bcx_offset * wordSize), r13); + void save_bcp() { + movptr(Address(rbp, frame::interpreter_frame_bcx_offset * wordSize), r13); } - void restore_bcp() - { - movq(r13, Address(rbp, frame::interpreter_frame_bcx_offset * wordSize)); + void restore_bcp() { + movptr(r13, Address(rbp, frame::interpreter_frame_bcx_offset * wordSize)); } - void restore_locals() - { - movq(r14, Address(rbp, frame::interpreter_frame_locals_offset * wordSize)); + void restore_locals() { + movptr(r14, Address(rbp, frame::interpreter_frame_locals_offset * wordSize)); } // Helpers for runtime call arguments/results - void get_method(Register reg) - { - movq(reg, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); + void get_method(Register reg) { + movptr(reg, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); } - void get_constant_pool(Register reg) - { + void get_constant_pool(Register reg) { get_method(reg); - movq(reg, Address(reg, methodOopDesc::constants_offset())); + movptr(reg, Address(reg, methodOopDesc::constants_offset())); } - void get_constant_pool_cache(Register reg) - { + void get_constant_pool_cache(Register reg) { get_constant_pool(reg); - movq(reg, Address(reg, constantPoolOopDesc::cache_offset_in_bytes())); + movptr(reg, Address(reg, constantPoolOopDesc::cache_offset_in_bytes())); } - void get_cpool_and_tags(Register cpool, Register tags) - { + void get_cpool_and_tags(Register cpool, Register tags) { get_constant_pool(cpool); - movq(tags, Address(cpool, constantPoolOopDesc::tags_offset_in_bytes())); + movptr(tags, Address(cpool, constantPoolOopDesc::tags_offset_in_bytes())); } void get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset); @@ -98,6 +99,7 @@ class InterpreterMacroAssembler void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset); + void pop_ptr(Register r = rax); void pop_i(Register r = rax); void pop_l(Register r = rax); @@ -109,15 +111,23 @@ class InterpreterMacroAssembler void push_f(XMMRegister r = xmm0); void push_d(XMMRegister r = xmm0); + void pop(Register r ) { ((MacroAssembler*)this)->pop(r); } + + void push(Register r ) { ((MacroAssembler*)this)->push(r); } + void push(int32_t imm ) { ((MacroAssembler*)this)->push(imm); } + void pop(TosState state); // transition vtos -> state void push(TosState state); // transition state -> vtos // Tagged stack support, pop and push both tag and value. void pop_ptr(Register r, Register tag); void push_ptr(Register r, Register tag); +#endif // CC_INTERP DEBUG_ONLY(void verify_stack_tag(frame::Tag t);) +#ifndef CC_INTERP + // Tagged stack helpers for swap and dup void load_ptr_and_tag(int n, Register val, Register tag); void store_ptr_and_tag(int n, Register val, Register tag); @@ -133,12 +143,12 @@ class InterpreterMacroAssembler void verify_local_tag(frame::Tag tag, Register idx); #endif // ASSERT + void empty_expression_stack() { - movq(rsp, Address(rbp, frame::interpreter_frame_monitor_block_top_offset * - wordSize)); + movptr(rsp, Address(rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize)); // NULL last_sp until next java call - movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); } // Super call_VM calls - correspond to MacroAssembler::call_VM(_leaf) calls @@ -185,11 +195,14 @@ class InterpreterMacroAssembler bool throw_monitor_exception = true, bool install_monitor_exception = true, bool notify_jvmdi = true); +#endif // CC_INTERP // Object locking void lock_object (Register lock_reg); void unlock_object(Register lock_reg); +#ifndef CC_INTERP + // Interpreter profiling operations void set_method_data_pointer_for_bcp(); void test_method_data_pointer(Register mdp, Label& zero_continue); @@ -237,6 +250,8 @@ class InterpreterMacroAssembler // only if +VerifyFPU && (state == ftos || state == dtos) void verify_FPU(int stack_depth, TosState state = ftos); +#endif // !CC_INTERP + typedef enum { NotifyJVMTI, SkipNotifyJVMTI } NotifyMethodExitMode; // support for jvmti/dtrace diff --git a/hotspot/src/cpu/x86/vm/interpreterRT_x86_32.cpp b/hotspot/src/cpu/x86/vm/interpreterRT_x86_32.cpp index 73f11d64ccd..34bf8350241 100644 --- a/hotspot/src/cpu/x86/vm/interpreterRT_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/interpreterRT_x86_32.cpp @@ -50,13 +50,13 @@ void InterpreterRuntime::SignatureHandlerGenerator::move(int from_offset, int to void InterpreterRuntime::SignatureHandlerGenerator::box(int from_offset, int to_offset) { - __ leal(temp(), Address(from(), Interpreter::local_offset_in_bytes(from_offset))); - __ cmpl(Address(from(), Interpreter::local_offset_in_bytes(from_offset)), 0); // do not use temp() to avoid AGI + __ lea(temp(), Address(from(), Interpreter::local_offset_in_bytes(from_offset))); + __ cmpptr(Address(from(), Interpreter::local_offset_in_bytes(from_offset)), (int32_t)NULL_WORD); // do not use temp() to avoid AGI Label L; __ jcc(Assembler::notZero, L); - __ movl(temp(), 0); + __ movptr(temp(), ((int32_t)NULL_WORD)); __ bind(L); - __ movl(Address(to(), to_offset * wordSize), temp()); + __ movptr(Address(to(), to_offset * wordSize), temp()); } diff --git a/hotspot/src/cpu/x86/vm/interpreterRT_x86_64.cpp b/hotspot/src/cpu/x86/vm/interpreterRT_x86_64.cpp index 90d0ad9d8d0..99381900be3 100644 --- a/hotspot/src/cpu/x86/vm/interpreterRT_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/interpreterRT_x86_64.cpp @@ -93,49 +93,49 @@ void InterpreterRuntime::SignatureHandlerGenerator::pass_long() { #ifdef _WIN64 switch (_num_args) { case 0: - __ movq(c_rarg1, src); + __ movptr(c_rarg1, src); _num_args++; break; case 1: - __ movq(c_rarg2, src); + __ movptr(c_rarg2, src); _num_args++; break; case 2: - __ movq(c_rarg3, src); + __ movptr(c_rarg3, src); _num_args++; break; case 3: default: - __ movq(rax, src); - __ movq(Address(to(), _stack_offset), rax); + __ movptr(rax, src); + __ movptr(Address(to(), _stack_offset), rax); _stack_offset += wordSize; break; } #else switch (_num_int_args) { case 0: - __ movq(c_rarg1, src); + __ movptr(c_rarg1, src); _num_int_args++; break; case 1: - __ movq(c_rarg2, src); + __ movptr(c_rarg2, src); _num_int_args++; break; case 2: - __ movq(c_rarg3, src); + __ movptr(c_rarg3, src); _num_int_args++; break; case 3: - __ movq(c_rarg4, src); + __ movptr(c_rarg4, src); _num_int_args++; break; case 4: - __ movq(c_rarg5, src); + __ movptr(c_rarg5, src); _num_int_args++; break; default: - __ movq(rax, src); - __ movq(Address(to(), _stack_offset), rax); + __ movptr(rax, src); + __ movptr(Address(to(), _stack_offset), rax); _stack_offset += wordSize; break; } @@ -171,16 +171,16 @@ void InterpreterRuntime::SignatureHandlerGenerator::pass_double() { if (_num_args < Argument::n_float_register_parameters_c-1) { __ movdbl(as_XMMRegister(++_num_args), src); } else { - __ movq(rax, src); - __ movq(Address(to(), _stack_offset), rax); + __ movptr(rax, src); + __ movptr(Address(to(), _stack_offset), rax); _stack_offset += wordSize; } #else if (_num_fp_args < Argument::n_float_register_parameters_c) { __ movdbl(as_XMMRegister(_num_fp_args++), src); } else { - __ movq(rax, src); - __ movq(Address(to(), _stack_offset), rax); + __ movptr(rax, src); + __ movptr(Address(to(), _stack_offset), rax); _stack_offset += wordSize; } #endif @@ -193,29 +193,29 @@ void InterpreterRuntime::SignatureHandlerGenerator::pass_object() { switch (_num_args) { case 0: assert(offset() == 0, "argument register 1 can only be (non-null) receiver"); - __ leaq(c_rarg1, src); + __ lea(c_rarg1, src); _num_args++; break; case 1: - __ leaq(rax, src); + __ lea(rax, src); __ xorl(c_rarg2, c_rarg2); - __ cmpq(src, 0); - __ cmovq(Assembler::notEqual, c_rarg2, rax); + __ cmpptr(src, 0); + __ cmov(Assembler::notEqual, c_rarg2, rax); _num_args++; break; case 2: - __ leaq(rax, src); + __ lea(rax, src); __ xorl(c_rarg3, c_rarg3); - __ cmpq(src, 0); - __ cmovq(Assembler::notEqual, c_rarg3, rax); + __ cmpptr(src, 0); + __ cmov(Assembler::notEqual, c_rarg3, rax); _num_args++; break; default: - __ leaq(rax, src); + __ lea(rax, src); __ xorl(temp(), temp()); - __ cmpq(src, 0); - __ cmovq(Assembler::notEqual, temp(), rax); - __ movq(Address(to(), _stack_offset), temp()); + __ cmpptr(src, 0); + __ cmov(Assembler::notEqual, temp(), rax); + __ movptr(Address(to(), _stack_offset), temp()); _stack_offset += wordSize; break; } @@ -223,43 +223,43 @@ void InterpreterRuntime::SignatureHandlerGenerator::pass_object() { switch (_num_int_args) { case 0: assert(offset() == 0, "argument register 1 can only be (non-null) receiver"); - __ leaq(c_rarg1, src); + __ lea(c_rarg1, src); _num_int_args++; break; case 1: - __ leaq(rax, src); + __ lea(rax, src); __ xorl(c_rarg2, c_rarg2); - __ cmpq(src, 0); - __ cmovq(Assembler::notEqual, c_rarg2, rax); + __ cmpptr(src, 0); + __ cmov(Assembler::notEqual, c_rarg2, rax); _num_int_args++; break; case 2: - __ leaq(rax, src); + __ lea(rax, src); __ xorl(c_rarg3, c_rarg3); - __ cmpq(src, 0); - __ cmovq(Assembler::notEqual, c_rarg3, rax); + __ cmpptr(src, 0); + __ cmov(Assembler::notEqual, c_rarg3, rax); _num_int_args++; break; case 3: - __ leaq(rax, src); + __ lea(rax, src); __ xorl(c_rarg4, c_rarg4); - __ cmpq(src, 0); - __ cmovq(Assembler::notEqual, c_rarg4, rax); + __ cmpptr(src, 0); + __ cmov(Assembler::notEqual, c_rarg4, rax); _num_int_args++; break; case 4: - __ leaq(rax, src); + __ lea(rax, src); __ xorl(c_rarg5, c_rarg5); - __ cmpq(src, 0); - __ cmovq(Assembler::notEqual, c_rarg5, rax); + __ cmpptr(src, 0); + __ cmov(Assembler::notEqual, c_rarg5, rax); _num_int_args++; break; default: - __ leaq(rax, src); + __ lea(rax, src); __ xorl(temp(), temp()); - __ cmpq(src, 0); - __ cmovq(Assembler::notEqual, temp(), rax); - __ movq(Address(to(), _stack_offset), temp()); + __ cmpptr(src, 0); + __ cmov(Assembler::notEqual, temp(), rax); + __ movptr(Address(to(), _stack_offset), temp()); _stack_offset += wordSize; break; } diff --git a/hotspot/src/cpu/x86/vm/interpreter_x86_32.cpp b/hotspot/src/cpu/x86/vm/interpreter_x86_32.cpp index fbdf398bc80..cb24f12ed1c 100644 --- a/hotspot/src/cpu/x86/vm/interpreter_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/interpreter_x86_32.cpp @@ -38,7 +38,7 @@ address AbstractInterpreterGenerator::generate_slow_signature_handler() { // rcx: temporary // rdi: pointer to locals // rsp: end of copied parameters area - __ movl(rcx, rsp); + __ mov(rcx, rsp); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::slow_signature_handler), rbx, rdi, rcx); __ ret(0); return entry; @@ -75,8 +75,8 @@ address InterpreterGenerator::generate_empty_entry(void) { // Code: _return // _return // return w/o popping parameters - __ popl(rax); - __ movl(rsp, rsi); + __ pop(rax); + __ mov(rsp, rsi); __ jmp(rax); __ bind(slow_path); @@ -135,7 +135,7 @@ address InterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKin __ pushl(Address(rsp, 3*wordSize)); // push hi (and note rsp -= wordSize) __ pushl(Address(rsp, 2*wordSize)); // push lo __ fld_d(Address(rsp, 0)); // get double in ST0 - __ addl(rsp, 2*wordSize); + __ addptr(rsp, 2*wordSize); } else { __ fld_d(Address(rsp, 1*wordSize)); } @@ -173,15 +173,15 @@ address InterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKin // return double result in xmm0 for interpreter and compilers. if (UseSSE >= 2) { - __ subl(rsp, 2*wordSize); + __ subptr(rsp, 2*wordSize); __ fstp_d(Address(rsp, 0)); __ movdbl(xmm0, Address(rsp, 0)); - __ addl(rsp, 2*wordSize); + __ addptr(rsp, 2*wordSize); } // done, result in FPU ST(0) or XMM0 - __ popl(rdi); // get return address - __ movl(rsp, rsi); // set sp to sender sp + __ pop(rdi); // get return address + __ mov(rsp, rsi); // set sp to sender sp __ jmp(rdi); return entry_point; @@ -202,10 +202,10 @@ address InterpreterGenerator::generate_abstract_entry(void) { // abstract method entry // remove return address. Not really needed, since exception handling throws away expression stack - __ popl(rbx); + __ pop(rbx); // adjust stack to what a normal return would do - __ movl(rsp, rsi); + __ mov(rsp, rsi); // throw exception __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError)); // the call_VM checks for exception, so we should never return here. diff --git a/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp b/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp index 9636c5739e5..34e5b56b8d6 100644 --- a/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp @@ -35,9 +35,9 @@ address AbstractInterpreterGenerator::generate_slow_signature_handler() { // rbx: method // r14: pointer to locals // c_rarg3: first stack arg - wordSize - __ movq(c_rarg3, rsp); + __ mov(c_rarg3, rsp); // adjust rsp - __ subq(rsp, 4 * wordSize); + __ subptr(rsp, 4 * wordSize); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::slow_signature_handler), @@ -70,13 +70,13 @@ address AbstractInterpreterGenerator::generate_slow_signature_handler() { case 0: __ movl(rscratch1, Address(rbx, methodOopDesc::access_flags_offset())); __ testl(rscratch1, JVM_ACC_STATIC); - __ cmovq(Assembler::zero, c_rarg1, Address(rsp, 0)); + __ cmovptr(Assembler::zero, c_rarg1, Address(rsp, 0)); break; case 1: - __ movq(c_rarg2, Address(rsp, wordSize)); + __ movptr(c_rarg2, Address(rsp, wordSize)); break; case 2: - __ movq(c_rarg3, Address(rsp, 2 * wordSize)); + __ movptr(c_rarg3, Address(rsp, 2 * wordSize)); break; default: break; @@ -101,7 +101,7 @@ address AbstractInterpreterGenerator::generate_slow_signature_handler() { // restore rsp - __ addq(rsp, 4 * wordSize); + __ addptr(rsp, 4 * wordSize); __ ret(0); @@ -114,9 +114,9 @@ address AbstractInterpreterGenerator::generate_slow_signature_handler() { // rbx: method // r14: pointer to locals // c_rarg3: first stack arg - wordSize - __ movq(c_rarg3, rsp); + __ mov(c_rarg3, rsp); // adjust rsp - __ subq(rsp, 14 * wordSize); + __ subptr(rsp, 14 * wordSize); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::slow_signature_handler), @@ -155,15 +155,15 @@ address AbstractInterpreterGenerator::generate_slow_signature_handler() { // Now handle integrals. Only do c_rarg1 if not static. __ movl(c_rarg3, Address(rbx, methodOopDesc::access_flags_offset())); __ testl(c_rarg3, JVM_ACC_STATIC); - __ cmovq(Assembler::zero, c_rarg1, Address(rsp, 0)); + __ cmovptr(Assembler::zero, c_rarg1, Address(rsp, 0)); - __ movq(c_rarg2, Address(rsp, wordSize)); - __ movq(c_rarg3, Address(rsp, 2 * wordSize)); - __ movq(c_rarg4, Address(rsp, 3 * wordSize)); - __ movq(c_rarg5, Address(rsp, 4 * wordSize)); + __ movptr(c_rarg2, Address(rsp, wordSize)); + __ movptr(c_rarg3, Address(rsp, 2 * wordSize)); + __ movptr(c_rarg4, Address(rsp, 3 * wordSize)); + __ movptr(c_rarg5, Address(rsp, 4 * wordSize)); // restore rsp - __ addq(rsp, 14 * wordSize); + __ addptr(rsp, 14 * wordSize); __ ret(0); @@ -176,15 +176,14 @@ address AbstractInterpreterGenerator::generate_slow_signature_handler() { // Various method entries // -address InterpreterGenerator::generate_math_entry( - AbstractInterpreter::MethodKind kind) { - // rbx: methodOop +address InterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) { + + // rbx,: methodOop + // rcx: scratrch + // r13: sender sp if (!InlineIntrinsics) return NULL; // Generate a vanilla entry - assert(kind == Interpreter::java_lang_math_sqrt, - "Other intrinsics are not special"); - address entry_point = __ pc(); // These don't need a safepoint check because they aren't virtually @@ -197,6 +196,11 @@ address InterpreterGenerator::generate_math_entry( // in order to avoid monotonicity bugs when switching // from interpreter to compiler in the middle of some // computation) + // + // stack: [ ret adr ] <-- rsp + // [ lo(arg) ] + // [ hi(arg) ] + // // Note: For JDK 1.2 StrictMath doesn't exist and Math.sin/cos/sqrt are // native methods. Interpreter::method_kind(...) does a check for @@ -218,10 +222,46 @@ address InterpreterGenerator::generate_math_entry( // Note: For JDK 1.3 StrictMath exists and Math.sin/cos/sqrt are // java methods. Interpreter::method_kind(...) will select // this entry point for the corresponding methods in JDK 1.3. - __ sqrtsd(xmm0, Address(rsp, wordSize)); + // get argument - __ popq(rax); - __ movq(rsp, r13); + if (kind == Interpreter::java_lang_math_sqrt) { + __ sqrtsd(xmm0, Address(rsp, wordSize)); + } else { + __ fld_d(Address(rsp, wordSize)); + switch (kind) { + case Interpreter::java_lang_math_sin : + __ trigfunc('s'); + break; + case Interpreter::java_lang_math_cos : + __ trigfunc('c'); + break; + case Interpreter::java_lang_math_tan : + __ trigfunc('t'); + break; + case Interpreter::java_lang_math_abs: + __ fabs(); + break; + case Interpreter::java_lang_math_log: + __ flog(); + break; + case Interpreter::java_lang_math_log10: + __ flog10(); + break; + default : + ShouldNotReachHere(); + } + + // return double result in xmm0 for interpreter and compilers. + __ subptr(rsp, 2*wordSize); + // Round to 64bit precision + __ fstp_d(Address(rsp, 0)); + __ movdbl(xmm0, Address(rsp, 0)); + __ addptr(rsp, 2*wordSize); + } + + + __ pop(rax); + __ mov(rsp, r13); __ jmp(rax); return entry_point; @@ -239,10 +279,10 @@ address InterpreterGenerator::generate_abstract_entry(void) { // abstract method entry // remove return address. Not really needed, since exception // handling throws away expression stack - __ popq(rbx); + __ pop(rbx); // adjust stack to what a normal return would do - __ movq(rsp, r13); + __ mov(rsp, r13); // throw exception __ call_VM(noreg, CAST_FROM_FN_PTR(address, @@ -276,8 +316,8 @@ address InterpreterGenerator::generate_empty_entry(void) { // Code: _return // _return // return w/o popping parameters - __ popq(rax); - __ movq(rsp, r13); + __ pop(rax); + __ mov(rsp, r13); __ jmp(rax); __ bind(slow_path); @@ -286,148 +326,6 @@ address InterpreterGenerator::generate_empty_entry(void) { } -// Call an accessor method (assuming it is resolved, otherwise drop -// into vanilla (slow path) entry -address InterpreterGenerator::generate_accessor_entry(void) { - // rbx: methodOop - - // r13: senderSP must preserver for slow path, set SP to it on fast path - - address entry_point = __ pc(); - Label xreturn_path; - - // do fastpath for resolved accessor methods - if (UseFastAccessorMethods) { - // Code: _aload_0, _(i|a)getfield, _(i|a)return or any rewrites - // thereof; parameter size = 1 - // Note: We can only use this code if the getfield has been resolved - // and if we don't have a null-pointer exception => check for - // these conditions first and use slow path if necessary. - Label slow_path; - // If we need a safepoint check, generate full interpreter entry. - __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), - SafepointSynchronize::_not_synchronized); - - __ jcc(Assembler::notEqual, slow_path); - // rbx: method - __ movq(rax, Address(rsp, wordSize)); - - // check if local 0 != NULL and read field - __ testq(rax, rax); - __ jcc(Assembler::zero, slow_path); - - __ movq(rdi, Address(rbx, methodOopDesc::constants_offset())); - // read first instruction word and extract bytecode @ 1 and index @ 2 - __ movq(rdx, Address(rbx, methodOopDesc::const_offset())); - __ movl(rdx, Address(rdx, constMethodOopDesc::codes_offset())); - // Shift codes right to get the index on the right. - // The bytecode fetched looks like <0xb4><0x2a> - __ shrl(rdx, 2 * BitsPerByte); - __ shll(rdx, exact_log2(in_words(ConstantPoolCacheEntry::size()))); - __ movq(rdi, Address(rdi, constantPoolOopDesc::cache_offset_in_bytes())); - - // rax: local 0 - // rbx: method - // rdx: constant pool cache index - // rdi: constant pool cache - - // check if getfield has been resolved and read constant pool cache entry - // check the validity of the cache entry by testing whether _indices field - // contains Bytecode::_getfield in b1 byte. - assert(in_words(ConstantPoolCacheEntry::size()) == 4, - "adjust shift below"); - __ movl(rcx, - Address(rdi, - rdx, - Address::times_8, - constantPoolCacheOopDesc::base_offset() + - ConstantPoolCacheEntry::indices_offset())); - __ shrl(rcx, 2 * BitsPerByte); - __ andl(rcx, 0xFF); - __ cmpl(rcx, Bytecodes::_getfield); - __ jcc(Assembler::notEqual, slow_path); - - // Note: constant pool entry is not valid before bytecode is resolved - __ movq(rcx, - Address(rdi, - rdx, - Address::times_8, - constantPoolCacheOopDesc::base_offset() + - ConstantPoolCacheEntry::f2_offset())); - // edx: flags - __ movl(rdx, - Address(rdi, - rdx, - Address::times_8, - constantPoolCacheOopDesc::base_offset() + - ConstantPoolCacheEntry::flags_offset())); - - Label notObj, notInt, notByte, notShort; - const Address field_address(rax, rcx, Address::times_1); - - // Need to differentiate between igetfield, agetfield, bgetfield etc. - // because they are different sizes. - // Use the type from the constant pool cache - __ shrl(rdx, ConstantPoolCacheEntry::tosBits); - // Make sure we don't need to mask edx for tosBits after the above shift - ConstantPoolCacheEntry::verify_tosBits(); - - __ cmpl(rdx, atos); - __ jcc(Assembler::notEqual, notObj); - // atos - __ load_heap_oop(rax, field_address); - __ jmp(xreturn_path); - - __ bind(notObj); - __ cmpl(rdx, itos); - __ jcc(Assembler::notEqual, notInt); - // itos - __ movl(rax, field_address); - __ jmp(xreturn_path); - - __ bind(notInt); - __ cmpl(rdx, btos); - __ jcc(Assembler::notEqual, notByte); - // btos - __ load_signed_byte(rax, field_address); - __ jmp(xreturn_path); - - __ bind(notByte); - __ cmpl(rdx, stos); - __ jcc(Assembler::notEqual, notShort); - // stos - __ load_signed_word(rax, field_address); - __ jmp(xreturn_path); - - __ bind(notShort); -#ifdef ASSERT - Label okay; - __ cmpl(rdx, ctos); - __ jcc(Assembler::equal, okay); - __ stop("what type is this?"); - __ bind(okay); -#endif - // ctos - __ load_unsigned_word(rax, field_address); - - __ bind(xreturn_path); - - // _ireturn/_areturn - __ popq(rdi); - __ movq(rsp, r13); - __ jmp(rdi); - __ ret(0); - - // generate a vanilla interpreter entry as the slow path - __ bind(slow_path); - (void) generate_normal_entry(false); - } else { - (void) generate_normal_entry(false); - } - - return entry_point; -} - // This method tells the deoptimizer how big an interpreted frame must be: int AbstractInterpreter::size_activation(methodOop method, int tempcount, diff --git a/hotspot/src/cpu/x86/vm/jniFastGetField_x86_32.cpp b/hotspot/src/cpu/x86/vm/jniFastGetField_x86_32.cpp index 9643c843d0d..d362b282787 100644 --- a/hotspot/src/cpu/x86/vm/jniFastGetField_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/jniFastGetField_x86_32.cpp @@ -72,25 +72,25 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { __ testb (rcx, 1); __ jcc (Assembler::notZero, slow); if (os::is_MP()) { - __ movl (rax, rcx); - __ andl (rax, 1); // rax, must end up 0 - __ movl (rdx, Address(rsp, rax, Address::times_1, 2*wordSize)); + __ mov(rax, rcx); + __ andptr(rax, 1); // rax, must end up 0 + __ movptr(rdx, Address(rsp, rax, Address::times_1, 2*wordSize)); // obj, notice rax, is 0. // rdx is data dependent on rcx. } else { - __ movl (rdx, Address(rsp, 2*wordSize)); // obj + __ movptr (rdx, Address(rsp, 2*wordSize)); // obj } - __ movl (rax, Address(rsp, 3*wordSize)); // jfieldID - __ movl (rdx, Address(rdx, 0)); // *obj - __ shrl (rax, 2); // offset + __ movptr(rax, Address(rsp, 3*wordSize)); // jfieldID + __ movptr(rdx, Address(rdx, 0)); // *obj + __ shrptr (rax, 2); // offset assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); speculative_load_pclist[count] = __ pc(); switch (type) { - case T_BOOLEAN: __ movzxb (rax, Address(rdx, rax, Address::times_1)); break; - case T_BYTE: __ movsxb (rax, Address(rdx, rax, Address::times_1)); break; - case T_CHAR: __ movzxw (rax, Address(rdx, rax, Address::times_1)); break; - case T_SHORT: __ movsxw (rax, Address(rdx, rax, Address::times_1)); break; + case T_BOOLEAN: __ movzbl (rax, Address(rdx, rax, Address::times_1)); break; + case T_BYTE: __ movsbl (rax, Address(rdx, rax, Address::times_1)); break; + case T_CHAR: __ movzwl (rax, Address(rdx, rax, Address::times_1)); break; + case T_SHORT: __ movswl (rax, Address(rdx, rax, Address::times_1)); break; case T_INT: __ movl (rax, Address(rdx, rax, Address::times_1)); break; default: ShouldNotReachHere(); } @@ -98,8 +98,8 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { Address ca1; if (os::is_MP()) { __ lea(rdx, counter); - __ xorl(rdx, rax); - __ xorl(rdx, rax); + __ xorptr(rdx, rax); + __ xorptr(rdx, rax); __ cmp32(rcx, Address(rdx, 0)); // ca1 is the same as ca because // rax, ^ counter_addr ^ rax, = address @@ -184,35 +184,37 @@ address JNI_FastGetField::generate_fast_get_long_field() { ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr()); - __ pushl (rsi); + __ push (rsi); __ mov32 (rcx, counter); __ testb (rcx, 1); __ jcc (Assembler::notZero, slow); if (os::is_MP()) { - __ movl (rax, rcx); - __ andl (rax, 1); // rax, must end up 0 - __ movl (rdx, Address(rsp, rax, Address::times_1, 3*wordSize)); + __ mov(rax, rcx); + __ andptr(rax, 1); // rax, must end up 0 + __ movptr(rdx, Address(rsp, rax, Address::times_1, 3*wordSize)); // obj, notice rax, is 0. // rdx is data dependent on rcx. } else { - __ movl (rdx, Address(rsp, 3*wordSize)); // obj + __ movptr(rdx, Address(rsp, 3*wordSize)); // obj } - __ movl (rsi, Address(rsp, 4*wordSize)); // jfieldID - __ movl (rdx, Address(rdx, 0)); // *obj - __ shrl (rsi, 2); // offset + __ movptr(rsi, Address(rsp, 4*wordSize)); // jfieldID + __ movptr(rdx, Address(rdx, 0)); // *obj + __ shrptr(rsi, 2); // offset assert(count < LIST_CAPACITY-1, "LIST_CAPACITY too small"); speculative_load_pclist[count++] = __ pc(); - __ movl (rax, Address(rdx, rsi, Address::times_1)); + __ movptr(rax, Address(rdx, rsi, Address::times_1)); +#ifndef _LP64 speculative_load_pclist[count] = __ pc(); - __ movl (rdx, Address(rdx, rsi, Address::times_1, 4)); + __ movl(rdx, Address(rdx, rsi, Address::times_1, 4)); +#endif // _LP64 if (os::is_MP()) { - __ lea (rsi, counter); - __ xorl (rsi, rdx); - __ xorl (rsi, rax); - __ xorl (rsi, rdx); - __ xorl (rsi, rax); + __ lea(rsi, counter); + __ xorptr(rsi, rdx); + __ xorptr(rsi, rax); + __ xorptr(rsi, rdx); + __ xorptr(rsi, rax); __ cmp32(rcx, Address(rsi, 0)); // ca1 is the same as ca because // rax, ^ rdx ^ counter_addr ^ rax, ^ rdx = address @@ -222,7 +224,7 @@ address JNI_FastGetField::generate_fast_get_long_field() { } __ jcc (Assembler::notEqual, slow); - __ popl (rsi); + __ pop (rsi); #ifndef _WINDOWS __ ret (0); @@ -234,7 +236,7 @@ address JNI_FastGetField::generate_fast_get_long_field() { slowcase_entry_pclist[count-1] = __ pc(); slowcase_entry_pclist[count++] = __ pc(); __ bind (slow); - __ popl (rsi); + __ pop (rsi); address slow_case_addr = jni_GetLongField_addr();; // tail call __ jump (ExternalAddress(slow_case_addr)); @@ -276,23 +278,28 @@ address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) { __ testb (rcx, 1); __ jcc (Assembler::notZero, slow); if (os::is_MP()) { - __ movl (rax, rcx); - __ andl (rax, 1); // rax, must end up 0 - __ movl (rdx, Address(rsp, rax, Address::times_1, 2*wordSize)); + __ mov(rax, rcx); + __ andptr(rax, 1); // rax, must end up 0 + __ movptr(rdx, Address(rsp, rax, Address::times_1, 2*wordSize)); // obj, notice rax, is 0. // rdx is data dependent on rcx. } else { - __ movl (rdx, Address(rsp, 2*wordSize)); // obj + __ movptr(rdx, Address(rsp, 2*wordSize)); // obj } - __ movl (rax, Address(rsp, 3*wordSize)); // jfieldID - __ movl (rdx, Address(rdx, 0)); // *obj - __ shrl (rax, 2); // offset + __ movptr(rax, Address(rsp, 3*wordSize)); // jfieldID + __ movptr(rdx, Address(rdx, 0)); // *obj + __ shrptr(rax, 2); // offset assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); speculative_load_pclist[count] = __ pc(); switch (type) { +#ifndef _LP64 case T_FLOAT: __ fld_s (Address(rdx, rax, Address::times_1)); break; case T_DOUBLE: __ fld_d (Address(rdx, rax, Address::times_1)); break; +#else + case T_FLOAT: __ movflt (xmm0, Address(robj, roffset, Address::times_1)); break; + case T_DOUBLE: __ movdbl (xmm0, Address(robj, roffset, Address::times_1)); break; +#endif // _LP64 default: ShouldNotReachHere(); } @@ -301,8 +308,9 @@ address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) { __ fst_s (Address(rsp, -4)); __ lea(rdx, counter); __ movl (rax, Address(rsp, -4)); - __ xorl(rdx, rax); - __ xorl(rdx, rax); + // garbage hi-order bits on 64bit are harmless. + __ xorptr(rdx, rax); + __ xorptr(rdx, rax); __ cmp32(rcx, Address(rdx, 0)); // rax, ^ counter_addr ^ rax, = address // ca1 is data dependent on the field diff --git a/hotspot/src/cpu/x86/vm/jniFastGetField_x86_64.cpp b/hotspot/src/cpu/x86/vm/jniFastGetField_x86_64.cpp index 31160b66f56..53204e70ede 100644 --- a/hotspot/src/cpu/x86/vm/jniFastGetField_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/jniFastGetField_x86_64.cpp @@ -67,18 +67,18 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr()); __ mov32 (rcounter, counter); - __ movq (robj, c_rarg1); + __ mov (robj, c_rarg1); __ testb (rcounter, 1); __ jcc (Assembler::notZero, slow); if (os::is_MP()) { - __ xorq (robj, rcounter); - __ xorq (robj, rcounter); // obj, since + __ xorptr(robj, rcounter); + __ xorptr(robj, rcounter); // obj, since // robj ^ rcounter ^ rcounter == robj // robj is data dependent on rcounter. } - __ movq (robj, Address(robj, 0)); // *obj - __ movq (roffset, c_rarg2); - __ shrq (roffset, 2); // offset + __ movptr(robj, Address(robj, 0)); // *obj + __ mov (roffset, c_rarg2); + __ shrptr(roffset, 2); // offset assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); speculative_load_pclist[count] = __ pc(); @@ -95,8 +95,8 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { if (os::is_MP()) { __ lea(rcounter_addr, counter); // ca is data dependent on rax. - __ xorq (rcounter_addr, rax); - __ xorq (rcounter_addr, rax); + __ xorptr(rcounter_addr, rax); + __ xorptr(rcounter_addr, rax); __ cmpl (rcounter, Address(rcounter_addr, 0)); } else { __ cmp32 (rcounter, counter); @@ -165,18 +165,18 @@ address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) { ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr()); __ mov32 (rcounter, counter); - __ movq (robj, c_rarg1); + __ mov (robj, c_rarg1); __ testb (rcounter, 1); __ jcc (Assembler::notZero, slow); if (os::is_MP()) { - __ xorq (robj, rcounter); - __ xorq (robj, rcounter); // obj, since + __ xorptr(robj, rcounter); + __ xorptr(robj, rcounter); // obj, since // robj ^ rcounter ^ rcounter == robj // robj is data dependent on rcounter. } - __ movq (robj, Address(robj, 0)); // *obj - __ movq (roffset, c_rarg2); - __ shrq (roffset, 2); // offset + __ movptr(robj, Address(robj, 0)); // *obj + __ mov (roffset, c_rarg2); + __ shrptr(roffset, 2); // offset assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); speculative_load_pclist[count] = __ pc(); @@ -190,8 +190,8 @@ address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) { __ lea(rcounter_addr, counter); __ movdq (rax, xmm0); // counter address is data dependent on xmm0. - __ xorq (rcounter_addr, rax); - __ xorq (rcounter_addr, rax); + __ xorptr(rcounter_addr, rax); + __ xorptr(rcounter_addr, rax); __ cmpl (rcounter, Address(rcounter_addr, 0)); } else { __ cmp32 (rcounter, counter); diff --git a/hotspot/src/cpu/x86/vm/nativeInst_x86.cpp b/hotspot/src/cpu/x86/vm/nativeInst_x86.cpp index f8147a4cc64..b4a3ccea503 100644 --- a/hotspot/src/cpu/x86/vm/nativeInst_x86.cpp +++ b/hotspot/src/cpu/x86/vm/nativeInst_x86.cpp @@ -223,49 +223,150 @@ void NativeMovConstReg::print() { //------------------------------------------------------------------- -#ifndef AMD64 +int NativeMovRegMem::instruction_start() const { + int off = 0; + u_char instr_0 = ubyte_at(off); -void NativeMovRegMem::copy_instruction_to(address new_instruction_address) { - int inst_size = instruction_size; - - // See if there's an instruction size prefix override. - if ( *(address(this)) == instruction_operandsize_prefix && - *(address(this)+1) != instruction_code_xmm_code ) { // Not SSE instr - inst_size += 1; + // First check to see if we have a (prefixed or not) xor + if ( instr_0 >= instruction_prefix_wide_lo && // 0x40 + instr_0 <= instruction_prefix_wide_hi) { // 0x4f + off++; + instr_0 = ubyte_at(off); } - if ( *(address(this)) == instruction_extended_prefix ) inst_size += 1; - for (int i = 0; i < instruction_size; i++) { - *(new_instruction_address + i) = *(address(this) + i); + if (instr_0 == instruction_code_xor) { + off += 2; + instr_0 = ubyte_at(off); } + + // Now look for the real instruction and the many prefix/size specifiers. + + if (instr_0 == instruction_operandsize_prefix ) { // 0x66 + off++; // Not SSE instructions + instr_0 = ubyte_at(off); + } + + if ( instr_0 == instruction_code_xmm_ss_prefix || // 0xf3 + instr_0 == instruction_code_xmm_sd_prefix) { // 0xf2 + off++; + instr_0 = ubyte_at(off); + } + + if ( instr_0 >= instruction_prefix_wide_lo && // 0x40 + instr_0 <= instruction_prefix_wide_hi) { // 0x4f + off++; + instr_0 = ubyte_at(off); + } + + + if (instr_0 == instruction_extended_prefix ) { // 0x0f + off++; + } + + return off; +} + +address NativeMovRegMem::instruction_address() const { + return addr_at(instruction_start()); +} + +address NativeMovRegMem::next_instruction_address() const { + address ret = instruction_address() + instruction_size; + u_char instr_0 = *(u_char*) instruction_address(); + switch (instr_0) { + case instruction_operandsize_prefix: + + fatal("should have skipped instruction_operandsize_prefix"); + break; + + case instruction_extended_prefix: + fatal("should have skipped instruction_extended_prefix"); + break; + + case instruction_code_mem2reg_movslq: // 0x63 + case instruction_code_mem2reg_movzxb: // 0xB6 + case instruction_code_mem2reg_movsxb: // 0xBE + case instruction_code_mem2reg_movzxw: // 0xB7 + case instruction_code_mem2reg_movsxw: // 0xBF + case instruction_code_reg2mem: // 0x89 (q/l) + case instruction_code_mem2reg: // 0x8B (q/l) + case instruction_code_reg2memb: // 0x88 + case instruction_code_mem2regb: // 0x8a + + case instruction_code_float_s: // 0xd9 fld_s a + case instruction_code_float_d: // 0xdd fld_d a + + case instruction_code_xmm_load: // 0x10 + case instruction_code_xmm_store: // 0x11 + case instruction_code_xmm_lpd: // 0x12 + { + // If there is an SIB then instruction is longer than expected + u_char mod_rm = *(u_char*)(instruction_address() + 1); + if ((mod_rm & 7) == 0x4) { + ret++; + } + } + case instruction_code_xor: + fatal("should have skipped xor lead in"); + break; + + default: + fatal("not a NativeMovRegMem"); + } + return ret; + +} + +int NativeMovRegMem::offset() const{ + int off = data_offset + instruction_start(); + u_char mod_rm = *(u_char*)(instruction_address() + 1); + // nnnn(r12|rsp) isn't coded as simple mod/rm since that is + // the encoding to use an SIB byte. Which will have the nnnn + // field off by one byte + if ((mod_rm & 7) == 0x4) { + off++; + } + return int_at(off); +} + +void NativeMovRegMem::set_offset(int x) { + int off = data_offset + instruction_start(); + u_char mod_rm = *(u_char*)(instruction_address() + 1); + // nnnn(r12|rsp) isn't coded as simple mod/rm since that is + // the encoding to use an SIB byte. Which will have the nnnn + // field off by one byte + if ((mod_rm & 7) == 0x4) { + off++; + } + set_int_at(off, x); } void NativeMovRegMem::verify() { // make sure code pattern is actually a mov [reg+offset], reg instruction u_char test_byte = *(u_char*)instruction_address(); - if ( ! ( (test_byte == instruction_code_reg2memb) - || (test_byte == instruction_code_mem2regb) - || (test_byte == instruction_code_mem2regl) - || (test_byte == instruction_code_reg2meml) - || (test_byte == instruction_code_mem2reg_movzxb ) - || (test_byte == instruction_code_mem2reg_movzxw ) - || (test_byte == instruction_code_mem2reg_movsxb ) - || (test_byte == instruction_code_mem2reg_movsxw ) - || (test_byte == instruction_code_float_s) - || (test_byte == instruction_code_float_d) - || (test_byte == instruction_code_long_volatile) ) ) - { - u_char byte1 = ((u_char*)instruction_address())[1]; - u_char byte2 = ((u_char*)instruction_address())[2]; - if ((test_byte != instruction_code_xmm_ss_prefix && - test_byte != instruction_code_xmm_sd_prefix && - test_byte != instruction_operandsize_prefix) || - byte1 != instruction_code_xmm_code || - (byte2 != instruction_code_xmm_load && - byte2 != instruction_code_xmm_lpd && - byte2 != instruction_code_xmm_store)) { + switch (test_byte) { + case instruction_code_reg2memb: // 0x88 movb a, r + case instruction_code_reg2mem: // 0x89 movl a, r (can be movq in 64bit) + case instruction_code_mem2regb: // 0x8a movb r, a + case instruction_code_mem2reg: // 0x8b movl r, a (can be movq in 64bit) + break; + + case instruction_code_mem2reg_movslq: // 0x63 movsql r, a + case instruction_code_mem2reg_movzxb: // 0xb6 movzbl r, a (movzxb) + case instruction_code_mem2reg_movzxw: // 0xb7 movzwl r, a (movzxw) + case instruction_code_mem2reg_movsxb: // 0xbe movsbl r, a (movsxb) + case instruction_code_mem2reg_movsxw: // 0xbf movswl r, a (movsxw) + break; + + case instruction_code_float_s: // 0xd9 fld_s a + case instruction_code_float_d: // 0xdd fld_d a + case instruction_code_xmm_load: // 0x10 movsd xmm, a + case instruction_code_xmm_store: // 0x11 movsd a, xmm + case instruction_code_xmm_lpd: // 0x12 movlpd xmm, a + break; + + default: fatal ("not a mov [reg+offs], reg instruction"); - } } } @@ -279,7 +380,14 @@ void NativeMovRegMem::print() { void NativeLoadAddress::verify() { // make sure code pattern is actually a mov [reg+offset], reg instruction u_char test_byte = *(u_char*)instruction_address(); - if ( ! (test_byte == instruction_code) ) { +#ifdef _LP64 + if ( (test_byte == instruction_prefix_wide || + test_byte == instruction_prefix_wide_extended) ) { + test_byte = *(u_char*)(instruction_address() + 1); + } +#endif // _LP64 + if ( ! ((test_byte == lea_instruction_code) + LP64_ONLY(|| (test_byte == mov64_instruction_code) ))) { fatal ("not a lea reg, [reg+offs] instruction"); } } @@ -289,8 +397,6 @@ void NativeLoadAddress::print() { tty->print_cr("0x%x: lea [reg + %x], reg", instruction_address(), offset()); } -#endif // !AMD64 - //-------------------------------------------------------------------------------- void NativeJump::verify() { diff --git a/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp b/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp index 255e8210f99..c3951c5af29 100644 --- a/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp +++ b/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp @@ -235,16 +235,15 @@ class NativeMovConstRegPatching: public NativeMovConstReg { } }; -#ifndef AMD64 - // An interface for accessing/manipulating native moves of the form: -// mov[b/w/l] [reg + offset], reg (instruction_code_reg2mem) -// mov[b/w/l] reg, [reg+offset] (instruction_code_mem2reg -// mov[s/z]x[w/b] [reg + offset], reg +// mov[b/w/l/q] [reg + offset], reg (instruction_code_reg2mem) +// mov[b/w/l/q] reg, [reg+offset] (instruction_code_mem2reg +// mov[s/z]x[w/b/q] [reg + offset], reg // fld_s [reg+offset] // fld_d [reg+offset] // fstp_s [reg + offset] // fstp_d [reg + offset] +// mov_literal64 scratch, ; mov[b/w/l/q] 0(scratch),reg | mov[b/w/l/q] reg,0(scratch) // // Warning: These routines must be able to handle any instruction sequences // that are generated as a result of the load/store byte,word,long @@ -255,15 +254,18 @@ class NativeMovConstRegPatching: public NativeMovConstReg { class NativeMovRegMem: public NativeInstruction { public: enum Intel_specific_constants { + instruction_prefix_wide_lo = Assembler::REX, + instruction_prefix_wide_hi = Assembler::REX_WRXB, instruction_code_xor = 0x33, instruction_extended_prefix = 0x0F, + instruction_code_mem2reg_movslq = 0x63, instruction_code_mem2reg_movzxb = 0xB6, instruction_code_mem2reg_movsxb = 0xBE, instruction_code_mem2reg_movzxw = 0xB7, instruction_code_mem2reg_movsxw = 0xBF, instruction_operandsize_prefix = 0x66, - instruction_code_reg2meml = 0x89, - instruction_code_mem2regl = 0x8b, + instruction_code_reg2mem = 0x89, + instruction_code_mem2reg = 0x8b, instruction_code_reg2memb = 0x88, instruction_code_mem2regb = 0x8a, instruction_code_float_s = 0xd9, @@ -282,73 +284,18 @@ class NativeMovRegMem: public NativeInstruction { next_instruction_offset = 4 }; - address instruction_address() const { - if (*addr_at(instruction_offset) == instruction_operandsize_prefix && - *addr_at(instruction_offset+1) != instruction_code_xmm_code) { - return addr_at(instruction_offset+1); // Not SSE instructions - } - else if (*addr_at(instruction_offset) == instruction_extended_prefix) { - return addr_at(instruction_offset+1); - } - else if (*addr_at(instruction_offset) == instruction_code_xor) { - return addr_at(instruction_offset+2); - } - else return addr_at(instruction_offset); - } + // helper + int instruction_start() const; - address next_instruction_address() const { - switch (*addr_at(instruction_offset)) { - case instruction_operandsize_prefix: - if (*addr_at(instruction_offset+1) == instruction_code_xmm_code) - return instruction_address() + instruction_size; // SSE instructions - case instruction_extended_prefix: - return instruction_address() + instruction_size + 1; - case instruction_code_reg2meml: - case instruction_code_mem2regl: - case instruction_code_reg2memb: - case instruction_code_mem2regb: - case instruction_code_xor: - return instruction_address() + instruction_size + 2; - default: - return instruction_address() + instruction_size; - } - } - int offset() const{ - if (*addr_at(instruction_offset) == instruction_operandsize_prefix && - *addr_at(instruction_offset+1) != instruction_code_xmm_code) { - return int_at(data_offset+1); // Not SSE instructions - } - else if (*addr_at(instruction_offset) == instruction_extended_prefix) { - return int_at(data_offset+1); - } - else if (*addr_at(instruction_offset) == instruction_code_xor || - *addr_at(instruction_offset) == instruction_code_xmm_ss_prefix || - *addr_at(instruction_offset) == instruction_code_xmm_sd_prefix || - *addr_at(instruction_offset) == instruction_operandsize_prefix) { - return int_at(data_offset+2); - } - else return int_at(data_offset); - } + address instruction_address() const; - void set_offset(int x) { - if (*addr_at(instruction_offset) == instruction_operandsize_prefix && - *addr_at(instruction_offset+1) != instruction_code_xmm_code) { - set_int_at(data_offset+1, x); // Not SSE instructions - } - else if (*addr_at(instruction_offset) == instruction_extended_prefix) { - set_int_at(data_offset+1, x); - } - else if (*addr_at(instruction_offset) == instruction_code_xor || - *addr_at(instruction_offset) == instruction_code_xmm_ss_prefix || - *addr_at(instruction_offset) == instruction_code_xmm_sd_prefix || - *addr_at(instruction_offset) == instruction_operandsize_prefix) { - set_int_at(data_offset+2, x); - } - else set_int_at(data_offset, x); - } + address next_instruction_address() const; + + int offset() const; + + void set_offset(int x); void add_offset_in_bytes(int add_offset) { set_offset ( ( offset() + add_offset ) ); } - void copy_instruction_to(address new_instruction_address); void verify(); void print (); @@ -385,9 +332,19 @@ class NativeMovRegMemPatching: public NativeMovRegMem { // leal reg, [reg + offset] class NativeLoadAddress: public NativeMovRegMem { +#ifdef AMD64 + static const bool has_rex = true; + static const int rex_size = 1; +#else + static const bool has_rex = false; + static const int rex_size = 0; +#endif // AMD64 public: enum Intel_specific_constants { - instruction_code = 0x8D + instruction_prefix_wide = Assembler::REX_W, + instruction_prefix_wide_extended = Assembler::REX_WB, + lea_instruction_code = 0x8D, + mov64_instruction_code = 0xB8 }; void verify(); @@ -406,8 +363,6 @@ class NativeLoadAddress: public NativeMovRegMem { } }; -#endif // AMD64 - // jump rel32off class NativeJump: public NativeInstruction { @@ -424,22 +379,20 @@ class NativeJump: public NativeInstruction { address next_instruction_address() const { return addr_at(next_instruction_offset); } address jump_destination() const { address dest = (int_at(data_offset)+next_instruction_address()); -#ifdef AMD64 // What is this about? + // 32bit used to encode unresolved jmp as jmp -1 + // 64bit can't produce this so it used jump to self. + // Now 32bit and 64bit use jump to self as the unresolved address + // which the inline cache code (and relocs) know about + // return -1 if jump to self dest = (dest == (address) this) ? (address) -1 : dest; -#endif // AMD64 return dest; } void set_jump_destination(address dest) { intptr_t val = dest - next_instruction_address(); #ifdef AMD64 - if (dest == (address) -1) { // can't encode jump to -1 - val = -5; // jump to self - } else { - assert((labs(val) & 0xFFFFFFFF00000000) == 0, - "must be 32bit offset"); - } + assert((labs(val) & 0xFFFFFFFF00000000) == 0 || dest == (address)-1, "must be 32bit offset or -1"); #endif // AMD64 set_int_at(data_offset, (jint)val); } @@ -568,11 +521,15 @@ inline bool NativeInstruction::is_cond_jump() { return (int_at(0) & 0xF0FF) = (ubyte_at(0) & 0xF0) == 0x70; /* short jump */ } inline bool NativeInstruction::is_safepoint_poll() { #ifdef AMD64 - return ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl && - ubyte_at(1) == 0x05 && // 00 rax 101 - ((intptr_t) addr_at(6)) + int_at(2) == (intptr_t) os::get_polling_page(); + if ( ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl && + ubyte_at(1) == 0x05 ) { // 00 rax 101 + address fault = addr_at(6) + int_at(2); + return os::is_poll_address(fault); + } else { + return false; + } #else - return ( ubyte_at(0) == NativeMovRegMem::instruction_code_mem2regl || + return ( ubyte_at(0) == NativeMovRegMem::instruction_code_mem2reg || ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl ) && (ubyte_at(1)&0xC7) == 0x05 && /* Mod R/M == disp32 */ (os::is_poll_address((address)int_at(2))); diff --git a/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp b/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp index 055c237149b..4f49d14bb42 100644 --- a/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp +++ b/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp @@ -30,11 +30,11 @@ void Relocation::pd_set_data_value(address x, intptr_t o) { #ifdef AMD64 x += o; typedef Assembler::WhichOperand WhichOperand; - WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm64, call32, narrow oop + WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm, call32, narrow oop assert(which == Assembler::disp32_operand || which == Assembler::narrow_oop_operand || - which == Assembler::imm64_operand, "format unpacks ok"); - if (which == Assembler::imm64_operand) { + which == Assembler::imm_operand, "format unpacks ok"); + if (which == Assembler::imm_operand) { *pd_address_in_code() = x; } else if (which == Assembler::narrow_oop_operand) { address disp = Assembler::locate_operand(addr(), which); @@ -81,11 +81,16 @@ void Relocation::pd_set_call_destination(address x) { nativeCall_at(addr())->set_destination(x); } else if (ni->is_jump()) { NativeJump* nj = nativeJump_at(addr()); -#ifdef AMD64 + + // Unresolved jumps are recognized by a destination of -1 + // However 64bit can't actually produce such an address + // and encodes a jump to self but jump_destination will + // return a -1 as the signal. We must not relocate this + // jmp or the ic code will not see it as unresolved. + if (nj->jump_destination() == (address) -1) { - x = (address) -1; // retain jump to self + x = addr(); // jump to self } -#endif // AMD64 nj->set_jump_destination(x); } else if (ni->is_cond_jump()) { // %%%% kludge this, for now, until we get a jump_destination method @@ -106,19 +111,19 @@ address* Relocation::pd_address_in_code() { // we must parse the instruction a bit to find the embedded word. assert(is_data(), "must be a DataRelocation"); typedef Assembler::WhichOperand WhichOperand; - WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm64/imm32 + WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm/imm32 #ifdef AMD64 assert(which == Assembler::disp32_operand || which == Assembler::call32_operand || - which == Assembler::imm64_operand, "format unpacks ok"); - if (which != Assembler::imm64_operand) { + which == Assembler::imm_operand, "format unpacks ok"); + if (which != Assembler::imm_operand) { // The "address" in the code is a displacement can't return it as // and address* since it is really a jint* ShouldNotReachHere(); return NULL; } #else - assert(which == Assembler::disp32_operand || which == Assembler::imm32_operand, "format unpacks ok"); + assert(which == Assembler::disp32_operand || which == Assembler::imm_operand, "format unpacks ok"); #endif // AMD64 return (address*) Assembler::locate_operand(addr(), which); } @@ -131,11 +136,11 @@ address Relocation::pd_get_address_from_code() { // we must parse the instruction a bit to find the embedded word. assert(is_data(), "must be a DataRelocation"); typedef Assembler::WhichOperand WhichOperand; - WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm64/imm32 + WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm/imm32 assert(which == Assembler::disp32_operand || which == Assembler::call32_operand || - which == Assembler::imm64_operand, "format unpacks ok"); - if (which != Assembler::imm64_operand) { + which == Assembler::imm_operand, "format unpacks ok"); + if (which != Assembler::imm_operand) { address ip = addr(); address disp = Assembler::locate_operand(ip, which); address next_ip = Assembler::locate_next_instruction(ip); @@ -169,3 +174,44 @@ void Relocation::pd_swap_out_breakpoint(address x, short* instrs, int instrlen) NativeInstruction* ni = nativeInstruction_at(x); *(short*)ni->addr_at(0) = instrs[0]; } + +void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { +#ifdef _LP64 + typedef Assembler::WhichOperand WhichOperand; + WhichOperand which = (WhichOperand) format(); + // This format is imm but it is really disp32 + which = Assembler::disp32_operand; + address orig_addr = old_addr_for(addr(), src, dest); + NativeInstruction* oni = nativeInstruction_at(orig_addr); + int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which); + // This poll_addr is incorrect by the size of the instruction it is irrelevant + intptr_t poll_addr = (intptr_t)oni + *orig_disp; + + NativeInstruction* ni = nativeInstruction_at(addr()); + intptr_t new_disp = poll_addr - (intptr_t) ni; + + int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which); + * disp = (int32_t)new_disp; + +#endif // _LP64 +} + +void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { +#ifdef _LP64 + typedef Assembler::WhichOperand WhichOperand; + WhichOperand which = (WhichOperand) format(); + // This format is imm but it is really disp32 + which = Assembler::disp32_operand; + address orig_addr = old_addr_for(addr(), src, dest); + NativeInstruction* oni = nativeInstruction_at(orig_addr); + int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which); + // This poll_addr is incorrect by the size of the instruction it is irrelevant + intptr_t poll_addr = (intptr_t)oni + *orig_disp; + + NativeInstruction* ni = nativeInstruction_at(addr()); + intptr_t new_disp = poll_addr - (intptr_t) ni; + + int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which); + * disp = (int32_t)new_disp; +#endif // _LP64 +} diff --git a/hotspot/src/cpu/x86/vm/runtime_x86_32.cpp b/hotspot/src/cpu/x86/vm/runtime_x86_32.cpp index d8d190936b7..108bbee1378 100644 --- a/hotspot/src/cpu/x86/vm/runtime_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/runtime_x86_32.cpp @@ -78,18 +78,18 @@ void OptoRuntime::generate_exception_blob() { address start = __ pc(); - __ pushl(rdx); - __ subl(rsp, return_off * wordSize); // Prolog! + __ push(rdx); + __ subptr(rsp, return_off * wordSize); // Prolog! // rbp, location is implicitly known - __ movl(Address(rsp,rbp_off *wordSize),rbp); + __ movptr(Address(rsp,rbp_off *wordSize), rbp); // Store exception in Thread object. We cannot pass any arguments to the // handle_exception call, since we do not want to make any assumption // about the size of the frame where the exception happened in. __ get_thread(rcx); - __ movl(Address(rcx, JavaThread::exception_oop_offset()), rax); - __ movl(Address(rcx, JavaThread::exception_pc_offset()), rdx); + __ movptr(Address(rcx, JavaThread::exception_oop_offset()), rax); + __ movptr(Address(rcx, JavaThread::exception_pc_offset()), rdx); // This call does all the hard work. It checks if an exception handler // exists in the method. @@ -97,7 +97,7 @@ void OptoRuntime::generate_exception_blob() { // If not, it prepares for stack-unwinding, restoring the callee-save // registers of the frame being removed. // - __ movl(Address(rsp, thread_off * wordSize), rcx); // Thread is first argument + __ movptr(Address(rsp, thread_off * wordSize), rcx); // Thread is first argument __ set_last_Java_frame(rcx, noreg, noreg, NULL); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, OptoRuntime::handle_exception_C))); @@ -108,10 +108,10 @@ void OptoRuntime::generate_exception_blob() { __ reset_last_Java_frame(rcx, false, false); // Restore callee-saved registers - __ movl(rbp, Address(rsp, rbp_off * wordSize)); + __ movptr(rbp, Address(rsp, rbp_off * wordSize)); - __ addl(rsp, return_off * wordSize); // Epilog! - __ popl(rdx); // Exception pc + __ addptr(rsp, return_off * wordSize); // Epilog! + __ pop(rdx); // Exception pc // rax,: exception handler for given @@ -119,23 +119,23 @@ void OptoRuntime::generate_exception_blob() { // We have a handler in rax, (could be deopt blob) // rdx - throwing pc, deopt blob will need it. - __ pushl(rax); + __ push(rax); // rcx contains handler address __ get_thread(rcx); // TLS // Get the exception - __ movl(rax, Address(rcx, JavaThread::exception_oop_offset())); + __ movptr(rax, Address(rcx, JavaThread::exception_oop_offset())); // Get the exception pc in case we are deoptimized - __ movl(rdx, Address(rcx, JavaThread::exception_pc_offset())); + __ movptr(rdx, Address(rcx, JavaThread::exception_pc_offset())); #ifdef ASSERT - __ movl(Address(rcx, JavaThread::exception_handler_pc_offset()), 0); - __ movl(Address(rcx, JavaThread::exception_pc_offset()), 0); + __ movptr(Address(rcx, JavaThread::exception_handler_pc_offset()), (int32_t)NULL_WORD); + __ movptr(Address(rcx, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD); #endif // Clear the exception oop so GC no longer processes it as a root. - __ movl(Address(rcx, JavaThread::exception_oop_offset()), 0); + __ movptr(Address(rcx, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD); - __ popl(rcx); + __ pop(rcx); // rax,: exception oop // rcx: exception handler diff --git a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp index 85befcf4e78..7c0aa6bf556 100644 --- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp @@ -118,12 +118,12 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_ // save registers, fpu state, and flags // We assume caller has already has return address slot on the stack // We push epb twice in this sequence because we want the real rbp, - // to be under the return like a normal enter and we want to use pushad + // to be under the return like a normal enter and we want to use pusha // We push by hand instead of pusing push __ enter(); - __ pushad(); - __ pushfd(); - __ subl(rsp,FPU_regs_live*sizeof(jdouble)); // Push FPU registers space + __ pusha(); + __ pushf(); + __ subptr(rsp,FPU_regs_live*sizeof(jdouble)); // Push FPU registers space __ push_FPU_state(); // Save FPU state & init if (verify_fpu) { @@ -270,12 +270,12 @@ void RegisterSaver::restore_live_registers(MacroAssembler* masm) { __ movdbl(xmm7,Address(rsp,xmm7_off*wordSize)); } __ pop_FPU_state(); - __ addl(rsp,FPU_regs_live*sizeof(jdouble)); // Pop FPU registers + __ addptr(rsp, FPU_regs_live*sizeof(jdouble)); // Pop FPU registers - __ popfd(); - __ popad(); + __ popf(); + __ popa(); // Get the rbp, described implicitly by the frame sender code (no oopMap) - __ popl(rbp); + __ pop(rbp); } @@ -296,10 +296,10 @@ void RegisterSaver::restore_result_registers(MacroAssembler* masm) { } else if( UseSSE >= 2 ) { __ movdbl(xmm0, Address(rsp, xmm0_off*wordSize)); } - __ movl(rax, Address(rsp, rax_off*wordSize)); - __ movl(rdx, Address(rsp, rdx_off*wordSize)); + __ movptr(rax, Address(rsp, rax_off*wordSize)); + __ movptr(rdx, Address(rsp, rdx_off*wordSize)); // Pop all of the register save are off the stack except the return address - __ addl(rsp, return_off * wordSize); + __ addptr(rsp, return_off * wordSize); } // The java_calling_convention describes stack locations as ideal slots on @@ -448,22 +448,22 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, static void patch_callers_callsite(MacroAssembler *masm) { Label L; __ verify_oop(rbx); - __ cmpl(Address(rbx, in_bytes(methodOopDesc::code_offset())), NULL_WORD); + __ cmpptr(Address(rbx, in_bytes(methodOopDesc::code_offset())), (int32_t)NULL_WORD); __ jcc(Assembler::equal, L); // Schedule the branch target address early. // Call into the VM to patch the caller, then jump to compiled callee // rax, isn't live so capture return address while we easily can - __ movl(rax, Address(rsp, 0)); - __ pushad(); - __ pushfd(); + __ movptr(rax, Address(rsp, 0)); + __ pusha(); + __ pushf(); if (UseSSE == 1) { - __ subl(rsp, 2*wordSize); + __ subptr(rsp, 2*wordSize); __ movflt(Address(rsp, 0), xmm0); __ movflt(Address(rsp, wordSize), xmm1); } if (UseSSE >= 2) { - __ subl(rsp, 4*wordSize); + __ subptr(rsp, 4*wordSize); __ movdbl(Address(rsp, 0), xmm0); __ movdbl(Address(rsp, 2*wordSize), xmm1); } @@ -477,26 +477,26 @@ static void patch_callers_callsite(MacroAssembler *masm) { #endif /* COMPILER2 */ // VM needs caller's callsite - __ pushl(rax); + __ push(rax); // VM needs target method - __ pushl(rbx); + __ push(rbx); __ verify_oop(rbx); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite))); - __ addl(rsp, 2*wordSize); + __ addptr(rsp, 2*wordSize); if (UseSSE == 1) { __ movflt(xmm0, Address(rsp, 0)); __ movflt(xmm1, Address(rsp, wordSize)); - __ addl(rsp, 2*wordSize); + __ addptr(rsp, 2*wordSize); } if (UseSSE >= 2) { __ movdbl(xmm0, Address(rsp, 0)); __ movdbl(xmm1, Address(rsp, 2*wordSize)); - __ addl(rsp, 4*wordSize); + __ addptr(rsp, 4*wordSize); } - __ popfd(); - __ popad(); + __ popf(); + __ popa(); __ bind(L); } @@ -506,13 +506,13 @@ static void tag_stack(MacroAssembler *masm, const BasicType sig, int st_off) { if (TaggedStackInterpreter) { int tag_offset = st_off + Interpreter::expr_tag_offset_in_bytes(0); if (sig == T_OBJECT || sig == T_ARRAY) { - __ movl(Address(rsp, tag_offset), frame::TagReference); + __ movptr(Address(rsp, tag_offset), frame::TagReference); } else if (sig == T_LONG || sig == T_DOUBLE) { int next_tag_offset = st_off + Interpreter::expr_tag_offset_in_bytes(1); - __ movl(Address(rsp, next_tag_offset), frame::TagValue); - __ movl(Address(rsp, tag_offset), frame::TagValue); + __ movptr(Address(rsp, next_tag_offset), frame::TagValue); + __ movptr(Address(rsp, tag_offset), frame::TagValue); } else { - __ movl(Address(rsp, tag_offset), frame::TagValue); + __ movptr(Address(rsp, tag_offset), frame::TagValue); } } } @@ -561,12 +561,12 @@ static void gen_c2i_adapter(MacroAssembler *masm, int extraspace = total_args_passed * Interpreter::stackElementSize(); // Get return address - __ popl(rax); + __ pop(rax); // set senderSP value - __ movl(rsi, rsp); + __ movptr(rsi, rsp); - __ subl(rsp, extraspace); + __ subptr(rsp, extraspace); // Now write the args into the outgoing interpreter space for (int i = 0; i < total_args_passed; i++) { @@ -577,6 +577,8 @@ static void gen_c2i_adapter(MacroAssembler *masm, // st_off points to lowest address on stack. int st_off = ((total_args_passed - 1) - i) * Interpreter::stackElementSize(); + int next_off = st_off - Interpreter::stackElementSize(); + // Say 4 args: // i st_off // 0 12 T_LONG @@ -596,18 +598,25 @@ static void gen_c2i_adapter(MacroAssembler *masm, if (!r_2->is_valid()) { __ movl(rdi, Address(rsp, ld_off)); - __ movl(Address(rsp, st_off), rdi); + __ movptr(Address(rsp, st_off), rdi); tag_stack(masm, sig_bt[i], st_off); } else { // ld_off == LSW, ld_off+VMRegImpl::stack_slot_size == MSW // st_off == MSW, st_off-wordSize == LSW - int next_off = st_off - Interpreter::stackElementSize(); - __ movl(rdi, Address(rsp, ld_off)); - __ movl(Address(rsp, next_off), rdi); - __ movl(rdi, Address(rsp, ld_off + wordSize)); - __ movl(Address(rsp, st_off), rdi); + __ movptr(rdi, Address(rsp, ld_off)); + __ movptr(Address(rsp, next_off), rdi); +#ifndef _LP64 + __ movptr(rdi, Address(rsp, ld_off + wordSize)); + __ movptr(Address(rsp, st_off), rdi); +#else +#ifdef ASSERT + // Overwrite the unused slot with known junk + __ mov64(rax, CONST64(0xdeadffffdeadaaaa)); + __ movptr(Address(rsp, st_off), rax); +#endif /* ASSERT */ +#endif // _LP64 tag_stack(masm, sig_bt[i], next_off); } } else if (r_1->is_Register()) { @@ -617,7 +626,22 @@ static void gen_c2i_adapter(MacroAssembler *masm, tag_stack(masm, sig_bt[i], st_off); } else { // long/double in gpr - ShouldNotReachHere(); + NOT_LP64(ShouldNotReachHere()); + // Two VMRegs can be T_OBJECT, T_ADDRESS, T_DOUBLE, T_LONG + // T_DOUBLE and T_LONG use two slots in the interpreter + if ( sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) { + // long/double in gpr +#ifdef ASSERT + // Overwrite the unused slot with known junk + LP64_ONLY(__ mov64(rax, CONST64(0xdeadffffdeadaaab))); + __ movptr(Address(rsp, st_off), rax); +#endif /* ASSERT */ + __ movptr(Address(rsp, next_off), r); + tag_stack(masm, sig_bt[i], next_off); + } else { + __ movptr(Address(rsp, st_off), r); + tag_stack(masm, sig_bt[i], st_off); + } } } else { assert(r_1->is_XMMRegister(), ""); @@ -632,9 +656,9 @@ static void gen_c2i_adapter(MacroAssembler *masm, } // Schedule the branch target address early. - __ movl(rcx, Address(rbx, in_bytes(methodOopDesc::interpreter_entry_offset()))); + __ movptr(rcx, Address(rbx, in_bytes(methodOopDesc::interpreter_entry_offset()))); // And repush original return address - __ pushl(rax); + __ push(rax); __ jmp(rcx); } @@ -645,11 +669,11 @@ static void move_i2c_double(MacroAssembler *masm, XMMRegister r, Register saved_ int next_val_off = ld_off - Interpreter::stackElementSize(); if (TaggedStackInterpreter) { // use tag slot temporarily for MSW - __ movl(rsi, Address(saved_sp, ld_off)); - __ movl(Address(saved_sp, next_val_off+wordSize), rsi); + __ movptr(rsi, Address(saved_sp, ld_off)); + __ movptr(Address(saved_sp, next_val_off+wordSize), rsi); __ movdbl(r, Address(saved_sp, next_val_off)); // restore tag - __ movl(Address(saved_sp, next_val_off+wordSize), frame::TagValue); + __ movptr(Address(saved_sp, next_val_off+wordSize), frame::TagValue); } else { __ movdbl(r, Address(saved_sp, next_val_off)); } @@ -685,7 +709,7 @@ static void gen_i2c_adapter(MacroAssembler *masm, // code goes non-entrant while we get args ready. // Pick up the return address - __ movl(rax, Address(rsp, 0)); + __ movptr(rax, Address(rsp, 0)); // If UseSSE >= 2 then no cleanup is needed on the return to the // interpreter so skip fixing up the return entry point unless @@ -696,10 +720,10 @@ static void gen_i2c_adapter(MacroAssembler *masm, // cleanup than if the interpreter returned to the call stub. ExternalAddress stub_return_address(StubRoutines::_call_stub_return_address); - __ cmp32(rax, stub_return_address.addr()); + __ cmpptr(rax, stub_return_address.addr()); __ jcc(Assembler::notEqual, chk_int); - assert(StubRoutines::i486::get_call_stub_compiled_return() != NULL, "must be set"); - __ lea(rax, ExternalAddress(StubRoutines::i486::get_call_stub_compiled_return())); + assert(StubRoutines::x86::get_call_stub_compiled_return() != NULL, "must be set"); + __ lea(rax, ExternalAddress(StubRoutines::x86::get_call_stub_compiled_return())); __ jmp(skip); // It must be the interpreter since we never get here via a c2i (unlike Azul) @@ -708,13 +732,13 @@ static void gen_i2c_adapter(MacroAssembler *masm, #ifdef ASSERT { Label ok; - __ cmpl(Address(rax, -8), Interpreter::return_sentinel); + __ cmpl(Address(rax, -2*wordSize), Interpreter::return_sentinel); __ jcc(Assembler::equal, ok); __ int3(); __ bind(ok); } #endif // ASSERT - __ movl(rax, Address(rax, -4)); + __ movptr(rax, Address(rax, -wordSize)); __ bind(skip); } @@ -723,7 +747,7 @@ static void gen_i2c_adapter(MacroAssembler *masm, // Must preserve original SP for loading incoming arguments because // we need to align the outgoing SP for compiled code. - __ movl(rdi, rsp); + __ movptr(rdi, rsp); // Cut-out for having no stack args. Since up to 2 int/oop args are passed // in registers, we will occasionally have no stack args. @@ -737,24 +761,24 @@ static void gen_i2c_adapter(MacroAssembler *masm, comp_words_on_stack = round_to(comp_args_on_stack*4, wordSize)>>LogBytesPerWord; // Round up to miminum stack alignment, in wordSize comp_words_on_stack = round_to(comp_words_on_stack, 2); - __ subl(rsp, comp_words_on_stack * wordSize); + __ subptr(rsp, comp_words_on_stack * wordSize); } // Align the outgoing SP - __ andl(rsp, -(StackAlignmentInBytes)); + __ andptr(rsp, -(StackAlignmentInBytes)); // push the return address on the stack (note that pushing, rather // than storing it, yields the correct frame alignment for the callee) - __ pushl(rax); + __ push(rax); // Put saved SP in another register const Register saved_sp = rax; - __ movl(saved_sp, rdi); + __ movptr(saved_sp, rdi); // Will jump to the compiled code just as if compiled code was doing it. // Pre-load the register-jump target early, to schedule it better. - __ movl(rdi, Address(rbx, in_bytes(methodOopDesc::from_compiled_offset()))); + __ movptr(rdi, Address(rbx, in_bytes(methodOopDesc::from_compiled_offset()))); // Now generate the shuffle code. Pick up all register args and move the // rest through the floating point stack top. @@ -794,7 +818,7 @@ static void gen_i2c_adapter(MacroAssembler *masm, // __ fld_s(Address(saved_sp, ld_off)); // __ fstp_s(Address(rsp, st_off)); __ movl(rsi, Address(saved_sp, ld_off)); - __ movl(Address(rsp, st_off), rsi); + __ movptr(Address(rsp, st_off), rsi); } else { // Interpreter local[n] == MSW, local[n+1] == LSW however locals // are accessed as negative so LSW is at LOW address @@ -803,20 +827,44 @@ static void gen_i2c_adapter(MacroAssembler *masm, // st_off is LSW (i.e. reg.first()) // __ fld_d(Address(saved_sp, next_off)); // __ fstp_d(Address(rsp, st_off)); - __ movl(rsi, Address(saved_sp, next_off)); - __ movl(Address(rsp, st_off), rsi); - __ movl(rsi, Address(saved_sp, ld_off)); - __ movl(Address(rsp, st_off + wordSize), rsi); + // + // We are using two VMRegs. This can be either T_OBJECT, T_ADDRESS, T_LONG, or T_DOUBLE + // the interpreter allocates two slots but only uses one for thr T_LONG or T_DOUBLE case + // So we must adjust where to pick up the data to match the interpreter. + // + // Interpreter local[n] == MSW, local[n+1] == LSW however locals + // are accessed as negative so LSW is at LOW address + + // ld_off is MSW so get LSW + const int offset = (NOT_LP64(true ||) sig_bt[i]==T_LONG||sig_bt[i]==T_DOUBLE)? + next_off : ld_off; + __ movptr(rsi, Address(saved_sp, offset)); + __ movptr(Address(rsp, st_off), rsi); +#ifndef _LP64 + __ movptr(rsi, Address(saved_sp, ld_off)); + __ movptr(Address(rsp, st_off + wordSize), rsi); +#endif // _LP64 } } else if (r_1->is_Register()) { // Register argument Register r = r_1->as_Register(); assert(r != rax, "must be different"); if (r_2->is_valid()) { + // + // We are using two VMRegs. This can be either T_OBJECT, T_ADDRESS, T_LONG, or T_DOUBLE + // the interpreter allocates two slots but only uses one for thr T_LONG or T_DOUBLE case + // So we must adjust where to pick up the data to match the interpreter. + + const int offset = (NOT_LP64(true ||) sig_bt[i]==T_LONG||sig_bt[i]==T_DOUBLE)? + next_off : ld_off; + + // this can be a misaligned move + __ movptr(r, Address(saved_sp, offset)); +#ifndef _LP64 assert(r_2->as_Register() != rax, "need another temporary register"); // Remember r_1 is low address (and LSB on x86) // So r_2 gets loaded from high address regardless of the platform - __ movl(r_2->as_Register(), Address(saved_sp, ld_off)); - __ movl(r, Address(saved_sp, next_off)); + __ movptr(r_2->as_Register(), Address(saved_sp, ld_off)); +#endif // _LP64 } else { __ movl(r, Address(saved_sp, ld_off)); } @@ -841,13 +889,13 @@ static void gen_i2c_adapter(MacroAssembler *masm, // and the vm will find there should this case occur. __ get_thread(rax); - __ movl(Address(rax, JavaThread::callee_target_offset()), rbx); + __ movptr(Address(rax, JavaThread::callee_target_offset()), rbx); // move methodOop to rax, in case we end up in an c2i adapter. // the c2i adapters expect methodOop in rax, (c2) because c2's // resolve stubs return the result (the method) in rax,. // I'd love to fix this. - __ movl(rax, rbx); + __ mov(rax, rbx); __ jmp(rdi); } @@ -883,16 +931,16 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm Label missed; __ verify_oop(holder); - __ movl(temp, Address(receiver, oopDesc::klass_offset_in_bytes())); + __ movptr(temp, Address(receiver, oopDesc::klass_offset_in_bytes())); __ verify_oop(temp); - __ cmpl(temp, Address(holder, compiledICHolderOopDesc::holder_klass_offset())); - __ movl(rbx, Address(holder, compiledICHolderOopDesc::holder_method_offset())); + __ cmpptr(temp, Address(holder, compiledICHolderOopDesc::holder_klass_offset())); + __ movptr(rbx, Address(holder, compiledICHolderOopDesc::holder_method_offset())); __ jcc(Assembler::notEqual, missed); // Method might have been compiled since the call site was patched to // interpreted if that is the case treat it as a miss so we can get // the call site corrected. - __ cmpl(Address(rbx, in_bytes(methodOopDesc::code_offset())), NULL_WORD); + __ cmpptr(Address(rbx, in_bytes(methodOopDesc::code_offset())), (int32_t)NULL_WORD); __ jcc(Assembler::equal, skip_fixup); __ bind(missed); @@ -953,17 +1001,20 @@ static void simple_move32(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { // stack to stack // __ ld(FP, reg2offset(src.first()) + STACK_BIAS, L5); // __ st(L5, SP, reg2offset(dst.first()) + STACK_BIAS); - __ movl(rax, Address(rbp, reg2offset_in(src.first()))); - __ movl(Address(rsp, reg2offset_out(dst.first())), rax); + __ movl2ptr(rax, Address(rbp, reg2offset_in(src.first()))); + __ movptr(Address(rsp, reg2offset_out(dst.first())), rax); } else { // stack to reg - __ movl(dst.first()->as_Register(), Address(rbp, reg2offset_in(src.first()))); + __ movl2ptr(dst.first()->as_Register(), Address(rbp, reg2offset_in(src.first()))); } } else if (dst.first()->is_stack()) { // reg to stack - __ movl(Address(rsp, reg2offset_out(dst.first())), src.first()->as_Register()); + // no need to sign extend on 64bit + __ movptr(Address(rsp, reg2offset_out(dst.first())), src.first()->as_Register()); } else { - __ movl(dst.first()->as_Register(), src.first()->as_Register()); + if (dst.first() != src.first()) { + __ mov(dst.first()->as_Register(), src.first()->as_Register()); + } } } @@ -987,12 +1038,12 @@ static void object_move(MacroAssembler* masm, // Oop is already on the stack as an argument Register rHandle = rax; Label nil; - __ xorl(rHandle, rHandle); - __ cmpl(Address(rbp, reg2offset_in(src.first())), NULL_WORD); + __ xorptr(rHandle, rHandle); + __ cmpptr(Address(rbp, reg2offset_in(src.first())), (int32_t)NULL_WORD); __ jcc(Assembler::equal, nil); - __ leal(rHandle, Address(rbp, reg2offset_in(src.first()))); + __ lea(rHandle, Address(rbp, reg2offset_in(src.first()))); __ bind(nil); - __ movl(Address(rsp, reg2offset_out(dst.first())), rHandle); + __ movptr(Address(rsp, reg2offset_out(dst.first())), rHandle); int offset_in_older_frame = src.first()->reg2stack() + SharedRuntime::out_preserve_stack_slots(); map->set_oop(VMRegImpl::stack2reg(offset_in_older_frame + framesize_in_slots)); @@ -1007,15 +1058,15 @@ static void object_move(MacroAssembler* masm, int oop_slot = (rOop == rcx ? 0 : 1) * VMRegImpl::slots_per_word + oop_handle_offset; int offset = oop_slot*VMRegImpl::stack_slot_size; Label skip; - __ movl(Address(rsp, offset), rOop); + __ movptr(Address(rsp, offset), rOop); map->set_oop(VMRegImpl::stack2reg(oop_slot)); - __ xorl(rHandle, rHandle); - __ cmpl(rOop, NULL_WORD); + __ xorptr(rHandle, rHandle); + __ cmpptr(rOop, (int32_t)NULL_WORD); __ jcc(Assembler::equal, skip); - __ leal(rHandle, Address(rsp, offset)); + __ lea(rHandle, Address(rsp, offset)); __ bind(skip); // Store the handle parameter - __ movl(Address(rsp, reg2offset_out(dst.first())), rHandle); + __ movptr(Address(rsp, reg2offset_out(dst.first())), rHandle); if (is_receiver) { *receiver_offset = offset; } @@ -1033,7 +1084,7 @@ static void float_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { if (src.first()->is_stack()) { __ movl(rax, Address(rbp, reg2offset_in(src.first()))); - __ movl(Address(rsp, reg2offset_out(dst.first())), rax); + __ movptr(Address(rsp, reg2offset_out(dst.first())), rax); } else { // reg to stack __ movflt(Address(rsp, reg2offset_out(dst.first())), src.first()->as_XMMRegister()); @@ -1050,10 +1101,10 @@ static void long_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { if (src.first()->is_stack() && dst.first()->is_stack()) { assert(src.second()->is_stack() && dst.second()->is_stack(), "must be all stack"); - __ movl(rax, Address(rbp, reg2offset_in(src.first()))); - __ movl(rbx, Address(rbp, reg2offset_in(src.second()))); - __ movl(Address(rsp, reg2offset_out(dst.first())), rax); - __ movl(Address(rsp, reg2offset_out(dst.second())), rbx); + __ movptr(rax, Address(rbp, reg2offset_in(src.first()))); + NOT_LP64(__ movptr(rbx, Address(rbp, reg2offset_in(src.second())))); + __ movptr(Address(rsp, reg2offset_out(dst.first())), rax); + NOT_LP64(__ movptr(Address(rsp, reg2offset_out(dst.second())), rbx)); } else { ShouldNotReachHere(); } @@ -1074,10 +1125,10 @@ static void double_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { if (src.first()->is_stack()) { // source is all stack - __ movl(rax, Address(rbp, reg2offset_in(src.first()))); - __ movl(rbx, Address(rbp, reg2offset_in(src.second()))); - __ movl(Address(rsp, reg2offset_out(dst.first())), rax); - __ movl(Address(rsp, reg2offset_out(dst.second())), rbx); + __ movptr(rax, Address(rbp, reg2offset_in(src.first()))); + NOT_LP64(__ movptr(rbx, Address(rbp, reg2offset_in(src.second())))); + __ movptr(Address(rsp, reg2offset_out(dst.first())), rax); + NOT_LP64(__ movptr(Address(rsp, reg2offset_out(dst.second())), rbx)); } else { // reg to stack // No worries about stack alignment @@ -1098,11 +1149,11 @@ void SharedRuntime::save_native_result(MacroAssembler *masm, BasicType ret_type, break; case T_VOID: break; case T_LONG: - __ movl(Address(rbp, -wordSize), rax); - __ movl(Address(rbp, -2*wordSize), rdx); + __ movptr(Address(rbp, -wordSize), rax); + NOT_LP64(__ movptr(Address(rbp, -2*wordSize), rdx)); break; default: { - __ movl(Address(rbp, -wordSize), rax); + __ movptr(Address(rbp, -wordSize), rax); } } } @@ -1118,12 +1169,12 @@ void SharedRuntime::restore_native_result(MacroAssembler *masm, BasicType ret_ty __ fld_d(Address(rbp, -2*wordSize)); break; case T_LONG: - __ movl(rax, Address(rbp, -wordSize)); - __ movl(rdx, Address(rbp, -2*wordSize)); + __ movptr(rax, Address(rbp, -wordSize)); + NOT_LP64(__ movptr(rdx, Address(rbp, -2*wordSize))); break; case T_VOID: break; default: { - __ movl(rax, Address(rbp, -wordSize)); + __ movptr(rax, Address(rbp, -wordSize)); } } } @@ -1268,7 +1319,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, __ verify_oop(receiver); - __ cmpl(ic_reg, Address(receiver, oopDesc::klass_offset_in_bytes())); + __ cmpptr(ic_reg, Address(receiver, oopDesc::klass_offset_in_bytes())); __ jcc(Assembler::equal, hit); __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); @@ -1291,23 +1342,23 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, Label slowCase; Register receiver = rcx; Register result = rax; - __ movl(result, Address(receiver, oopDesc::mark_offset_in_bytes())); + __ movptr(result, Address(receiver, oopDesc::mark_offset_in_bytes())); // check if locked - __ testl (result, markOopDesc::unlocked_value); + __ testptr(result, markOopDesc::unlocked_value); __ jcc (Assembler::zero, slowCase); if (UseBiasedLocking) { // Check if biased and fall through to runtime if so - __ testl (result, markOopDesc::biased_lock_bit_in_place); + __ testptr(result, markOopDesc::biased_lock_bit_in_place); __ jcc (Assembler::notZero, slowCase); } // get hash - __ andl (result, markOopDesc::hash_mask_in_place); + __ andptr(result, markOopDesc::hash_mask_in_place); // test if hashCode exists __ jcc (Assembler::zero, slowCase); - __ shrl (result, markOopDesc::hash_shift); + __ shrptr(result, markOopDesc::hash_shift); __ ret(0); __ bind (slowCase); } @@ -1329,7 +1380,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // Generate a new frame for the wrapper. __ enter(); // -2 because return address is already present and so is saved rbp, - __ subl(rsp, stack_size - 2*wordSize); + __ subptr(rsp, stack_size - 2*wordSize); // Frame is now completed as far a size and linkage. @@ -1450,13 +1501,13 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, __ movoop(oop_handle_reg, JNIHandles::make_local(Klass::cast(method->method_holder())->java_mirror())); // Now handlize the static class mirror it's known not-null. - __ movl(Address(rsp, klass_offset), oop_handle_reg); + __ movptr(Address(rsp, klass_offset), oop_handle_reg); map->set_oop(VMRegImpl::stack2reg(klass_slot_offset)); // Now get the handle - __ leal(oop_handle_reg, Address(rsp, klass_offset)); + __ lea(oop_handle_reg, Address(rsp, klass_offset)); // store the klass handle as second argument - __ movl(Address(rsp, wordSize), oop_handle_reg); + __ movptr(Address(rsp, wordSize), oop_handle_reg); } // Change state to native (we save the return address in the thread, since it might not @@ -1497,14 +1548,14 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, const int mark_word_offset = BasicLock::displaced_header_offset_in_bytes(); // Get the handle (the 2nd argument) - __ movl(oop_handle_reg, Address(rsp, wordSize)); + __ movptr(oop_handle_reg, Address(rsp, wordSize)); // Get address of the box - __ leal(lock_reg, Address(rbp, lock_slot_rbp_offset)); + __ lea(lock_reg, Address(rbp, lock_slot_rbp_offset)); // Load the oop from the handle - __ movl(obj_reg, Address(oop_handle_reg, 0)); + __ movptr(obj_reg, Address(oop_handle_reg, 0)); if (UseBiasedLocking) { // Note that oop_handle_reg is trashed during this call @@ -1512,13 +1563,13 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, } // Load immediate 1 into swap_reg %rax, - __ movl(swap_reg, 1); + __ movptr(swap_reg, 1); // Load (object->mark() | 1) into swap_reg %rax, - __ orl(swap_reg, Address(obj_reg, 0)); + __ orptr(swap_reg, Address(obj_reg, 0)); // Save (object->mark() | 1) into BasicLock's displaced header - __ movl(Address(lock_reg, mark_word_offset), swap_reg); + __ movptr(Address(lock_reg, mark_word_offset), swap_reg); if (os::is_MP()) { __ lock(); @@ -1526,7 +1577,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // src -> dest iff dest == rax, else rax, <- dest // *obj_reg = lock_reg iff *obj_reg == rax, else rax, = *(obj_reg) - __ cmpxchg(lock_reg, Address(obj_reg, 0)); + __ cmpxchgptr(lock_reg, Address(obj_reg, 0)); __ jcc(Assembler::equal, lock_done); // Test if the oopMark is an obvious stack pointer, i.e., @@ -1538,18 +1589,18 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // least significant 2 bits clear. // NOTE: the oopMark is in swap_reg %rax, as the result of cmpxchg - __ subl(swap_reg, rsp); - __ andl(swap_reg, 3 - os::vm_page_size()); + __ subptr(swap_reg, rsp); + __ andptr(swap_reg, 3 - os::vm_page_size()); // Save the test result, for recursive case, the result is zero - __ movl(Address(lock_reg, mark_word_offset), swap_reg); + __ movptr(Address(lock_reg, mark_word_offset), swap_reg); __ jcc(Assembler::notEqual, slow_path_lock); // Slow path will re-enter here __ bind(lock_done); if (UseBiasedLocking) { // Re-fetch oop_handle_reg as we trashed it above - __ movl(oop_handle_reg, Address(rsp, wordSize)); + __ movptr(oop_handle_reg, Address(rsp, wordSize)); } } @@ -1559,8 +1610,8 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // get JNIEnv* which is first argument to native - __ leal(rdx, Address(thread, in_bytes(JavaThread::jni_environment_offset()))); - __ movl(Address(rsp, 0), rdx); + __ lea(rdx, Address(thread, in_bytes(JavaThread::jni_environment_offset()))); + __ movptr(Address(rsp, 0), rdx); // Now set thread in native __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native); @@ -1575,7 +1626,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // Unpack native results. switch (ret_type) { case T_BOOLEAN: __ c2bool(rax); break; - case T_CHAR : __ andl(rax, 0xFFFF); break; + case T_CHAR : __ andptr(rax, 0xFFFF); break; case T_BYTE : __ sign_extend_byte (rax); break; case T_SHORT : __ sign_extend_short(rax); break; case T_INT : /* nothing to do */ break; @@ -1602,7 +1653,10 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, if(os::is_MP()) { if (UseMembar) { - __ membar(); // Force this write out before the read below + // Force this write out before the read below + __ membar(Assembler::Membar_mask_bits( + Assembler::LoadLoad | Assembler::LoadStore | + Assembler::StoreLoad | Assembler::StoreStore)); } else { // Write serialization page so VM thread can do a pseudo remote membar. // We use the current thread pointer to calculate a thread specific @@ -1636,7 +1690,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // by hand. // save_native_result(masm, ret_type, stack_slots); - __ pushl(thread); + __ push(thread); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans))); __ increment(rsp, wordSize); @@ -1669,7 +1723,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, Label done; // Get locked oop from the handle we passed to jni - __ movl(obj_reg, Address(oop_handle_reg, 0)); + __ movptr(obj_reg, Address(oop_handle_reg, 0)); if (UseBiasedLocking) { __ biased_locking_exit(obj_reg, rbx, done); @@ -1677,7 +1731,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // Simple recursive lock? - __ cmpl(Address(rbp, lock_slot_rbp_offset), NULL_WORD); + __ cmpptr(Address(rbp, lock_slot_rbp_offset), (int32_t)NULL_WORD); __ jcc(Assembler::equal, done); // Must save rax, if if it is live now because cmpxchg must use it @@ -1686,10 +1740,10 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, } // get old displaced header - __ movl(rbx, Address(rbp, lock_slot_rbp_offset)); + __ movptr(rbx, Address(rbp, lock_slot_rbp_offset)); // get address of the stack lock - __ leal(rax, Address(rbp, lock_slot_rbp_offset)); + __ lea(rax, Address(rbp, lock_slot_rbp_offset)); // Atomic swap old header if oop still contains the stack lock if (os::is_MP()) { @@ -1698,7 +1752,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // src -> dest iff dest == rax, else rax, <- dest // *obj_reg = rbx, iff *obj_reg == rax, else rax, = *(obj_reg) - __ cmpxchg(rbx, Address(obj_reg, 0)); + __ cmpxchgptr(rbx, Address(obj_reg, 0)); __ jcc(Assembler::notEqual, slow_path_unlock); // slow path re-enters here @@ -1729,20 +1783,20 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // Unpack oop result if (ret_type == T_OBJECT || ret_type == T_ARRAY) { Label L; - __ cmpl(rax, NULL_WORD); + __ cmpptr(rax, (int32_t)NULL_WORD); __ jcc(Assembler::equal, L); - __ movl(rax, Address(rax, 0)); + __ movptr(rax, Address(rax, 0)); __ bind(L); __ verify_oop(rax); } // reset handle block - __ movl(rcx, Address(thread, JavaThread::active_handles_offset())); + __ movptr(rcx, Address(thread, JavaThread::active_handles_offset())); - __ movl(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), 0); + __ movptr(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); // Any exception pending? - __ cmpl(Address(thread, in_bytes(Thread::pending_exception_offset())), NULL_WORD); + __ cmpptr(Address(thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD); __ jcc(Assembler::notEqual, exception_pending); @@ -1782,15 +1836,15 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // has last_Java_frame setup. No exceptions so do vanilla call not call_VM // args are (oop obj, BasicLock* lock, JavaThread* thread) - __ pushl(thread); - __ pushl(lock_reg); - __ pushl(obj_reg); + __ push(thread); + __ push(lock_reg); + __ push(obj_reg); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_locking_C))); - __ addl(rsp, 3*wordSize); + __ addptr(rsp, 3*wordSize); #ifdef ASSERT { Label L; - __ cmpl(Address(thread, in_bytes(Thread::pending_exception_offset())), (int)NULL_WORD); + __ cmpptr(Address(thread, in_bytes(Thread::pending_exception_offset())), (int)NULL_WORD); __ jcc(Assembler::equal, L); __ stop("no pending exception allowed on exit from monitorenter"); __ bind(L); @@ -1810,29 +1864,29 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, } // Save pending exception around call to VM (which contains an EXCEPTION_MARK) - __ pushl(Address(thread, in_bytes(Thread::pending_exception_offset()))); - __ movl(Address(thread, in_bytes(Thread::pending_exception_offset())), NULL_WORD); + __ pushptr(Address(thread, in_bytes(Thread::pending_exception_offset()))); + __ movptr(Address(thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD); // should be a peal // +wordSize because of the push above - __ leal(rax, Address(rbp, lock_slot_rbp_offset)); - __ pushl(rax); + __ lea(rax, Address(rbp, lock_slot_rbp_offset)); + __ push(rax); - __ pushl(obj_reg); + __ push(obj_reg); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C))); - __ addl(rsp, 2*wordSize); + __ addptr(rsp, 2*wordSize); #ifdef ASSERT { Label L; - __ cmpl(Address(thread, in_bytes(Thread::pending_exception_offset())), NULL_WORD); + __ cmpptr(Address(thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD); __ jcc(Assembler::equal, L); __ stop("no pending exception allowed on exit complete_monitor_unlocking_C"); __ bind(L); } #endif /* ASSERT */ - __ popl(Address(thread, in_bytes(Thread::pending_exception_offset()))); + __ popptr(Address(thread, in_bytes(Thread::pending_exception_offset()))); if (ret_type == T_FLOAT || ret_type == T_DOUBLE ) { restore_native_result(masm, ret_type, stack_slots); @@ -2320,7 +2374,7 @@ void SharedRuntime::generate_deopt_blob() { map = RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words); // Normal deoptimization - __ pushl(Deoptimization::Unpack_deopt); + __ push(Deoptimization::Unpack_deopt); __ jmp(cont); int reexecute_offset = __ pc() - start; @@ -2331,7 +2385,7 @@ void SharedRuntime::generate_deopt_blob() { // No need to update map as each call to save_live_registers will produce identical oopmap (void) RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words); - __ pushl(Deoptimization::Unpack_reexecute); + __ push(Deoptimization::Unpack_reexecute); __ jmp(cont); int exception_offset = __ pc() - start; @@ -2344,8 +2398,8 @@ void SharedRuntime::generate_deopt_blob() { // unpack_with_exception_in_tls entry point. __ get_thread(rdi); - __ movl(Address(rdi, JavaThread::exception_pc_offset()), rdx); - __ movl(Address(rdi, JavaThread::exception_oop_offset()), rax); + __ movptr(Address(rdi, JavaThread::exception_pc_offset()), rdx); + __ movptr(Address(rdi, JavaThread::exception_oop_offset()), rax); int exception_in_tls_offset = __ pc() - start; @@ -2360,7 +2414,7 @@ void SharedRuntime::generate_deopt_blob() { // make room on stack for the return address // It will be patched later with the throwing pc. The correct value is not // available now because loading it from memory would destroy registers. - __ pushl(0); + __ push(0); // Save everything in sight. @@ -2370,24 +2424,24 @@ void SharedRuntime::generate_deopt_blob() { // Now it is safe to overwrite any register // store the correct deoptimization type - __ pushl(Deoptimization::Unpack_exception); + __ push(Deoptimization::Unpack_exception); // load throwing pc from JavaThread and patch it as the return address // of the current frame. Then clear the field in JavaThread __ get_thread(rdi); - __ movl(rdx, Address(rdi, JavaThread::exception_pc_offset())); - __ movl(Address(rbp, wordSize), rdx); - __ movl(Address(rdi, JavaThread::exception_pc_offset()), NULL_WORD); + __ movptr(rdx, Address(rdi, JavaThread::exception_pc_offset())); + __ movptr(Address(rbp, wordSize), rdx); + __ movptr(Address(rdi, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD); #ifdef ASSERT // verify that there is really an exception oop in JavaThread - __ movl(rax, Address(rdi, JavaThread::exception_oop_offset())); + __ movptr(rax, Address(rdi, JavaThread::exception_oop_offset())); __ verify_oop(rax); // verify that there is no pending exception Label no_pending_exception; - __ movl(rax, Address(rdi, Thread::pending_exception_offset())); - __ testl(rax, rax); + __ movptr(rax, Address(rdi, Thread::pending_exception_offset())); + __ testptr(rax, rax); __ jcc(Assembler::zero, no_pending_exception); __ stop("must not have pending exception here"); __ bind(no_pending_exception); @@ -2402,7 +2456,7 @@ void SharedRuntime::generate_deopt_blob() { // Call C code. Need thread and this frame, but NOT official VM entry // crud. We cannot block on this call, no GC can happen. __ get_thread(rcx); - __ pushl(rcx); + __ push(rcx); // fetch_unroll_info needs to call last_java_frame() __ set_last_Java_frame(rcx, noreg, noreg, NULL); @@ -2414,35 +2468,35 @@ void SharedRuntime::generate_deopt_blob() { oop_maps->add_gc_map( __ pc()-start, map); // Discard arg to fetch_unroll_info - __ popl(rcx); + __ pop(rcx); __ get_thread(rcx); __ reset_last_Java_frame(rcx, false, false); // Load UnrollBlock into EDI - __ movl(rdi, rax); + __ mov(rdi, rax); // Move the unpack kind to a safe place in the UnrollBlock because // we are very short of registers Address unpack_kind(rdi, Deoptimization::UnrollBlock::unpack_kind_offset_in_bytes()); // retrieve the deopt kind from where we left it. - __ popl(rax); + __ pop(rax); __ movl(unpack_kind, rax); // save the unpack_kind value Label noException; __ cmpl(rax, Deoptimization::Unpack_exception); // Was exception pending? __ jcc(Assembler::notEqual, noException); - __ movl(rax, Address(rcx, JavaThread::exception_oop_offset())); - __ movl(rdx, Address(rcx, JavaThread::exception_pc_offset())); - __ movl(Address(rcx, JavaThread::exception_oop_offset()), NULL_WORD); - __ movl(Address(rcx, JavaThread::exception_pc_offset()), NULL_WORD); + __ movptr(rax, Address(rcx, JavaThread::exception_oop_offset())); + __ movptr(rdx, Address(rcx, JavaThread::exception_pc_offset())); + __ movptr(Address(rcx, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD); + __ movptr(Address(rcx, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD); __ verify_oop(rax); // Overwrite the result registers with the exception results. - __ movl(Address(rsp, RegisterSaver::raxOffset()*wordSize), rax); - __ movl(Address(rsp, RegisterSaver::rdxOffset()*wordSize), rdx); + __ movptr(Address(rsp, RegisterSaver::raxOffset()*wordSize), rax); + __ movptr(Address(rsp, RegisterSaver::rdxOffset()*wordSize), rdx); __ bind(noException); @@ -2467,7 +2521,7 @@ void SharedRuntime::generate_deopt_blob() { // when we are done the return to frame 3 will still be on the stack. // Pop deoptimized frame - __ addl(rsp,Address(rdi,Deoptimization::UnrollBlock::size_of_deoptimized_frame_offset_in_bytes())); + __ addptr(rsp, Address(rdi,Deoptimization::UnrollBlock::size_of_deoptimized_frame_offset_in_bytes())); // sp should be pointing at the return address to the caller (3) @@ -2478,12 +2532,12 @@ void SharedRuntime::generate_deopt_blob() { } // Load array of frame pcs into ECX - __ movl(rcx,Address(rdi,Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes())); + __ movptr(rcx,Address(rdi,Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes())); - __ popl(rsi); // trash the old pc + __ pop(rsi); // trash the old pc // Load array of frame sizes into ESI - __ movl(rsi,Address(rdi,Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes())); + __ movptr(rsi,Address(rdi,Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes())); Address counter(rdi, Deoptimization::UnrollBlock::counter_temp_offset_in_bytes()); @@ -2491,7 +2545,7 @@ void SharedRuntime::generate_deopt_blob() { __ movl(counter, rbx); // Pick up the initial fp we should save - __ movl(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_fp_offset_in_bytes())); + __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_fp_offset_in_bytes())); // Now adjust the caller's stack to make up for the extra locals // but record the original sp so that we can save it in the skeletal interpreter @@ -2499,43 +2553,44 @@ void SharedRuntime::generate_deopt_blob() { // value and not the "real" sp value. Address sp_temp(rdi, Deoptimization::UnrollBlock::sender_sp_temp_offset_in_bytes()); - __ movl(sp_temp, rsp); - __ subl(rsp, Address(rdi, Deoptimization::UnrollBlock::caller_adjustment_offset_in_bytes())); + __ movptr(sp_temp, rsp); + __ movl2ptr(rbx, Address(rdi, Deoptimization::UnrollBlock::caller_adjustment_offset_in_bytes())); + __ subptr(rsp, rbx); // Push interpreter frames in a loop Label loop; __ bind(loop); - __ movl(rbx, Address(rsi, 0)); // Load frame size + __ movptr(rbx, Address(rsi, 0)); // Load frame size #ifdef CC_INTERP - __ subl(rbx, 4*wordSize); // we'll push pc and ebp by hand and + __ subptr(rbx, 4*wordSize); // we'll push pc and ebp by hand and #ifdef ASSERT - __ pushl(0xDEADDEAD); // Make a recognizable pattern - __ pushl(0xDEADDEAD); + __ push(0xDEADDEAD); // Make a recognizable pattern + __ push(0xDEADDEAD); #else /* ASSERT */ - __ subl(rsp, 2*wordSize); // skip the "static long no_param" + __ subptr(rsp, 2*wordSize); // skip the "static long no_param" #endif /* ASSERT */ #else /* CC_INTERP */ - __ subl(rbx, 2*wordSize); // we'll push pc and rbp, by hand + __ subptr(rbx, 2*wordSize); // we'll push pc and rbp, by hand #endif /* CC_INTERP */ - __ pushl(Address(rcx, 0)); // save return address + __ pushptr(Address(rcx, 0)); // save return address __ enter(); // save old & set new rbp, - __ subl(rsp, rbx); // Prolog! - __ movl(rbx, sp_temp); // sender's sp + __ subptr(rsp, rbx); // Prolog! + __ movptr(rbx, sp_temp); // sender's sp #ifdef CC_INTERP - __ movl(Address(rbp, + __ movptr(Address(rbp, -(sizeof(BytecodeInterpreter)) + in_bytes(byte_offset_of(BytecodeInterpreter, _sender_sp))), rbx); // Make it walkable #else /* CC_INTERP */ // This value is corrected by layout_activation_impl - __ movl(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD ); - __ movl(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), rbx); // Make it walkable + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD ); + __ movptr(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), rbx); // Make it walkable #endif /* CC_INTERP */ - __ movl(sp_temp, rsp); // pass to next frame - __ addl(rsi, 4); // Bump array pointer (sizes) - __ addl(rcx, 4); // Bump array pointer (pcs) - __ decrement(counter); // decrement counter + __ movptr(sp_temp, rsp); // pass to next frame + __ addptr(rsi, wordSize); // Bump array pointer (sizes) + __ addptr(rcx, wordSize); // Bump array pointer (pcs) + __ decrementl(counter); // decrement counter __ jcc(Assembler::notZero, loop); - __ pushl(Address(rcx, 0)); // save final return address + __ pushptr(Address(rcx, 0)); // save final return address // Re-push self-frame __ enter(); // save old & set new rbp, @@ -2543,11 +2598,11 @@ void SharedRuntime::generate_deopt_blob() { // Return address and rbp, are in place // We'll push additional args later. Just allocate a full sized // register save area - __ subl(rsp, (frame_size_in_words-additional_words - 2) * wordSize); + __ subptr(rsp, (frame_size_in_words-additional_words - 2) * wordSize); // Restore frame locals after moving the frame - __ movl(Address(rsp, RegisterSaver::raxOffset()*wordSize), rax); - __ movl(Address(rsp, RegisterSaver::rdxOffset()*wordSize), rdx); + __ movptr(Address(rsp, RegisterSaver::raxOffset()*wordSize), rax); + __ movptr(Address(rsp, RegisterSaver::rdxOffset()*wordSize), rdx); __ fstp_d(Address(rsp, RegisterSaver::fpResultOffset()*wordSize)); // Pop float stack and store in local if( UseSSE>=2 ) __ movdbl(Address(rsp, RegisterSaver::xmm0Offset()*wordSize), xmm0); if( UseSSE==1 ) __ movflt(Address(rsp, RegisterSaver::xmm0Offset()*wordSize), xmm0); @@ -2556,7 +2611,7 @@ void SharedRuntime::generate_deopt_blob() { __ pushl(unpack_kind); // get the unpack_kind value __ get_thread(rcx); - __ pushl(rcx); + __ push(rcx); // set last_Java_sp, last_Java_fp __ set_last_Java_frame(rcx, noreg, rbp, NULL); @@ -2569,14 +2624,14 @@ void SharedRuntime::generate_deopt_blob() { oop_maps->add_gc_map( __ pc()-start, new OopMap( frame_size_in_words, 0 )); // rax, contains the return result type - __ pushl(rax); + __ push(rax); __ get_thread(rcx); __ reset_last_Java_frame(rcx, false, false); // Collect return values - __ movl(rax,Address(rsp, (RegisterSaver::raxOffset() + additional_words + 1)*wordSize)); - __ movl(rdx,Address(rsp, (RegisterSaver::rdxOffset() + additional_words + 1)*wordSize)); + __ movptr(rax,Address(rsp, (RegisterSaver::raxOffset() + additional_words + 1)*wordSize)); + __ movptr(rdx,Address(rsp, (RegisterSaver::rdxOffset() + additional_words + 1)*wordSize)); // Clear floating point stack before returning to interpreter __ empty_FPU_stack(); @@ -2637,12 +2692,12 @@ void SharedRuntime::generate_uncommon_trap_blob() { address start = __ pc(); // Push self-frame. - __ subl(rsp, return_off*wordSize); // Epilog! + __ subptr(rsp, return_off*wordSize); // Epilog! // rbp, is an implicitly saved callee saved register (i.e. the calling // convention will save restore it in prolog/epilog) Other than that // there are no callee save registers no that adapter frames are gone. - __ movl(Address(rsp, rbp_off*wordSize),rbp); + __ movptr(Address(rsp, rbp_off*wordSize), rbp); // Clear the floating point exception stack __ empty_FPU_stack(); @@ -2654,7 +2709,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { // Call C code. Need thread but NOT official VM entry // crud. We cannot block on this call, no GC can happen. Call should // capture callee-saved registers as well as return values. - __ movl(Address(rsp, arg0_off*wordSize),rdx); + __ movptr(Address(rsp, arg0_off*wordSize), rdx); // argument already in ECX __ movl(Address(rsp, arg1_off*wordSize),rcx); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap))); @@ -2671,7 +2726,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { __ reset_last_Java_frame(rcx, false, false); // Load UnrollBlock into EDI - __ movl(rdi, rax); + __ movptr(rdi, rax); // Pop all the frames we must move/replace. // @@ -2681,10 +2736,11 @@ void SharedRuntime::generate_uncommon_trap_blob() { // 3: caller of deopting frame (could be compiled/interpreted). // Pop self-frame. We have no frame, and must rely only on EAX and ESP. - __ addl(rsp,(framesize-1)*wordSize); // Epilog! + __ addptr(rsp,(framesize-1)*wordSize); // Epilog! // Pop deoptimized frame - __ addl(rsp,Address(rdi,Deoptimization::UnrollBlock::size_of_deoptimized_frame_offset_in_bytes())); + __ movl2ptr(rcx, Address(rdi,Deoptimization::UnrollBlock::size_of_deoptimized_frame_offset_in_bytes())); + __ addptr(rsp, rcx); // sp should be pointing at the return address to the caller (3) @@ -2698,10 +2754,10 @@ void SharedRuntime::generate_uncommon_trap_blob() { // Load array of frame pcs into ECX __ movl(rcx,Address(rdi,Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes())); - __ popl(rsi); // trash the pc + __ pop(rsi); // trash the pc // Load array of frame sizes into ESI - __ movl(rsi,Address(rdi,Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes())); + __ movptr(rsi,Address(rdi,Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes())); Address counter(rdi, Deoptimization::UnrollBlock::counter_temp_offset_in_bytes()); @@ -2709,7 +2765,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { __ movl(counter, rbx); // Pick up the initial fp we should save - __ movl(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_fp_offset_in_bytes())); + __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_fp_offset_in_bytes())); // Now adjust the caller's stack to make up for the extra locals // but record the original sp so that we can save it in the skeletal interpreter @@ -2717,47 +2773,48 @@ void SharedRuntime::generate_uncommon_trap_blob() { // value and not the "real" sp value. Address sp_temp(rdi, Deoptimization::UnrollBlock::sender_sp_temp_offset_in_bytes()); - __ movl(sp_temp, rsp); - __ subl(rsp, Address(rdi, Deoptimization::UnrollBlock::caller_adjustment_offset_in_bytes())); + __ movptr(sp_temp, rsp); + __ movl(rbx, Address(rdi, Deoptimization::UnrollBlock::caller_adjustment_offset_in_bytes())); + __ subptr(rsp, rbx); // Push interpreter frames in a loop Label loop; __ bind(loop); - __ movl(rbx, Address(rsi, 0)); // Load frame size + __ movptr(rbx, Address(rsi, 0)); // Load frame size #ifdef CC_INTERP - __ subl(rbx, 4*wordSize); // we'll push pc and ebp by hand and + __ subptr(rbx, 4*wordSize); // we'll push pc and ebp by hand and #ifdef ASSERT - __ pushl(0xDEADDEAD); // Make a recognizable pattern - __ pushl(0xDEADDEAD); // (parm to RecursiveInterpreter...) + __ push(0xDEADDEAD); // Make a recognizable pattern + __ push(0xDEADDEAD); // (parm to RecursiveInterpreter...) #else /* ASSERT */ - __ subl(rsp, 2*wordSize); // skip the "static long no_param" + __ subptr(rsp, 2*wordSize); // skip the "static long no_param" #endif /* ASSERT */ #else /* CC_INTERP */ - __ subl(rbx, 2*wordSize); // we'll push pc and rbp, by hand + __ subptr(rbx, 2*wordSize); // we'll push pc and rbp, by hand #endif /* CC_INTERP */ - __ pushl(Address(rcx, 0)); // save return address + __ pushptr(Address(rcx, 0)); // save return address __ enter(); // save old & set new rbp, - __ subl(rsp, rbx); // Prolog! - __ movl(rbx, sp_temp); // sender's sp + __ subptr(rsp, rbx); // Prolog! + __ movptr(rbx, sp_temp); // sender's sp #ifdef CC_INTERP - __ movl(Address(rbp, + __ movptr(Address(rbp, -(sizeof(BytecodeInterpreter)) + in_bytes(byte_offset_of(BytecodeInterpreter, _sender_sp))), rbx); // Make it walkable #else /* CC_INTERP */ // This value is corrected by layout_activation_impl - __ movl(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD ); - __ movl(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), rbx); // Make it walkable + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD ); + __ movptr(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), rbx); // Make it walkable #endif /* CC_INTERP */ - __ movl(sp_temp, rsp); // pass to next frame - __ addl(rsi, 4); // Bump array pointer (sizes) - __ addl(rcx, 4); // Bump array pointer (pcs) - __ decrement(counter); // decrement counter + __ movptr(sp_temp, rsp); // pass to next frame + __ addptr(rsi, wordSize); // Bump array pointer (sizes) + __ addptr(rcx, wordSize); // Bump array pointer (pcs) + __ decrementl(counter); // decrement counter __ jcc(Assembler::notZero, loop); - __ pushl(Address(rcx, 0)); // save final return address + __ pushptr(Address(rcx, 0)); // save final return address // Re-push self-frame __ enter(); // save old & set new rbp, - __ subl(rsp, (framesize-2) * wordSize); // Prolog! + __ subptr(rsp, (framesize-2) * wordSize); // Prolog! // set last_Java_sp, last_Java_fp @@ -2767,7 +2824,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { // Call C code. Need thread but NOT official VM entry // crud. We cannot block on this call, no GC can happen. Call should // restore return values to their stack-slots with the new SP. - __ movl(Address(rsp,arg0_off*wordSize),rdi); + __ movptr(Address(rsp,arg0_off*wordSize),rdi); __ movl(Address(rsp,arg1_off*wordSize), Deoptimization::Unpack_uncommon_trap); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames))); // Set an oopmap for the call site @@ -2824,7 +2881,7 @@ static SafepointBlob* generate_handler_blob(address call_ptr, bool cause_return) // Otherwise we push space for a return address that the safepoint // handler will install later to make the stack walking sensible. if( !cause_return ) - __ pushl(rbx); // Make room for return address (or push it again) + __ push(rbx); // Make room for return address (or push it again) map = RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words, false); @@ -2834,13 +2891,13 @@ static SafepointBlob* generate_handler_blob(address call_ptr, bool cause_return) // Push thread argument and setup last_Java_sp __ get_thread(java_thread); - __ pushl(java_thread); + __ push(java_thread); __ set_last_Java_frame(java_thread, noreg, noreg, NULL); // if this was not a poll_return then we need to correct the return address now. if( !cause_return ) { - __ movl(rax, Address(java_thread, JavaThread::saved_exception_pc_offset())); - __ movl(Address(rbp, wordSize), rax); + __ movptr(rax, Address(java_thread, JavaThread::saved_exception_pc_offset())); + __ movptr(Address(rbp, wordSize), rax); } // do the call @@ -2854,7 +2911,7 @@ static SafepointBlob* generate_handler_blob(address call_ptr, bool cause_return) oop_maps->add_gc_map( __ pc() - start, map); // Discard arg - __ popl(rcx); + __ pop(rcx); Label noException; @@ -2862,7 +2919,7 @@ static SafepointBlob* generate_handler_blob(address call_ptr, bool cause_return) __ get_thread(java_thread); __ reset_last_Java_frame(java_thread, false, false); - __ cmpl(Address(java_thread, Thread::pending_exception_offset()), NULL_WORD); + __ cmpptr(Address(java_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::equal, noException); // Exception pending @@ -2919,7 +2976,7 @@ static RuntimeStub* generate_resolve_blob(address destination, const char* name) const Register thread = rdi; __ get_thread(rdi); - __ pushl(thread); + __ push(thread); __ set_last_Java_frame(thread, noreg, rbp, NULL); __ call(RuntimeAddress(destination)); @@ -2933,20 +2990,20 @@ static RuntimeStub* generate_resolve_blob(address destination, const char* name) // rax, contains the address we are going to jump to assuming no exception got installed - __ addl(rsp, wordSize); + __ addptr(rsp, wordSize); // clear last_Java_sp __ reset_last_Java_frame(thread, true, false); // check for pending exceptions Label pending; - __ cmpl(Address(thread, Thread::pending_exception_offset()), NULL_WORD); + __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::notEqual, pending); // get the returned methodOop - __ movl(rbx, Address(thread, JavaThread::vm_result_offset())); - __ movl(Address(rsp, RegisterSaver::rbx_offset() * wordSize), rbx); + __ movptr(rbx, Address(thread, JavaThread::vm_result_offset())); + __ movptr(Address(rsp, RegisterSaver::rbx_offset() * wordSize), rbx); - __ movl(Address(rsp, RegisterSaver::rax_offset() * wordSize), rax); + __ movptr(Address(rsp, RegisterSaver::rax_offset() * wordSize), rax); RegisterSaver::restore_live_registers(masm); @@ -2963,8 +3020,8 @@ static RuntimeStub* generate_resolve_blob(address destination, const char* name) // exception pending => remove activation and forward to exception handler __ get_thread(thread); - __ movl(Address(thread, JavaThread::vm_result_offset()), NULL_WORD); - __ movl(rax, Address(thread, Thread::pending_exception_offset())); + __ movptr(Address(thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD); + __ movptr(rax, Address(thread, Thread::pending_exception_offset())); __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); // ------------- diff --git a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp index b2d4a6513ac..26e7e148968 100644 --- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp @@ -120,6 +120,7 @@ class RegisterSaver { // values on its own static int rax_offset_in_bytes(void) { return BytesPerInt * rax_off; } + static int rdx_offset_in_bytes(void) { return BytesPerInt * rdx_off; } static int rbx_offset_in_bytes(void) { return BytesPerInt * rbx_off; } static int xmm0_offset_in_bytes(void) { return BytesPerInt * xmm0_off; } static int return_offset_in_bytes(void) { return BytesPerInt * return_off; } @@ -152,7 +153,7 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_ __ push_CPU_state(); // Push a multiple of 16 bytes if (frame::arg_reg_save_area_bytes != 0) { // Allocate argument register save area - __ subq(rsp, frame::arg_reg_save_area_bytes); + __ subptr(rsp, frame::arg_reg_save_area_bytes); } // Set an oopmap for the call site. This oopmap will map all @@ -266,12 +267,12 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_ void RegisterSaver::restore_live_registers(MacroAssembler* masm) { if (frame::arg_reg_save_area_bytes != 0) { // Pop arg register save area - __ addq(rsp, frame::arg_reg_save_area_bytes); + __ addptr(rsp, frame::arg_reg_save_area_bytes); } // Recover CPU state __ pop_CPU_state(); // Get the rbp described implicitly by the calling convention (no oopMap) - __ popq(rbp); + __ pop(rbp); } void RegisterSaver::restore_result_registers(MacroAssembler* masm) { @@ -285,9 +286,11 @@ void RegisterSaver::restore_result_registers(MacroAssembler* masm) { // Restore fp result register __ movdbl(xmm0, Address(rsp, xmm0_offset_in_bytes())); // Restore integer result register - __ movq(rax, Address(rsp, rax_offset_in_bytes())); + __ movptr(rax, Address(rsp, rax_offset_in_bytes())); + __ movptr(rdx, Address(rsp, rdx_offset_in_bytes())); + // Pop all of the register save are off the stack except the return address - __ addq(rsp, return_offset_in_bytes()); + __ addptr(rsp, return_offset_in_bytes()); } // The java_calling_convention describes stack locations as ideal slots on @@ -407,18 +410,18 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, static void patch_callers_callsite(MacroAssembler *masm) { Label L; __ verify_oop(rbx); - __ cmpq(Address(rbx, in_bytes(methodOopDesc::code_offset())), (int)NULL_WORD); + __ cmpptr(Address(rbx, in_bytes(methodOopDesc::code_offset())), (int32_t)NULL_WORD); __ jcc(Assembler::equal, L); // Save the current stack pointer - __ movq(r13, rsp); + __ mov(r13, rsp); // Schedule the branch target address early. // Call into the VM to patch the caller, then jump to compiled callee // rax isn't live so capture return address while we easily can - __ movq(rax, Address(rsp, 0)); + __ movptr(rax, Address(rsp, 0)); // align stack so push_CPU_state doesn't fault - __ andq(rsp, -(StackAlignmentInBytes)); + __ andptr(rsp, -(StackAlignmentInBytes)); __ push_CPU_state(); @@ -430,20 +433,20 @@ static void patch_callers_callsite(MacroAssembler *masm) { // Allocate argument register save area if (frame::arg_reg_save_area_bytes != 0) { - __ subq(rsp, frame::arg_reg_save_area_bytes); + __ subptr(rsp, frame::arg_reg_save_area_bytes); } - __ movq(c_rarg0, rbx); - __ movq(c_rarg1, rax); + __ mov(c_rarg0, rbx); + __ mov(c_rarg1, rax); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite))); // De-allocate argument register save area if (frame::arg_reg_save_area_bytes != 0) { - __ addq(rsp, frame::arg_reg_save_area_bytes); + __ addptr(rsp, frame::arg_reg_save_area_bytes); } __ pop_CPU_state(); // restore sp - __ movq(rsp, r13); + __ mov(rsp, r13); __ bind(L); } @@ -452,13 +455,13 @@ static void tag_stack(MacroAssembler *masm, const BasicType sig, int st_off) { if (TaggedStackInterpreter) { int tag_offset = st_off + Interpreter::expr_tag_offset_in_bytes(0); if (sig == T_OBJECT || sig == T_ARRAY) { - __ mov64(Address(rsp, tag_offset), frame::TagReference); + __ movptr(Address(rsp, tag_offset), (int32_t) frame::TagReference); } else if (sig == T_LONG || sig == T_DOUBLE) { int next_tag_offset = st_off + Interpreter::expr_tag_offset_in_bytes(1); - __ mov64(Address(rsp, next_tag_offset), frame::TagValue); - __ mov64(Address(rsp, tag_offset), frame::TagValue); + __ movptr(Address(rsp, next_tag_offset), (int32_t) frame::TagValue); + __ movptr(Address(rsp, tag_offset), (int32_t) frame::TagValue); } else { - __ mov64(Address(rsp, tag_offset), frame::TagValue); + __ movptr(Address(rsp, tag_offset), (int32_t) frame::TagValue); } } } @@ -490,15 +493,15 @@ static void gen_c2i_adapter(MacroAssembler *masm, extraspace = round_to(extraspace, 2*wordSize); // Get return address - __ popq(rax); + __ pop(rax); // set senderSP value - __ movq(r13, rsp); + __ mov(r13, rsp); - __ subq(rsp, extraspace); + __ subptr(rsp, extraspace); // Store the return address in the expected location - __ movq(Address(rsp, 0), rax); + __ movptr(Address(rsp, 0), rax); // Now write the args into the outgoing interpreter space for (int i = 0; i < total_args_passed; i++) { @@ -537,7 +540,7 @@ static void gen_c2i_adapter(MacroAssembler *masm, if (!r_2->is_valid()) { // sign extend?? __ movl(rax, Address(rsp, ld_off)); - __ movq(Address(rsp, st_off), rax); + __ movptr(Address(rsp, st_off), rax); tag_stack(masm, sig_bt[i], st_off); } else { @@ -553,7 +556,7 @@ static void gen_c2i_adapter(MacroAssembler *masm, #ifdef ASSERT // Overwrite the unused slot with known junk __ mov64(rax, CONST64(0xdeadffffdeadaaaa)); - __ movq(Address(rsp, st_off), rax); + __ movptr(Address(rsp, st_off), rax); #endif /* ASSERT */ tag_stack(masm, sig_bt[i], next_off); } else { @@ -576,12 +579,12 @@ static void gen_c2i_adapter(MacroAssembler *masm, #ifdef ASSERT // Overwrite the unused slot with known junk __ mov64(rax, CONST64(0xdeadffffdeadaaab)); - __ movq(Address(rsp, st_off), rax); + __ movptr(Address(rsp, st_off), rax); #endif /* ASSERT */ __ movq(Address(rsp, next_off), r); tag_stack(masm, sig_bt[i], next_off); } else { - __ movq(Address(rsp, st_off), r); + __ movptr(Address(rsp, st_off), r); tag_stack(masm, sig_bt[i], st_off); } } @@ -595,7 +598,7 @@ static void gen_c2i_adapter(MacroAssembler *masm, #ifdef ASSERT // Overwrite the unused slot with known junk __ mov64(rax, CONST64(0xdeadffffdeadaaac)); - __ movq(Address(rsp, st_off), rax); + __ movptr(Address(rsp, st_off), rax); #endif /* ASSERT */ __ movdbl(Address(rsp, next_off), r_1->as_XMMRegister()); tag_stack(masm, sig_bt[i], next_off); @@ -604,7 +607,7 @@ static void gen_c2i_adapter(MacroAssembler *masm, } // Schedule the branch target address early. - __ movq(rcx, Address(rbx, in_bytes(methodOopDesc::interpreter_entry_offset()))); + __ movptr(rcx, Address(rbx, in_bytes(methodOopDesc::interpreter_entry_offset()))); __ jmp(rcx); } @@ -631,7 +634,7 @@ static void gen_i2c_adapter(MacroAssembler *masm, // save code can segv when fxsave instructions find improperly // aligned stack pointer. - __ movq(rax, Address(rsp, 0)); + __ movptr(rax, Address(rsp, 0)); // Cut-out for having no stack args. Since up to 2 int/oop args are passed // in registers, we will occasionally have no stack args. @@ -645,20 +648,20 @@ static void gen_i2c_adapter(MacroAssembler *masm, comp_words_on_stack = round_to(comp_args_on_stack*VMRegImpl::stack_slot_size, wordSize)>>LogBytesPerWord; // Round up to miminum stack alignment, in wordSize comp_words_on_stack = round_to(comp_words_on_stack, 2); - __ subq(rsp, comp_words_on_stack * wordSize); + __ subptr(rsp, comp_words_on_stack * wordSize); } // Ensure compiled code always sees stack at proper alignment - __ andq(rsp, -16); + __ andptr(rsp, -16); // push the return address and misalign the stack that youngest frame always sees // as far as the placement of the call instruction - __ pushq(rax); + __ push(rax); // Will jump to the compiled code just as if compiled code was doing it. // Pre-load the register-jump target early, to schedule it better. - __ movq(r11, Address(rbx, in_bytes(methodOopDesc::from_compiled_offset()))); + __ movptr(r11, Address(rbx, in_bytes(methodOopDesc::from_compiled_offset()))); // Now generate the shuffle code. Pick up all register args and move the // rest through the floating point stack top. @@ -697,7 +700,7 @@ static void gen_i2c_adapter(MacroAssembler *masm, if (!r_2->is_valid()) { // sign extend??? __ movl(rax, Address(r13, ld_off)); - __ movq(Address(rsp, st_off), rax); + __ movptr(Address(rsp, st_off), rax); } else { // // We are using two optoregs. This can be either T_OBJECT, T_ADDRESS, T_LONG, or T_DOUBLE @@ -751,12 +754,12 @@ static void gen_i2c_adapter(MacroAssembler *masm, // is possible. So we stash the desired callee in the thread // and the vm will find there should this case occur. - __ movq(Address(r15_thread, JavaThread::callee_target_offset()), rbx); + __ movptr(Address(r15_thread, JavaThread::callee_target_offset()), rbx); // put methodOop where a c2i would expect should we end up there // only needed becaus eof c2 resolve stubs return methodOop as a result in // rax - __ movq(rax, rbx); + __ mov(rax, rbx); __ jmp(r11); } @@ -792,8 +795,8 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm __ load_klass(temp, receiver); __ verify_oop(temp); - __ cmpq(temp, Address(holder, compiledICHolderOopDesc::holder_klass_offset())); - __ movq(rbx, Address(holder, compiledICHolderOopDesc::holder_method_offset())); + __ cmpptr(temp, Address(holder, compiledICHolderOopDesc::holder_klass_offset())); + __ movptr(rbx, Address(holder, compiledICHolderOopDesc::holder_method_offset())); __ jcc(Assembler::equal, ok); __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); @@ -801,7 +804,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm // Method might have been compiled since the call site was patched to // interpreted if that is the case treat it as a miss so we can get // the call site corrected. - __ cmpq(Address(rbx, in_bytes(methodOopDesc::code_offset())), (int)NULL_WORD); + __ cmpptr(Address(rbx, in_bytes(methodOopDesc::code_offset())), (int32_t)NULL_WORD); __ jcc(Assembler::equal, skip_fixup); __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); } @@ -980,10 +983,10 @@ static void object_move(MacroAssembler* masm, *receiver_offset = (offset_in_older_frame + framesize_in_slots) * VMRegImpl::stack_slot_size; } - __ cmpq(Address(rbp, reg2offset_in(src.first())), (int)NULL_WORD); - __ leaq(rHandle, Address(rbp, reg2offset_in(src.first()))); + __ cmpptr(Address(rbp, reg2offset_in(src.first())), (int32_t)NULL_WORD); + __ lea(rHandle, Address(rbp, reg2offset_in(src.first()))); // conditionally move a NULL - __ cmovq(Assembler::equal, rHandle, Address(rbp, reg2offset_in(src.first()))); + __ cmovptr(Assembler::equal, rHandle, Address(rbp, reg2offset_in(src.first()))); } else { // Oop is in an a register we must store it to the space we reserve @@ -1011,20 +1014,20 @@ static void object_move(MacroAssembler* masm, map->set_oop(VMRegImpl::stack2reg(oop_slot)); // Store oop in handle area, may be NULL - __ movq(Address(rsp, offset), rOop); + __ movptr(Address(rsp, offset), rOop); if (is_receiver) { *receiver_offset = offset; } - __ cmpq(rOop, (int)NULL); - __ leaq(rHandle, Address(rsp, offset)); + __ cmpptr(rOop, (int32_t)NULL_WORD); + __ lea(rHandle, Address(rsp, offset)); // conditionally move a NULL from the handle area where it was just stored - __ cmovq(Assembler::equal, rHandle, Address(rsp, offset)); + __ cmovptr(Assembler::equal, rHandle, Address(rsp, offset)); } // If arg is on the stack then place it otherwise it is already in correct reg. if (dst.first()->is_stack()) { - __ movq(Address(rsp, reg2offset_out(dst.first())), rHandle); + __ movptr(Address(rsp, reg2offset_out(dst.first())), rHandle); } } @@ -1039,7 +1042,7 @@ static void float_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { if (src.first()->is_stack()) { if (dst.first()->is_stack()) { __ movl(rax, Address(rbp, reg2offset_in(src.first()))); - __ movq(Address(rsp, reg2offset_out(dst.first())), rax); + __ movptr(Address(rsp, reg2offset_out(dst.first())), rax); } else { // stack to reg assert(dst.first()->is_XMMRegister(), "only expect xmm registers as parameters"); @@ -1068,7 +1071,7 @@ static void long_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { if (src.is_single_phys_reg() ) { if (dst.is_single_phys_reg()) { if (dst.first() != src.first()) { - __ movq(dst.first()->as_Register(), src.first()->as_Register()); + __ mov(dst.first()->as_Register(), src.first()->as_Register()); } } else { assert(dst.is_single_reg(), "not a stack pair"); @@ -1124,7 +1127,7 @@ void SharedRuntime::save_native_result(MacroAssembler *masm, BasicType ret_type, break; case T_VOID: break; default: { - __ movq(Address(rbp, -wordSize), rax); + __ movptr(Address(rbp, -wordSize), rax); } } } @@ -1141,7 +1144,7 @@ void SharedRuntime::restore_native_result(MacroAssembler *masm, BasicType ret_ty break; case T_VOID: break; default: { - __ movq(rax, Address(rbp, -wordSize)); + __ movptr(rax, Address(rbp, -wordSize)); } } } @@ -1149,9 +1152,9 @@ void SharedRuntime::restore_native_result(MacroAssembler *masm, BasicType ret_ty static void save_args(MacroAssembler *masm, int arg_count, int first_arg, VMRegPair *args) { for ( int i = first_arg ; i < arg_count ; i++ ) { if (args[i].first()->is_Register()) { - __ pushq(args[i].first()->as_Register()); + __ push(args[i].first()->as_Register()); } else if (args[i].first()->is_XMMRegister()) { - __ subq(rsp, 2*wordSize); + __ subptr(rsp, 2*wordSize); __ movdbl(Address(rsp, 0), args[i].first()->as_XMMRegister()); } } @@ -1160,10 +1163,10 @@ static void save_args(MacroAssembler *masm, int arg_count, int first_arg, VMRegP static void restore_args(MacroAssembler *masm, int arg_count, int first_arg, VMRegPair *args) { for ( int i = arg_count - 1 ; i >= first_arg ; i-- ) { if (args[i].first()->is_Register()) { - __ popq(args[i].first()->as_Register()); + __ pop(args[i].first()->as_Register()); } else if (args[i].first()->is_XMMRegister()) { __ movdbl(args[i].first()->as_XMMRegister(), Address(rsp, 0)); - __ addq(rsp, 2*wordSize); + __ addptr(rsp, 2*wordSize); } } } @@ -1303,16 +1306,16 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, Label exception_pending; __ verify_oop(receiver); - __ pushq(tmp); // spill (any other registers free here???) + __ push(tmp); // spill (any other registers free here???) __ load_klass(tmp, receiver); __ cmpq(ic_reg, tmp); __ jcc(Assembler::equal, ok); - __ popq(tmp); + __ pop(tmp); __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); __ bind(ok); - __ popq(tmp); + __ pop(tmp); // Verified entry point must be aligned __ align(8); @@ -1335,7 +1338,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // Generate a new frame for the wrapper. __ enter(); // -2 because return address is already present and so is saved rbp - __ subq(rsp, stack_size - 2*wordSize); + __ subptr(rsp, stack_size - 2*wordSize); // Frame is now completed as far as size and linkage. @@ -1344,9 +1347,9 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, #ifdef ASSERT { Label L; - __ movq(rax, rsp); - __ andq(rax, -16); // must be 16 byte boundry (see amd64 ABI) - __ cmpq(rax, rsp); + __ mov(rax, rsp); + __ andptr(rax, -16); // must be 16 byte boundry (see amd64 ABI) + __ cmpptr(rax, rsp); __ jcc(Assembler::equal, L); __ stop("improperly aligned stack"); __ bind(L); @@ -1467,13 +1470,13 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, __ movoop(oop_handle_reg, JNIHandles::make_local(Klass::cast(method->method_holder())->java_mirror())); // Now handlize the static class mirror it's known not-null. - __ movq(Address(rsp, klass_offset), oop_handle_reg); + __ movptr(Address(rsp, klass_offset), oop_handle_reg); map->set_oop(VMRegImpl::stack2reg(klass_slot_offset)); // Now get the handle - __ leaq(oop_handle_reg, Address(rsp, klass_offset)); + __ lea(oop_handle_reg, Address(rsp, klass_offset)); // store the klass handle as second argument - __ movq(c_rarg1, oop_handle_reg); + __ movptr(c_rarg1, oop_handle_reg); // and protect the arg if we must spill c_arg--; } @@ -1521,14 +1524,14 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, const int mark_word_offset = BasicLock::displaced_header_offset_in_bytes(); // Get the handle (the 2nd argument) - __ movq(oop_handle_reg, c_rarg1); + __ mov(oop_handle_reg, c_rarg1); // Get address of the box - __ leaq(lock_reg, Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size)); + __ lea(lock_reg, Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size)); // Load the oop from the handle - __ movq(obj_reg, Address(oop_handle_reg, 0)); + __ movptr(obj_reg, Address(oop_handle_reg, 0)); if (UseBiasedLocking) { __ biased_locking_enter(lock_reg, obj_reg, swap_reg, rscratch1, false, lock_done, &slow_path_lock); @@ -1538,17 +1541,17 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, __ movl(swap_reg, 1); // Load (object->mark() | 1) into swap_reg %rax - __ orq(swap_reg, Address(obj_reg, 0)); + __ orptr(swap_reg, Address(obj_reg, 0)); // Save (object->mark() | 1) into BasicLock's displaced header - __ movq(Address(lock_reg, mark_word_offset), swap_reg); + __ movptr(Address(lock_reg, mark_word_offset), swap_reg); if (os::is_MP()) { __ lock(); } // src -> dest iff dest == rax else rax <- dest - __ cmpxchgq(lock_reg, Address(obj_reg, 0)); + __ cmpxchgptr(lock_reg, Address(obj_reg, 0)); __ jcc(Assembler::equal, lock_done); // Hmm should this move to the slow path code area??? @@ -1562,11 +1565,11 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // least significant 2 bits clear. // NOTE: the oopMark is in swap_reg %rax as the result of cmpxchg - __ subq(swap_reg, rsp); - __ andq(swap_reg, 3 - os::vm_page_size()); + __ subptr(swap_reg, rsp); + __ andptr(swap_reg, 3 - os::vm_page_size()); // Save the test result, for recursive case, the result is zero - __ movq(Address(lock_reg, mark_word_offset), swap_reg); + __ movptr(Address(lock_reg, mark_word_offset), swap_reg); __ jcc(Assembler::notEqual, slow_path_lock); // Slow path will re-enter here @@ -1580,21 +1583,21 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // get JNIEnv* which is first argument to native - __ leaq(c_rarg0, Address(r15_thread, in_bytes(JavaThread::jni_environment_offset()))); + __ lea(c_rarg0, Address(r15_thread, in_bytes(JavaThread::jni_environment_offset()))); // Now set thread in native - __ mov64(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_native); + __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_native); __ call(RuntimeAddress(method->native_function())); // Either restore the MXCSR register after returning from the JNI Call // or verify that it wasn't changed. if (RestoreMXCSROnJNICalls) { - __ ldmxcsr(ExternalAddress(StubRoutines::amd64::mxcsr_std())); + __ ldmxcsr(ExternalAddress(StubRoutines::x86::mxcsr_std())); } else if (CheckJNICalls ) { - __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::amd64::verify_mxcsr_entry()))); + __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::verify_mxcsr_entry()))); } @@ -1624,7 +1627,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // VM thread changes sync state to synchronizing and suspends threads for GC. // Thread A is resumed to finish this native method, but doesn't block here since it // didn't see any synchronization is progress, and escapes. - __ mov64(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_native_trans); + __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_native_trans); if(os::is_MP()) { if (UseMembar) { @@ -1662,12 +1665,12 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // by hand. // save_native_result(masm, ret_type, stack_slots); - __ movq(c_rarg0, r15_thread); - __ movq(r12, rsp); // remember sp - __ subq(rsp, frame::arg_reg_save_area_bytes); // windows - __ andq(rsp, -16); // align stack as required by ABI + __ mov(c_rarg0, r15_thread); + __ mov(r12, rsp); // remember sp + __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows + __ andptr(rsp, -16); // align stack as required by ABI __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans))); - __ movq(rsp, r12); // restore sp + __ mov(rsp, r12); // restore sp __ reinit_heapbase(); // Restore any method result value restore_native_result(masm, ret_type, stack_slots); @@ -1691,7 +1694,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, if (method->is_synchronized()) { // Get locked oop from the handle we passed to jni - __ movq(obj_reg, Address(oop_handle_reg, 0)); + __ movptr(obj_reg, Address(oop_handle_reg, 0)); Label done; @@ -1701,7 +1704,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // Simple recursive lock? - __ cmpq(Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size), (int)NULL_WORD); + __ cmpptr(Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size), (int32_t)NULL_WORD); __ jcc(Assembler::equal, done); // Must save rax if if it is live now because cmpxchg must use it @@ -1711,15 +1714,15 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // get address of the stack lock - __ leaq(rax, Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size)); + __ lea(rax, Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size)); // get old displaced header - __ movq(old_hdr, Address(rax, 0)); + __ movptr(old_hdr, Address(rax, 0)); // Atomic swap old header if oop still contains the stack lock if (os::is_MP()) { __ lock(); } - __ cmpxchgq(old_hdr, Address(obj_reg, 0)); + __ cmpxchgptr(old_hdr, Address(obj_reg, 0)); __ jcc(Assembler::notEqual, slow_path_unlock); // slow path re-enters here @@ -1746,23 +1749,23 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // Unpack oop result if (ret_type == T_OBJECT || ret_type == T_ARRAY) { Label L; - __ testq(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, L); - __ movq(rax, Address(rax, 0)); + __ movptr(rax, Address(rax, 0)); __ bind(L); __ verify_oop(rax); } // reset handle block - __ movq(rcx, Address(r15_thread, JavaThread::active_handles_offset())); - __ movptr(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), (int)NULL_WORD); + __ movptr(rcx, Address(r15_thread, JavaThread::active_handles_offset())); + __ movptr(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); // pop our frame __ leave(); // Any exception pending? - __ cmpq(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), (int)NULL_WORD); + __ cmpptr(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD); __ jcc(Assembler::notEqual, exception_pending); // Return @@ -1790,9 +1793,9 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // protect the args we've loaded save_args(masm, total_c_args, c_arg, out_regs); - __ movq(c_rarg0, obj_reg); - __ movq(c_rarg1, lock_reg); - __ movq(c_rarg2, r15_thread); + __ mov(c_rarg0, obj_reg); + __ mov(c_rarg1, lock_reg); + __ mov(c_rarg2, r15_thread); // Not a leaf but we have last_Java_frame setup as we want __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_locking_C), 3); @@ -1800,7 +1803,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, #ifdef ASSERT { Label L; - __ cmpq(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), (int)NULL_WORD); + __ cmpptr(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD); __ jcc(Assembler::equal, L); __ stop("no pending exception allowed on exit from monitorenter"); __ bind(L); @@ -1820,32 +1823,32 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, save_native_result(masm, ret_type, stack_slots); } - __ leaq(c_rarg1, Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size)); + __ lea(c_rarg1, Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size)); - __ movq(c_rarg0, obj_reg); - __ movq(r12, rsp); // remember sp - __ subq(rsp, frame::arg_reg_save_area_bytes); // windows - __ andq(rsp, -16); // align stack as required by ABI + __ mov(c_rarg0, obj_reg); + __ mov(r12, rsp); // remember sp + __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows + __ andptr(rsp, -16); // align stack as required by ABI // Save pending exception around call to VM (which contains an EXCEPTION_MARK) // NOTE that obj_reg == rbx currently - __ movq(rbx, Address(r15_thread, in_bytes(Thread::pending_exception_offset()))); - __ movptr(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), (int)NULL_WORD); + __ movptr(rbx, Address(r15_thread, in_bytes(Thread::pending_exception_offset()))); + __ movptr(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C))); - __ movq(rsp, r12); // restore sp + __ mov(rsp, r12); // restore sp __ reinit_heapbase(); #ifdef ASSERT { Label L; - __ cmpq(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), (int)NULL_WORD); + __ cmpptr(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), (int)NULL_WORD); __ jcc(Assembler::equal, L); __ stop("no pending exception allowed on exit complete_monitor_unlocking_C"); __ bind(L); } #endif /* ASSERT */ - __ movq(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), rbx); + __ movptr(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), rbx); if (ret_type == T_FLOAT || ret_type == T_DOUBLE ) { restore_native_result(masm, ret_type, stack_slots); @@ -1860,11 +1863,11 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, __ bind(reguard); save_native_result(masm, ret_type, stack_slots); - __ movq(r12, rsp); // remember sp - __ subq(rsp, frame::arg_reg_save_area_bytes); // windows - __ andq(rsp, -16); // align stack as required by ABI + __ mov(r12, rsp); // remember sp + __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows + __ andptr(rsp, -16); // align stack as required by ABI __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages))); - __ movq(rsp, r12); // restore sp + __ mov(rsp, r12); // restore sp __ reinit_heapbase(); restore_native_result(masm, ret_type, stack_slots); // and continue @@ -2574,19 +2577,74 @@ void SharedRuntime::generate_deopt_blob() { // Normal deoptimization. Save exec mode for unpack_frames. __ movl(r14, Deoptimization::Unpack_deopt); // callee-saved __ jmp(cont); + + int reexecute_offset = __ pc() - start; + + // Reexecute case + // return address is the pc describes what bci to do re-execute at + + // No need to update map as each call to save_live_registers will produce identical oopmap + (void) RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words); + + __ movl(r14, Deoptimization::Unpack_reexecute); // callee-saved + __ jmp(cont); + int exception_offset = __ pc() - start; // Prolog for exception case - // Push throwing pc as return address - __ pushq(rdx); + // all registers are dead at this entry point, except for rax, and + // rdx which contain the exception oop and exception pc + // respectively. Set them in TLS and fall thru to the + // unpack_with_exception_in_tls entry point. + + __ movptr(Address(r15_thread, JavaThread::exception_pc_offset()), rdx); + __ movptr(Address(r15_thread, JavaThread::exception_oop_offset()), rax); + + int exception_in_tls_offset = __ pc() - start; + + // new implementation because exception oop is now passed in JavaThread + + // Prolog for exception case + // All registers must be preserved because they might be used by LinearScan + // Exceptiop oop and throwing PC are passed in JavaThread + // tos: stack at point of call to method that threw the exception (i.e. only + // args are on the stack, no return address) + + // make room on stack for the return address + // It will be patched later with the throwing pc. The correct value is not + // available now because loading it from memory would destroy registers. + __ push(0); // Save everything in sight. map = RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words); + // Now it is safe to overwrite any register + // Deopt during an exception. Save exec mode for unpack_frames. __ movl(r14, Deoptimization::Unpack_exception); // callee-saved + // load throwing pc from JavaThread and patch it as the return address + // of the current frame. Then clear the field in JavaThread + + __ movptr(rdx, Address(r15_thread, JavaThread::exception_pc_offset())); + __ movptr(Address(rbp, wordSize), rdx); + __ movptr(Address(r15_thread, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD); + +#ifdef ASSERT + // verify that there is really an exception oop in JavaThread + __ movptr(rax, Address(r15_thread, JavaThread::exception_oop_offset())); + __ verify_oop(rax); + + // verify that there is no pending exception + Label no_pending_exception; + __ movptr(rax, Address(r15_thread, Thread::pending_exception_offset())); + __ testptr(rax, rax); + __ jcc(Assembler::zero, no_pending_exception); + __ stop("must not have pending exception here"); + __ bind(no_pending_exception); +#endif + __ bind(cont); // Call C code. Need thread and this frame, but NOT official VM entry @@ -2599,15 +2657,15 @@ void SharedRuntime::generate_deopt_blob() { __ set_last_Java_frame(noreg, noreg, NULL); #ifdef ASSERT { Label L; - __ cmpq(Address(r15_thread, + __ cmpptr(Address(r15_thread, JavaThread::last_Java_fp_offset()), - 0); + (int32_t)0); __ jcc(Assembler::equal, L); __ stop("SharedRuntime::generate_deopt_blob: last_Java_fp not cleared"); __ bind(L); } #endif // ASSERT - __ movq(c_rarg0, r15_thread); + __ mov(c_rarg0, r15_thread); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::fetch_unroll_info))); // Need to have an oopmap that tells fetch_unroll_info where to @@ -2617,7 +2675,25 @@ void SharedRuntime::generate_deopt_blob() { __ reset_last_Java_frame(false, false); // Load UnrollBlock* into rdi - __ movq(rdi, rax); + __ mov(rdi, rax); + + Label noException; + __ cmpl(r12, Deoptimization::Unpack_exception); // Was exception pending? + __ jcc(Assembler::notEqual, noException); + __ movptr(rax, Address(r15_thread, JavaThread::exception_oop_offset())); + // QQQ this is useless it was NULL above + __ movptr(rdx, Address(r15_thread, JavaThread::exception_pc_offset())); + __ movptr(Address(r15_thread, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD); + __ movptr(Address(r15_thread, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD); + + __ verify_oop(rax); + + // Overwrite the result registers with the exception results. + __ movptr(Address(rsp, RegisterSaver::rax_offset_in_bytes()), rax); + // I think this is useless + __ movptr(Address(rsp, RegisterSaver::rdx_offset_in_bytes()), rdx); + + __ bind(noException); // Only register save data is on the stack. // Now restore the result registers. Everything else is either dead @@ -2640,7 +2716,7 @@ void SharedRuntime::generate_deopt_blob() { // Pop deoptimized frame __ movl(rcx, Address(rdi, Deoptimization::UnrollBlock::size_of_deoptimized_frame_offset_in_bytes())); - __ addq(rsp, rcx); + __ addptr(rsp, rcx); // rsp should be pointing at the return address to the caller (3) @@ -2651,19 +2727,19 @@ void SharedRuntime::generate_deopt_blob() { } // Load address of array of frame pcs into rcx - __ movq(rcx, Address(rdi, Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes())); + __ movptr(rcx, Address(rdi, Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes())); // Trash the old pc - __ addq(rsp, wordSize); + __ addptr(rsp, wordSize); // Load address of array of frame sizes into rsi - __ movq(rsi, Address(rdi, Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes())); + __ movptr(rsi, Address(rdi, Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes())); // Load counter into rdx __ movl(rdx, Address(rdi, Deoptimization::UnrollBlock::number_of_frames_offset_in_bytes())); // Pick up the initial fp we should save - __ movq(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_fp_offset_in_bytes())); + __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_fp_offset_in_bytes())); // Now adjust the caller's stack to make up for the extra locals // but record the original sp so that we can save it in the skeletal interpreter @@ -2672,41 +2748,56 @@ void SharedRuntime::generate_deopt_blob() { const Register sender_sp = r8; - __ movq(sender_sp, rsp); + __ mov(sender_sp, rsp); __ movl(rbx, Address(rdi, Deoptimization::UnrollBlock:: caller_adjustment_offset_in_bytes())); - __ subq(rsp, rbx); + __ subptr(rsp, rbx); // Push interpreter frames in a loop Label loop; __ bind(loop); - __ movq(rbx, Address(rsi, 0)); // Load frame size - __ subq(rbx, 2*wordSize); // We'll push pc and ebp by hand - __ pushq(Address(rcx, 0)); // Save return address + __ movptr(rbx, Address(rsi, 0)); // Load frame size +#ifdef CC_INTERP + __ subptr(rbx, 4*wordSize); // we'll push pc and ebp by hand and +#ifdef ASSERT + __ push(0xDEADDEAD); // Make a recognizable pattern + __ push(0xDEADDEAD); +#else /* ASSERT */ + __ subptr(rsp, 2*wordSize); // skip the "static long no_param" +#endif /* ASSERT */ +#else + __ subptr(rbx, 2*wordSize); // We'll push pc and ebp by hand +#endif // CC_INTERP + __ pushptr(Address(rcx, 0)); // Save return address __ enter(); // Save old & set new ebp - __ subq(rsp, rbx); // Prolog - __ movq(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), - sender_sp); // Make it walkable + __ subptr(rsp, rbx); // Prolog +#ifdef CC_INTERP + __ movptr(Address(rbp, + -(sizeof(BytecodeInterpreter)) + in_bytes(byte_offset_of(BytecodeInterpreter, _sender_sp))), + sender_sp); // Make it walkable +#else /* CC_INTERP */ // This value is corrected by layout_activation_impl - __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int)NULL_WORD ); - __ movq(sender_sp, rsp); // Pass sender_sp to next frame - __ addq(rsi, wordSize); // Bump array pointer (sizes) - __ addq(rcx, wordSize); // Bump array pointer (pcs) + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD ); + __ movptr(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), sender_sp); // Make it walkable +#endif /* CC_INTERP */ + __ mov(sender_sp, rsp); // Pass sender_sp to next frame + __ addptr(rsi, wordSize); // Bump array pointer (sizes) + __ addptr(rcx, wordSize); // Bump array pointer (pcs) __ decrementl(rdx); // Decrement counter __ jcc(Assembler::notZero, loop); - __ pushq(Address(rcx, 0)); // Save final return address + __ pushptr(Address(rcx, 0)); // Save final return address // Re-push self-frame __ enter(); // Save old & set new ebp // Allocate a full sized register save area. // Return address and rbp are in place, so we allocate two less words. - __ subq(rsp, (frame_size_in_words - 2) * wordSize); + __ subptr(rsp, (frame_size_in_words - 2) * wordSize); // Restore frame locals after moving the frame __ movdbl(Address(rsp, RegisterSaver::xmm0_offset_in_bytes()), xmm0); - __ movq(Address(rsp, RegisterSaver::rax_offset_in_bytes()), rax); + __ movptr(Address(rsp, RegisterSaver::rax_offset_in_bytes()), rax); // Call C code. Need thread but NOT official VM entry // crud. We cannot block on this call, no GC can happen. Call should @@ -2717,7 +2808,7 @@ void SharedRuntime::generate_deopt_blob() { // Use rbp because the frames look interpreted now __ set_last_Java_frame(noreg, rbp, NULL); - __ movq(c_rarg0, r15_thread); + __ mov(c_rarg0, r15_thread); __ movl(c_rarg1, r14); // second arg: exec_mode __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames))); @@ -2729,7 +2820,9 @@ void SharedRuntime::generate_deopt_blob() { // Collect return values __ movdbl(xmm0, Address(rsp, RegisterSaver::xmm0_offset_in_bytes())); - __ movq(rax, Address(rsp, RegisterSaver::rax_offset_in_bytes())); + __ movptr(rax, Address(rsp, RegisterSaver::rax_offset_in_bytes())); + // I think this is useless (throwing pc?) + __ movptr(rdx, Address(rsp, RegisterSaver::rdx_offset_in_bytes())); // Pop self-frame. __ leave(); // Epilog @@ -2740,7 +2833,8 @@ void SharedRuntime::generate_deopt_blob() { // Make sure all code is generated masm->flush(); - _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, 0, frame_size_in_words); + _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_in_words); + _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset); } #ifdef COMPILER2 @@ -2758,10 +2852,10 @@ void SharedRuntime::generate_uncommon_trap_blob() { // Push self-frame. We get here with a return address on the // stack, so rsp is 8-byte aligned until we allocate our frame. - __ subq(rsp, SimpleRuntimeFrame::return_off << LogBytesPerInt); // Epilog! + __ subptr(rsp, SimpleRuntimeFrame::return_off << LogBytesPerInt); // Epilog! // No callee saved registers. rbp is assumed implicitly saved - __ movq(Address(rsp, SimpleRuntimeFrame::rbp_off << LogBytesPerInt), rbp); + __ movptr(Address(rsp, SimpleRuntimeFrame::rbp_off << LogBytesPerInt), rbp); // compiler left unloaded_class_index in j_rarg0 move to where the // runtime expects it. @@ -2776,7 +2870,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { // // UnrollBlock* uncommon_trap(JavaThread* thread, jint unloaded_class_index); - __ movq(c_rarg0, r15_thread); + __ mov(c_rarg0, r15_thread); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap))); // Set an oopmap for the call site @@ -2790,7 +2884,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { __ reset_last_Java_frame(false, false); // Load UnrollBlock* into rdi - __ movq(rdi, rax); + __ mov(rdi, rax); // Pop all the frames we must move/replace. // @@ -2800,13 +2894,13 @@ void SharedRuntime::generate_uncommon_trap_blob() { // 3: caller of deopting frame (could be compiled/interpreted). // Pop self-frame. We have no frame, and must rely only on rax and rsp. - __ addq(rsp, (SimpleRuntimeFrame::framesize - 2) << LogBytesPerInt); // Epilog! + __ addptr(rsp, (SimpleRuntimeFrame::framesize - 2) << LogBytesPerInt); // Epilog! // Pop deoptimized frame (int) __ movl(rcx, Address(rdi, Deoptimization::UnrollBlock:: size_of_deoptimized_frame_offset_in_bytes())); - __ addq(rsp, rcx); + __ addptr(rsp, rcx); // rsp should be pointing at the return address to the caller (3) @@ -2817,17 +2911,17 @@ void SharedRuntime::generate_uncommon_trap_blob() { } // Load address of array of frame pcs into rcx (address*) - __ movq(rcx, - Address(rdi, - Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes())); + __ movptr(rcx, + Address(rdi, + Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes())); // Trash the return pc - __ addq(rsp, wordSize); + __ addptr(rsp, wordSize); // Load address of array of frame sizes into rsi (intptr_t*) - __ movq(rsi, Address(rdi, - Deoptimization::UnrollBlock:: - frame_sizes_offset_in_bytes())); + __ movptr(rsi, Address(rdi, + Deoptimization::UnrollBlock:: + frame_sizes_offset_in_bytes())); // Counter __ movl(rdx, Address(rdi, @@ -2835,9 +2929,9 @@ void SharedRuntime::generate_uncommon_trap_blob() { number_of_frames_offset_in_bytes())); // (int) // Pick up the initial fp we should save - __ movq(rbp, - Address(rdi, - Deoptimization::UnrollBlock::initial_fp_offset_in_bytes())); + __ movptr(rbp, + Address(rdi, + Deoptimization::UnrollBlock::initial_fp_offset_in_bytes())); // Now adjust the caller's stack to make up for the extra locals but // record the original sp so that we can save it in the skeletal @@ -2846,34 +2940,34 @@ void SharedRuntime::generate_uncommon_trap_blob() { const Register sender_sp = r8; - __ movq(sender_sp, rsp); + __ mov(sender_sp, rsp); __ movl(rbx, Address(rdi, Deoptimization::UnrollBlock:: caller_adjustment_offset_in_bytes())); // (int) - __ subq(rsp, rbx); + __ subptr(rsp, rbx); // Push interpreter frames in a loop Label loop; __ bind(loop); - __ movq(rbx, Address(rsi, 0)); // Load frame size - __ subq(rbx, 2 * wordSize); // We'll push pc and rbp by hand - __ pushq(Address(rcx, 0)); // Save return address - __ enter(); // Save old & set new rbp - __ subq(rsp, rbx); // Prolog - __ movq(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), - sender_sp); // Make it walkable + __ movptr(rbx, Address(rsi, 0)); // Load frame size + __ subptr(rbx, 2 * wordSize); // We'll push pc and rbp by hand + __ pushptr(Address(rcx, 0)); // Save return address + __ enter(); // Save old & set new rbp + __ subptr(rsp, rbx); // Prolog + __ movptr(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), + sender_sp); // Make it walkable // This value is corrected by layout_activation_impl - __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int)NULL_WORD ); - __ movq(sender_sp, rsp); // Pass sender_sp to next frame - __ addq(rsi, wordSize); // Bump array pointer (sizes) - __ addq(rcx, wordSize); // Bump array pointer (pcs) - __ decrementl(rdx); // Decrement counter + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD ); + __ mov(sender_sp, rsp); // Pass sender_sp to next frame + __ addptr(rsi, wordSize); // Bump array pointer (sizes) + __ addptr(rcx, wordSize); // Bump array pointer (pcs) + __ decrementl(rdx); // Decrement counter __ jcc(Assembler::notZero, loop); - __ pushq(Address(rcx, 0)); // Save final return address + __ pushptr(Address(rcx, 0)); // Save final return address // Re-push self-frame __ enter(); // Save old & set new rbp - __ subq(rsp, (SimpleRuntimeFrame::framesize - 4) << LogBytesPerInt); + __ subptr(rsp, (SimpleRuntimeFrame::framesize - 4) << LogBytesPerInt); // Prolog // Use rbp because the frames look interpreted now @@ -2886,7 +2980,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { // // BasicType unpack_frames(JavaThread* thread, int exec_mode); - __ movq(c_rarg0, r15_thread); + __ mov(c_rarg0, r15_thread); __ movl(c_rarg1, Deoptimization::Unpack_uncommon_trap); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames))); @@ -2933,7 +3027,7 @@ static SafepointBlob* generate_handler_blob(address call_ptr, bool cause_return) // Make room for return address (or push it again) if (!cause_return) { - __ pushq(rbx); + __ push(rbx); } // Save registers, fpu state, and flags @@ -2950,12 +3044,12 @@ static SafepointBlob* generate_handler_blob(address call_ptr, bool cause_return) if (!cause_return) { // overwrite the dummy value we pushed on entry - __ movq(c_rarg0, Address(r15_thread, JavaThread::saved_exception_pc_offset())); - __ movq(Address(rbp, wordSize), c_rarg0); + __ movptr(c_rarg0, Address(r15_thread, JavaThread::saved_exception_pc_offset())); + __ movptr(Address(rbp, wordSize), c_rarg0); } // Do the call - __ movq(c_rarg0, r15_thread); + __ mov(c_rarg0, r15_thread); __ call(RuntimeAddress(call_ptr)); // Set an oopmap for the call site. This oopmap will map all @@ -2969,7 +3063,7 @@ static SafepointBlob* generate_handler_blob(address call_ptr, bool cause_return) __ reset_last_Java_frame(false, false); - __ cmpq(Address(r15_thread, Thread::pending_exception_offset()), (int)NULL_WORD); + __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::equal, noException); // Exception pending @@ -3023,7 +3117,7 @@ static RuntimeStub* generate_resolve_blob(address destination, const char* name) __ set_last_Java_frame(noreg, noreg, NULL); - __ movq(c_rarg0, r15_thread); + __ mov(c_rarg0, r15_thread); __ call(RuntimeAddress(destination)); @@ -3040,14 +3134,14 @@ static RuntimeStub* generate_resolve_blob(address destination, const char* name) __ reset_last_Java_frame(false, false); // check for pending exceptions Label pending; - __ cmpq(Address(r15_thread, Thread::pending_exception_offset()), (int)NULL_WORD); + __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::notEqual, pending); // get the returned methodOop - __ movq(rbx, Address(r15_thread, JavaThread::vm_result_offset())); - __ movq(Address(rsp, RegisterSaver::rbx_offset_in_bytes()), rbx); + __ movptr(rbx, Address(r15_thread, JavaThread::vm_result_offset())); + __ movptr(Address(rsp, RegisterSaver::rbx_offset_in_bytes()), rbx); - __ movq(Address(rsp, RegisterSaver::rax_offset_in_bytes()), rax); + __ movptr(Address(rsp, RegisterSaver::rax_offset_in_bytes()), rax); RegisterSaver::restore_live_registers(masm); @@ -3065,7 +3159,7 @@ static RuntimeStub* generate_resolve_blob(address destination, const char* name) __ movptr(Address(r15_thread, JavaThread::vm_result_offset()), (int)NULL_WORD); - __ movq(rax, Address(r15_thread, Thread::pending_exception_offset())); + __ movptr(rax, Address(r15_thread, Thread::pending_exception_offset())); __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); // ------------- @@ -3154,8 +3248,8 @@ void OptoRuntime::generate_exception_blob() { address start = __ pc(); // Exception pc is 'return address' for stack walker - __ pushq(rdx); - __ subq(rsp, SimpleRuntimeFrame::return_off << LogBytesPerInt); // Prolog + __ push(rdx); + __ subptr(rsp, SimpleRuntimeFrame::return_off << LogBytesPerInt); // Prolog // Save callee-saved registers. See x86_64.ad. @@ -3163,14 +3257,14 @@ void OptoRuntime::generate_exception_blob() { // convention will save restore it in prolog/epilog) Other than that // there are no callee save registers now that adapter frames are gone. - __ movq(Address(rsp, SimpleRuntimeFrame::rbp_off << LogBytesPerInt), rbp); + __ movptr(Address(rsp, SimpleRuntimeFrame::rbp_off << LogBytesPerInt), rbp); // Store exception in Thread object. We cannot pass any arguments to the // handle_exception call, since we do not want to make any assumption // about the size of the frame where the exception happened in. // c_rarg0 is either rdi (Linux) or rcx (Windows). - __ movq(Address(r15_thread, JavaThread::exception_oop_offset()),rax); - __ movq(Address(r15_thread, JavaThread::exception_pc_offset()), rdx); + __ movptr(Address(r15_thread, JavaThread::exception_oop_offset()),rax); + __ movptr(Address(r15_thread, JavaThread::exception_pc_offset()), rdx); // This call does all the hard work. It checks if an exception handler // exists in the method. @@ -3181,7 +3275,7 @@ void OptoRuntime::generate_exception_blob() { // address OptoRuntime::handle_exception_C(JavaThread* thread) __ set_last_Java_frame(noreg, noreg, NULL); - __ movq(c_rarg0, r15_thread); + __ mov(c_rarg0, r15_thread); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, OptoRuntime::handle_exception_C))); // Set an oopmap for the call site. This oopmap will only be used if we @@ -3202,20 +3296,20 @@ void OptoRuntime::generate_exception_blob() { // convention will save restore it in prolog/epilog) Other than that // there are no callee save registers no that adapter frames are gone. - __ movq(rbp, Address(rsp, SimpleRuntimeFrame::rbp_off << LogBytesPerInt)); + __ movptr(rbp, Address(rsp, SimpleRuntimeFrame::rbp_off << LogBytesPerInt)); - __ addq(rsp, SimpleRuntimeFrame::return_off << LogBytesPerInt); // Epilog - __ popq(rdx); // No need for exception pc anymore + __ addptr(rsp, SimpleRuntimeFrame::return_off << LogBytesPerInt); // Epilog + __ pop(rdx); // No need for exception pc anymore // rax: exception handler // We have a handler in rax (could be deopt blob). - __ movq(r8, rax); + __ mov(r8, rax); // Get the exception oop - __ movq(rax, Address(r15_thread, JavaThread::exception_oop_offset())); + __ movptr(rax, Address(r15_thread, JavaThread::exception_oop_offset())); // Get the exception pc in case we are deoptimized - __ movq(rdx, Address(r15_thread, JavaThread::exception_pc_offset())); + __ movptr(rdx, Address(r15_thread, JavaThread::exception_pc_offset())); #ifdef ASSERT __ movptr(Address(r15_thread, JavaThread::exception_handler_pc_offset()), (int)NULL_WORD); __ movptr(Address(r15_thread, JavaThread::exception_pc_offset()), (int)NULL_WORD); diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp index 058c230282f..00b1fa7ea59 100644 --- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp @@ -30,6 +30,7 @@ // see the comment in stubRoutines.hpp #define __ _masm-> +#define a__ ((Assembler*)_masm)-> #ifdef PRODUCT #define BLOCK_COMMENT(str) /* nothing */ @@ -67,7 +68,7 @@ class StubGenerator: public StubCodeGenerator { #define inc_counter_np(counter) (0) #else void inc_counter_np_(int& counter) { - __ increment(ExternalAddress((address)&counter)); + __ incrementl(ExternalAddress((address)&counter)); } #define inc_counter_np(counter) \ BLOCK_COMMENT("inc_counter " #counter); \ @@ -137,16 +138,16 @@ class StubGenerator: public StubCodeGenerator { // stub code __ enter(); - __ movl(rcx, parameter_size); // parameter counter - __ shll(rcx, Interpreter::logStackElementSize()); // convert parameter count to bytes - __ addl(rcx, locals_count_in_bytes); // reserve space for register saves - __ subl(rsp, rcx); - __ andl(rsp, -(StackAlignmentInBytes)); // Align stack + __ movptr(rcx, parameter_size); // parameter counter + __ shlptr(rcx, Interpreter::logStackElementSize()); // convert parameter count to bytes + __ addptr(rcx, locals_count_in_bytes); // reserve space for register saves + __ subptr(rsp, rcx); + __ andptr(rsp, -(StackAlignmentInBytes)); // Align stack // save rdi, rsi, & rbx, according to C calling conventions - __ movl(saved_rdi, rdi); - __ movl(saved_rsi, rsi); - __ movl(saved_rbx, rbx); + __ movptr(saved_rdi, rdi); + __ movptr(saved_rsi, rsi); + __ movptr(saved_rbx, rbx); // save and initialize %mxcsr if (sse_save) { Label skip_ldmx; @@ -166,8 +167,8 @@ class StubGenerator: public StubCodeGenerator { #ifdef ASSERT // make sure we have no pending exceptions { Label L; - __ movl(rcx, thread); - __ cmpl(Address(rcx, Thread::pending_exception_offset()), NULL_WORD); + __ movptr(rcx, thread); + __ cmpptr(Address(rcx, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::equal, L); __ stop("StubRoutines::call_stub: entered with pending exception"); __ bind(L); @@ -189,20 +190,20 @@ class StubGenerator: public StubCodeGenerator { // source is rdx[rcx: N-1..0] // dest is rsp[rbx: 0..N-1] - __ movl(rdx, parameters); // parameter pointer - __ xorl(rbx, rbx); + __ movptr(rdx, parameters); // parameter pointer + __ xorptr(rbx, rbx); __ BIND(loop); if (TaggedStackInterpreter) { - __ movl(rax, Address(rdx, rcx, Interpreter::stackElementScale(), + __ movptr(rax, Address(rdx, rcx, Interpreter::stackElementScale(), -2*wordSize)); // get tag - __ movl(Address(rsp, rbx, Interpreter::stackElementScale(), + __ movptr(Address(rsp, rbx, Interpreter::stackElementScale(), Interpreter::expr_tag_offset_in_bytes(0)), rax); // store tag } // get parameter - __ movl(rax, Address(rdx, rcx, Interpreter::stackElementScale(), -wordSize)); - __ movl(Address(rsp, rbx, Interpreter::stackElementScale(), + __ movptr(rax, Address(rdx, rcx, Interpreter::stackElementScale(), -wordSize)); + __ movptr(Address(rsp, rbx, Interpreter::stackElementScale(), Interpreter::expr_offset_in_bytes(0)), rax); // store parameter __ increment(rbx); __ decrement(rcx); @@ -210,9 +211,9 @@ class StubGenerator: public StubCodeGenerator { // call Java function __ BIND(parameters_done); - __ movl(rbx, method); // get methodOop - __ movl(rax, entry_point); // get entry_point - __ movl(rsi, rsp); // set sender sp + __ movptr(rbx, method); // get methodOop + __ movptr(rax, entry_point); // get entry_point + __ mov(rsi, rsp); // set sender sp BLOCK_COMMENT("call Java function"); __ call(rax); @@ -225,7 +226,7 @@ class StubGenerator: public StubCodeGenerator { // store result depending on type // (everything that is not T_LONG, T_FLOAT or T_DOUBLE is treated as T_INT) - __ movl(rdi, result); + __ movptr(rdi, result); Label is_long, is_float, is_double, exit; __ movl(rsi, result_type); __ cmpl(rsi, T_LONG); @@ -243,7 +244,7 @@ class StubGenerator: public StubCodeGenerator { __ verify_FPU(0, "generate_call_stub"); // pop parameters - __ leal(rsp, rsp_after_call); + __ lea(rsp, rsp_after_call); // restore %mxcsr if (sse_save) { @@ -251,13 +252,13 @@ class StubGenerator: public StubCodeGenerator { } // restore rdi, rsi and rbx, - __ movl(rbx, saved_rbx); - __ movl(rsi, saved_rsi); - __ movl(rdi, saved_rdi); - __ addl(rsp, 4*wordSize); + __ movptr(rbx, saved_rbx); + __ movptr(rsi, saved_rsi); + __ movptr(rdi, saved_rdi); + __ addptr(rsp, 4*wordSize); // return - __ popl(rbp); + __ pop(rbp); __ ret(0); // handle return types different from T_INT @@ -291,7 +292,7 @@ class StubGenerator: public StubCodeGenerator { // return above that handles interpreter returns. BLOCK_COMMENT("call_stub_compiled_return:"); - StubRoutines::i486::set_call_stub_compiled_return( __ pc()); + StubRoutines::x86::set_call_stub_compiled_return( __ pc()); #ifdef COMPILER2 if (UseSSE >= 2) { @@ -337,12 +338,12 @@ class StubGenerator: public StubCodeGenerator { address start = __ pc(); // get thread directly - __ movl(rcx, thread); + __ movptr(rcx, thread); #ifdef ASSERT // verify that threads correspond { Label L; __ get_thread(rbx); - __ cmpl(rbx, rcx); + __ cmpptr(rbx, rcx); __ jcc(Assembler::equal, L); __ stop("StubRoutines::catch_exception: threads must correspond"); __ bind(L); @@ -350,7 +351,7 @@ class StubGenerator: public StubCodeGenerator { #endif // set pending exception __ verify_oop(rax); - __ movl(Address(rcx, Thread::pending_exception_offset()), rax ); + __ movptr(Address(rcx, Thread::pending_exception_offset()), rax ); __ lea(Address(rcx, Thread::exception_file_offset ()), ExternalAddress((address)__FILE__)); __ movl(Address(rcx, Thread::exception_line_offset ()), __LINE__ ); @@ -389,7 +390,7 @@ class StubGenerator: public StubCodeGenerator { // make sure this code is only executed if there is a pending exception { Label L; __ get_thread(rcx); - __ cmpl(Address(rcx, Thread::pending_exception_offset()), NULL_WORD); + __ cmpptr(Address(rcx, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::notEqual, L); __ stop("StubRoutines::forward exception: no pending exception (1)"); __ bind(L); @@ -397,21 +398,21 @@ class StubGenerator: public StubCodeGenerator { #endif // compute exception handler into rbx, - __ movl(rax, Address(rsp, 0)); + __ movptr(rax, Address(rsp, 0)); BLOCK_COMMENT("call exception_handler_for_return_address"); __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), rax); - __ movl(rbx, rax); + __ mov(rbx, rax); // setup rax, & rdx, remove return address & clear pending exception __ get_thread(rcx); - __ popl(rdx); - __ movl(rax, Address(rcx, Thread::pending_exception_offset())); - __ movl(Address(rcx, Thread::pending_exception_offset()), NULL_WORD); + __ pop(rdx); + __ movptr(rax, Address(rcx, Thread::pending_exception_offset())); + __ movptr(Address(rcx, Thread::pending_exception_offset()), (int32_t)NULL_WORD); #ifdef ASSERT // make sure exception is set { Label L; - __ testl(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::notEqual, L); __ stop("StubRoutines::forward exception: no pending exception (2)"); __ bind(L); @@ -447,13 +448,13 @@ class StubGenerator: public StubCodeGenerator { StubCodeMark mark(this, "StubRoutines", "atomic_xchg"); address start = __ pc(); - __ pushl(rdx); + __ push(rdx); Address exchange(rsp, 2 * wordSize); Address dest_addr(rsp, 3 * wordSize); __ movl(rax, exchange); - __ movl(rdx, dest_addr); - __ xchg(rax, Address(rdx, 0)); - __ popl(rdx); + __ movptr(rdx, dest_addr); + __ xchgl(rax, Address(rdx, 0)); + __ pop(rdx); __ ret(0); return start; @@ -476,8 +477,8 @@ class StubGenerator: public StubCodeGenerator { if (CheckJNICalls && UseSSE > 0 ) { Label ok_ret; ExternalAddress mxcsr_std(StubRoutines::addr_mxcsr_std()); - __ pushl(rax); - __ subl(rsp, wordSize); // allocate a temp location + __ push(rax); + __ subptr(rsp, wordSize); // allocate a temp location __ stmxcsr(mxcsr_save); __ movl(rax, mxcsr_save); __ andl(rax, MXCSR_MASK); @@ -489,8 +490,8 @@ class StubGenerator: public StubCodeGenerator { __ ldmxcsr(mxcsr_std); __ bind(ok_ret); - __ addl(rsp, wordSize); - __ popl(rax); + __ addptr(rsp, wordSize); + __ pop(rax); } __ ret(0); @@ -514,8 +515,8 @@ class StubGenerator: public StubCodeGenerator { if (CheckJNICalls) { Label ok_ret; - __ pushl(rax); - __ subl(rsp, wordSize); // allocate a temp location + __ push(rax); + __ subptr(rsp, wordSize); // allocate a temp location __ fnstcw(fpu_cntrl_wrd_save); __ movl(rax, fpu_cntrl_wrd_save); __ andl(rax, FPU_CNTRL_WRD_MASK); @@ -528,8 +529,8 @@ class StubGenerator: public StubCodeGenerator { __ fldcw(fpu_std); __ bind(ok_ret); - __ addl(rsp, wordSize); - __ popl(rax); + __ addptr(rsp, wordSize); + __ pop(rax); } __ ret(0); @@ -563,22 +564,22 @@ class StubGenerator: public StubCodeGenerator { assert(FPUStateSizeInWords == 27, "update stack layout"); // Save outgoing argument to stack across push_FPU_state() - __ subl(rsp, wordSize * 2); + __ subptr(rsp, wordSize * 2); __ fstp_d(Address(rsp, 0)); // Save CPU & FPU state - __ pushl(rbx); - __ pushl(rcx); - __ pushl(rsi); - __ pushl(rdi); - __ pushl(rbp); + __ push(rbx); + __ push(rcx); + __ push(rsi); + __ push(rdi); + __ push(rbp); __ push_FPU_state(); // push_FPU_state() resets the FP top of stack // Load original double into FP top of stack __ fld_d(Address(rsp, saved_argument_off * wordSize)); // Store double into stack as outgoing argument - __ subl(rsp, wordSize*2); + __ subptr(rsp, wordSize*2); __ fst_d(Address(rsp, 0)); // Prepare FPU for doing math in C-land @@ -592,12 +593,12 @@ class StubGenerator: public StubCodeGenerator { // Restore CPU & FPU state __ pop_FPU_state(); - __ popl(rbp); - __ popl(rdi); - __ popl(rsi); - __ popl(rcx); - __ popl(rbx); - __ addl(rsp, wordSize * 2); + __ pop(rbp); + __ pop(rdi); + __ pop(rsi); + __ pop(rcx); + __ pop(rbx); + __ addptr(rsp, wordSize * 2); __ ret(0); @@ -613,13 +614,13 @@ class StubGenerator: public StubCodeGenerator { StubCodeMark mark(this, "StubRoutines", "handler_for_unsafe_access"); address start = __ pc(); - __ pushl(0); // hole for return address-to-be - __ pushad(); // push registers + __ push(0); // hole for return address-to-be + __ pusha(); // push registers Address next_pc(rsp, RegisterImpl::number_of_registers * BytesPerWord); BLOCK_COMMENT("call handle_unsafe_access"); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, handle_unsafe_access))); - __ movl(next_pc, rax); // stuff next address - __ popad(); + __ movptr(next_pc, rax); // stuff next address + __ popa(); __ ret(0); // jump to next address return start; @@ -643,62 +644,62 @@ class StubGenerator: public StubCodeGenerator { // [tos + 5]: saved rax, - saved by caller and bashed Label exit, error; - __ pushfd(); - __ increment(ExternalAddress((address) StubRoutines::verify_oop_count_addr())); - __ pushl(rdx); // save rdx + __ pushf(); + __ incrementl(ExternalAddress((address) StubRoutines::verify_oop_count_addr())); + __ push(rdx); // save rdx // make sure object is 'reasonable' - __ movl(rax, Address(rsp, 4 * wordSize)); // get object - __ testl(rax, rax); + __ movptr(rax, Address(rsp, 4 * wordSize)); // get object + __ testptr(rax, rax); __ jcc(Assembler::zero, exit); // if obj is NULL it is ok // Check if the oop is in the right area of memory const int oop_mask = Universe::verify_oop_mask(); const int oop_bits = Universe::verify_oop_bits(); - __ movl(rdx, rax); - __ andl(rdx, oop_mask); - __ cmpl(rdx, oop_bits); + __ mov(rdx, rax); + __ andptr(rdx, oop_mask); + __ cmpptr(rdx, oop_bits); __ jcc(Assembler::notZero, error); // make sure klass is 'reasonable' - __ movl(rax, Address(rax, oopDesc::klass_offset_in_bytes())); // get klass - __ testl(rax, rax); + __ movptr(rax, Address(rax, oopDesc::klass_offset_in_bytes())); // get klass + __ testptr(rax, rax); __ jcc(Assembler::zero, error); // if klass is NULL it is broken // Check if the klass is in the right area of memory const int klass_mask = Universe::verify_klass_mask(); const int klass_bits = Universe::verify_klass_bits(); - __ movl(rdx, rax); - __ andl(rdx, klass_mask); - __ cmpl(rdx, klass_bits); + __ mov(rdx, rax); + __ andptr(rdx, klass_mask); + __ cmpptr(rdx, klass_bits); __ jcc(Assembler::notZero, error); // make sure klass' klass is 'reasonable' - __ movl(rax, Address(rax, oopDesc::klass_offset_in_bytes())); // get klass' klass - __ testl(rax, rax); + __ movptr(rax, Address(rax, oopDesc::klass_offset_in_bytes())); // get klass' klass + __ testptr(rax, rax); __ jcc(Assembler::zero, error); // if klass' klass is NULL it is broken - __ movl(rdx, rax); - __ andl(rdx, klass_mask); - __ cmpl(rdx, klass_bits); + __ mov(rdx, rax); + __ andptr(rdx, klass_mask); + __ cmpptr(rdx, klass_bits); __ jcc(Assembler::notZero, error); // if klass not in right area // of memory it is broken too. // return if everything seems ok __ bind(exit); - __ movl(rax, Address(rsp, 5 * wordSize)); // get saved rax, back - __ popl(rdx); // restore rdx - __ popfd(); // restore EFLAGS + __ movptr(rax, Address(rsp, 5 * wordSize)); // get saved rax, back + __ pop(rdx); // restore rdx + __ popf(); // restore EFLAGS __ ret(3 * wordSize); // pop arguments // handle errors __ bind(error); - __ movl(rax, Address(rsp, 5 * wordSize)); // get saved rax, back - __ popl(rdx); // get saved rdx back - __ popfd(); // get saved EFLAGS off stack -- will be ignored - __ pushad(); // push registers (eip = return address & msg are already pushed) + __ movptr(rax, Address(rsp, 5 * wordSize)); // get saved rax, back + __ pop(rdx); // get saved rdx back + __ popf(); // get saved EFLAGS off stack -- will be ignored + __ pusha(); // push registers (eip = return address & msg are already pushed) BLOCK_COMMENT("call MacroAssembler::debug"); - __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug))); - __ popad(); + __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug32))); + __ popa(); __ ret(3 * wordSize); // pop arguments return start; } @@ -717,12 +718,12 @@ class StubGenerator: public StubCodeGenerator { case BarrierSet::G1SATBCT: case BarrierSet::G1SATBCTLogging: { - __ pushad(); // push registers - __ pushl(count); - __ pushl(start); + __ pusha(); // push registers + __ push(count); + __ push(start); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre)); __ addl(esp, wordSize * 2); - __ popad(); + __ popa(); } break; case BarrierSet::CardTableModRef: @@ -753,12 +754,12 @@ class StubGenerator: public StubCodeGenerator { case BarrierSet::G1SATBCT: case BarrierSet::G1SATBCTLogging: { - __ pushad(); // push registers - __ pushl(count); - __ pushl(start); + __ pusha(); // push registers + __ push(count); + __ push(start); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post)); __ addl(esp, wordSize * 2); - __ popad(); + __ popa(); } break; @@ -774,10 +775,10 @@ class StubGenerator: public StubCodeGenerator { const Register end = count; // elements count; end == start+count-1 assert_different_registers(start, end); - __ leal(end, Address(start, count, Address::times_4, -4)); - __ shrl(start, CardTableModRefBS::card_shift); - __ shrl(end, CardTableModRefBS::card_shift); - __ subl(end, start); // end --> count + __ lea(end, Address(start, count, Address::times_ptr, -wordSize)); + __ shrptr(start, CardTableModRefBS::card_shift); + __ shrptr(end, CardTableModRefBS::card_shift); + __ subptr(end, start); // end --> count __ BIND(L_loop); intptr_t disp = (intptr_t) ct->byte_map_base; Address cardtable(start, count, Address::times_1, disp); @@ -823,7 +824,7 @@ class StubGenerator: public StubCodeGenerator { __ movq(Address(from, to_from, Address::times_1, 40), mmx5); __ movq(Address(from, to_from, Address::times_1, 48), mmx6); __ movq(Address(from, to_from, Address::times_1, 56), mmx7); - __ addl(from, 64); + __ addptr(from, 64); __ BIND(L_copy_64_bytes); __ subl(qword_count, 8); __ jcc(Assembler::greaterEqual, L_copy_64_bytes_loop); @@ -835,7 +836,7 @@ class StubGenerator: public StubCodeGenerator { __ BIND(L_copy_8_bytes); __ movq(mmx0, Address(from, 0)); __ movq(Address(from, to_from, Address::times_1), mmx0); - __ addl(from, 8); + __ addptr(from, 8); __ decrement(qword_count); __ jcc(Assembler::greater, L_copy_8_bytes); __ BIND(L_exit); @@ -852,7 +853,7 @@ class StubGenerator: public StubCodeGenerator { Label L_0_count, L_exit, L_skip_align1, L_skip_align2, L_copy_byte; Label L_copy_2_bytes, L_copy_4_bytes, L_copy_64_bytes; - int shift = Address::times_4 - sf; + int shift = Address::times_ptr - sf; const Register from = rsi; // source array address const Register to = rdi; // destination array address @@ -861,22 +862,22 @@ class StubGenerator: public StubCodeGenerator { const Register saved_to = rdx; // saved destination array address __ enter(); // required for proper stackwalking of RuntimeStub frame - __ pushl(rsi); - __ pushl(rdi); - __ movl(from , Address(rsp, 12+ 4)); - __ movl(to , Address(rsp, 12+ 8)); + __ push(rsi); + __ push(rdi); + __ movptr(from , Address(rsp, 12+ 4)); + __ movptr(to , Address(rsp, 12+ 8)); __ movl(count, Address(rsp, 12+ 12)); if (t == T_OBJECT) { __ testl(count, count); __ jcc(Assembler::zero, L_0_count); gen_write_ref_array_pre_barrier(to, count); - __ movl(saved_to, to); // save 'to' + __ mov(saved_to, to); // save 'to' } *entry = __ pc(); // Entry point from conjoint arraycopy stub. BLOCK_COMMENT("Entry:"); - __ subl(to, from); // to --> to_from + __ subptr(to, from); // to --> to_from __ cmpl(count, 2< to_from + __ subptr(to, from); // to --> to_from if (VM_Version::supports_mmx()) { mmx_copy_forward(from, to_from, count); } else { @@ -1153,14 +1154,14 @@ class StubGenerator: public StubCodeGenerator { __ BIND(L_copy_8_bytes_loop); __ fild_d(Address(from, 0)); __ fistp_d(Address(from, to_from, Address::times_1)); - __ addl(from, 8); + __ addptr(from, 8); __ BIND(L_copy_8_bytes); __ decrement(count); __ jcc(Assembler::greaterEqual, L_copy_8_bytes_loop); } inc_copy_counter_np(T_LONG); __ leave(); // required for proper stackwalking of RuntimeStub frame - __ xorl(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ ret(0); return start; } @@ -1178,20 +1179,20 @@ class StubGenerator: public StubCodeGenerator { const Register end_from = rax; // source array end address __ enter(); // required for proper stackwalking of RuntimeStub frame - __ movl(from , Address(rsp, 8+0)); // from - __ movl(to , Address(rsp, 8+4)); // to - __ movl(count, Address(rsp, 8+8)); // count + __ movptr(from , Address(rsp, 8+0)); // from + __ movptr(to , Address(rsp, 8+4)); // to + __ movl2ptr(count, Address(rsp, 8+8)); // count *entry = __ pc(); // Entry point from generic arraycopy stub. BLOCK_COMMENT("Entry:"); // arrays overlap test - __ cmpl(to, from); + __ cmpptr(to, from); RuntimeAddress nooverlap(nooverlap_target); __ jump_cc(Assembler::belowEqual, nooverlap); - __ leal(end_from, Address(from, count, Address::times_8, 0)); - __ cmpl(to, end_from); - __ movl(from, Address(rsp, 8)); // from + __ lea(end_from, Address(from, count, Address::times_8, 0)); + __ cmpptr(to, end_from); + __ movptr(from, Address(rsp, 8)); // from __ jump_cc(Assembler::aboveEqual, nooverlap); __ jmpb(L_copy_8_bytes); @@ -1214,7 +1215,7 @@ class StubGenerator: public StubCodeGenerator { } inc_copy_counter_np(T_LONG); __ leave(); // required for proper stackwalking of RuntimeStub frame - __ xorl(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ ret(0); return start; } @@ -1251,14 +1252,14 @@ class StubGenerator: public StubCodeGenerator { Address super_cache_addr( sub_klass, sc_offset); // if the pointers are equal, we are done (e.g., String[] elements) - __ cmpl(sub_klass, super_klass_addr); + __ cmpptr(sub_klass, super_klass_addr); __ jcc(Assembler::equal, L_success); // check the supertype display: - __ movl(temp, super_check_offset_addr); + __ movl2ptr(temp, super_check_offset_addr); Address super_check_addr(sub_klass, temp, Address::times_1, 0); - __ movl(temp, super_check_addr); // load displayed supertype - __ cmpl(temp, super_klass_addr); // test the super type + __ movptr(temp, super_check_addr); // load displayed supertype + __ cmpptr(temp, super_klass_addr); // test the super type __ jcc(Assembler::equal, L_success); // if it was a primary super, we can just fail immediately @@ -1271,31 +1272,31 @@ class StubGenerator: public StubCodeGenerator { { // The repne_scan instruction uses fixed registers, which we must spill. // (We need a couple more temps in any case.) - __ pushl(rax); - __ pushl(rcx); - __ pushl(rdi); + __ push(rax); + __ push(rcx); + __ push(rdi); assert_different_registers(sub_klass, rax, rcx, rdi); - __ movl(rdi, secondary_supers_addr); + __ movptr(rdi, secondary_supers_addr); // Load the array length. __ movl(rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes())); // Skip to start of data. - __ addl(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + __ addptr(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); // Scan rcx words at [edi] for occurance of rax, // Set NZ/Z based on last compare - __ movl(rax, super_klass_addr); + __ movptr(rax, super_klass_addr); __ repne_scan(); // Unspill the temp. registers: - __ popl(rdi); - __ popl(rcx); - __ popl(rax); + __ pop(rdi); + __ pop(rcx); + __ pop(rax); } __ jcc(Assembler::notEqual, L_failure); // Success. Cache the super we found and proceed in triumph. - __ movl(temp, super_klass_addr); // note: rax, is dead - __ movl(super_cache_addr, temp); + __ movptr(temp, super_klass_addr); // note: rax, is dead + __ movptr(super_cache_addr, temp); if (!fall_through_on_success) __ jmp(L_success); @@ -1338,9 +1339,9 @@ class StubGenerator: public StubCodeGenerator { __ enter(); // required for proper stackwalking of RuntimeStub frame - __ pushl(rsi); - __ pushl(rdi); - __ pushl(rbx); + __ push(rsi); + __ push(rdi); + __ push(rbx); Address from_arg(rsp, 16+ 4); // from Address to_arg(rsp, 16+ 8); // to @@ -1349,9 +1350,9 @@ class StubGenerator: public StubCodeGenerator { Address ckval_arg(rsp, 16+20); // super_klass // Load up: - __ movl(from, from_arg); - __ movl(to, to_arg); - __ movl(length, length_arg); + __ movptr(from, from_arg); + __ movptr(to, to_arg); + __ movl2ptr(length, length_arg); *entry = __ pc(); // Entry point from generic arraycopy stub. BLOCK_COMMENT("Entry:"); @@ -1364,28 +1365,28 @@ class StubGenerator: public StubCodeGenerator { // checked. // Loop-invariant addresses. They are exclusive end pointers. - Address end_from_addr(from, length, Address::times_4, 0); - Address end_to_addr(to, length, Address::times_4, 0); + Address end_from_addr(from, length, Address::times_ptr, 0); + Address end_to_addr(to, length, Address::times_ptr, 0); Register end_from = from; // re-use Register end_to = to; // re-use Register count = length; // re-use // Loop-variant addresses. They assume post-incremented count < 0. - Address from_element_addr(end_from, count, Address::times_4, 0); - Address to_element_addr(end_to, count, Address::times_4, 0); + Address from_element_addr(end_from, count, Address::times_ptr, 0); + Address to_element_addr(end_to, count, Address::times_ptr, 0); Address elem_klass_addr(elem, oopDesc::klass_offset_in_bytes()); // Copy from low to high addresses, indexed from the end of each array. - __ leal(end_from, end_from_addr); - __ leal(end_to, end_to_addr); + __ lea(end_from, end_from_addr); + __ lea(end_to, end_to_addr); gen_write_ref_array_pre_barrier(to, count); assert(length == count, ""); // else fix next line: - __ negl(count); // negate and test the length + __ negptr(count); // negate and test the length __ jccb(Assembler::notZero, L_load_element); // Empty array: Nothing to do. - __ xorl(rax, rax); // return 0 on (trivial) success + __ xorptr(rax, rax); // return 0 on (trivial) success __ jmp(L_done); // ======== begin loop ======== @@ -1396,20 +1397,20 @@ class StubGenerator: public StubCodeGenerator { __ align(16); __ BIND(L_store_element); - __ movl(to_element_addr, elem); // store the oop + __ movptr(to_element_addr, elem); // store the oop __ increment(count); // increment the count toward zero __ jccb(Assembler::zero, L_do_card_marks); // ======== loop entry is here ======== __ BIND(L_load_element); - __ movl(elem, from_element_addr); // load the oop - __ testl(elem, elem); + __ movptr(elem, from_element_addr); // load the oop + __ testptr(elem, elem); __ jccb(Assembler::zero, L_store_element); // (Could do a trick here: Remember last successful non-null // element stored and make a quick oop equality check on it.) - __ movl(elem_klass, elem_klass_addr); // query the object klass + __ movptr(elem_klass, elem_klass_addr); // query the object klass generate_type_check(elem_klass, ckoff_arg, ckval_arg, temp, &L_store_element, NULL); // (On fall-through, we have failed the element type check.) @@ -1420,25 +1421,25 @@ class StubGenerator: public StubCodeGenerator { // Emit GC store barriers for the oops we have copied (length_arg + count), // and report their number to the caller. __ addl(count, length_arg); // transfers = (length - remaining) - __ movl(rax, count); // save the value - __ notl(rax); // report (-1^K) to caller - __ movl(to, to_arg); // reload + __ movl2ptr(rax, count); // save the value + __ notptr(rax); // report (-1^K) to caller + __ movptr(to, to_arg); // reload assert_different_registers(to, count, rax); gen_write_ref_array_post_barrier(to, count); __ jmpb(L_done); // Come here on success only. __ BIND(L_do_card_marks); - __ movl(count, length_arg); - __ movl(to, to_arg); // reload + __ movl2ptr(count, length_arg); + __ movptr(to, to_arg); // reload gen_write_ref_array_post_barrier(to, count); - __ xorl(rax, rax); // return 0 on success + __ xorptr(rax, rax); // return 0 on success // Common exit point (success or failure). __ BIND(L_done); - __ popl(rbx); - __ popl(rdi); - __ popl(rsi); + __ pop(rbx); + __ pop(rdi); + __ pop(rsi); inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr); __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -1480,24 +1481,24 @@ class StubGenerator: public StubCodeGenerator { const Register count = rcx; // elements count __ enter(); // required for proper stackwalking of RuntimeStub frame - __ pushl(rsi); - __ pushl(rdi); + __ push(rsi); + __ push(rdi); Address from_arg(rsp, 12+ 4); // from Address to_arg(rsp, 12+ 8); // to Address count_arg(rsp, 12+12); // byte count // Load up: - __ movl(from , from_arg); - __ movl(to , to_arg); - __ movl(count, count_arg); + __ movptr(from , from_arg); + __ movptr(to , to_arg); + __ movl2ptr(count, count_arg); // bump this on entry, not on exit: inc_counter_np(SharedRuntime::_unsafe_array_copy_ctr); const Register bits = rsi; - __ movl(bits, from); - __ orl(bits, to); - __ orl(bits, count); + __ mov(bits, from); + __ orptr(bits, to); + __ orptr(bits, count); __ testl(bits, BytesPerLong-1); __ jccb(Assembler::zero, L_long_aligned); @@ -1509,20 +1510,20 @@ class StubGenerator: public StubCodeGenerator { __ jump_cc(Assembler::notZero, RuntimeAddress(byte_copy_entry)); __ BIND(L_short_aligned); - __ shrl(count, LogBytesPerShort); // size => short_count + __ shrptr(count, LogBytesPerShort); // size => short_count __ movl(count_arg, count); // update 'count' __ jump(RuntimeAddress(short_copy_entry)); __ BIND(L_int_aligned); - __ shrl(count, LogBytesPerInt); // size => int_count + __ shrptr(count, LogBytesPerInt); // size => int_count __ movl(count_arg, count); // update 'count' __ jump(RuntimeAddress(int_copy_entry)); __ BIND(L_long_aligned); - __ shrl(count, LogBytesPerLong); // size => qword_count + __ shrptr(count, LogBytesPerLong); // size => qword_count __ movl(count_arg, count); // update 'count' - __ popl(rdi); // Do pops here since jlong_arraycopy stub does not do it. - __ popl(rsi); + __ pop(rdi); // Do pops here since jlong_arraycopy stub does not do it. + __ pop(rsi); __ jump(RuntimeAddress(long_copy_entry)); return start; @@ -1595,8 +1596,8 @@ class StubGenerator: public StubCodeGenerator { address start = __ pc(); __ enter(); // required for proper stackwalking of RuntimeStub frame - __ pushl(rsi); - __ pushl(rdi); + __ push(rsi); + __ push(rdi); // bump this on entry, not on exit: inc_counter_np(SharedRuntime::_generic_array_copy_ctr); @@ -1629,27 +1630,27 @@ class StubGenerator: public StubCodeGenerator { const Register length = rcx; // transfer count // if (src == NULL) return -1; - __ movl(src, SRC); // src oop - __ testl(src, src); + __ movptr(src, SRC); // src oop + __ testptr(src, src); __ jccb(Assembler::zero, L_failed_0); // if (src_pos < 0) return -1; - __ movl(src_pos, SRC_POS); // src_pos + __ movl2ptr(src_pos, SRC_POS); // src_pos __ testl(src_pos, src_pos); __ jccb(Assembler::negative, L_failed_0); // if (dst == NULL) return -1; - __ movl(dst, DST); // dst oop - __ testl(dst, dst); + __ movptr(dst, DST); // dst oop + __ testptr(dst, dst); __ jccb(Assembler::zero, L_failed_0); // if (dst_pos < 0) return -1; - __ movl(dst_pos, DST_POS); // dst_pos + __ movl2ptr(dst_pos, DST_POS); // dst_pos __ testl(dst_pos, dst_pos); __ jccb(Assembler::negative, L_failed_0); // if (length < 0) return -1; - __ movl(length, LENGTH); // length + __ movl2ptr(length, LENGTH); // length __ testl(length, length); __ jccb(Assembler::negative, L_failed_0); @@ -1657,18 +1658,18 @@ class StubGenerator: public StubCodeGenerator { Address src_klass_addr(src, oopDesc::klass_offset_in_bytes()); Address dst_klass_addr(dst, oopDesc::klass_offset_in_bytes()); const Register rcx_src_klass = rcx; // array klass - __ movl(rcx_src_klass, Address(src, oopDesc::klass_offset_in_bytes())); + __ movptr(rcx_src_klass, Address(src, oopDesc::klass_offset_in_bytes())); #ifdef ASSERT // assert(src->klass() != NULL); BLOCK_COMMENT("assert klasses not null"); { Label L1, L2; - __ testl(rcx_src_klass, rcx_src_klass); + __ testptr(rcx_src_klass, rcx_src_klass); __ jccb(Assembler::notZero, L2); // it is broken if klass is NULL __ bind(L1); __ stop("broken null klass"); __ bind(L2); - __ cmpl(dst_klass_addr, 0); + __ cmpptr(dst_klass_addr, (int32_t)NULL_WORD); __ jccb(Assembler::equal, L1); // this would be broken also BLOCK_COMMENT("assert done"); } @@ -1692,7 +1693,7 @@ class StubGenerator: public StubCodeGenerator { __ jcc(Assembler::equal, L_objArray); // if (src->klass() != dst->klass()) return -1; - __ cmpl(rcx_src_klass, dst_klass_addr); + __ cmpptr(rcx_src_klass, dst_klass_addr); __ jccb(Assembler::notEqual, L_failed_0); const Register rcx_lh = rcx; // layout helper @@ -1726,12 +1727,12 @@ class StubGenerator: public StubCodeGenerator { const Register dst_array = dst; // dst array offset const Register rdi_elsize = rdi; // log2 element size - __ movl(rsi_offset, rcx_lh); - __ shrl(rsi_offset, Klass::_lh_header_size_shift); - __ andl(rsi_offset, Klass::_lh_header_size_mask); // array_offset - __ addl(src_array, rsi_offset); // src array offset - __ addl(dst_array, rsi_offset); // dst array offset - __ andl(rcx_lh, Klass::_lh_log2_element_size_mask); // log2 elsize + __ mov(rsi_offset, rcx_lh); + __ shrptr(rsi_offset, Klass::_lh_header_size_shift); + __ andptr(rsi_offset, Klass::_lh_header_size_mask); // array_offset + __ addptr(src_array, rsi_offset); // src array offset + __ addptr(dst_array, rsi_offset); // dst array offset + __ andptr(rcx_lh, Klass::_lh_log2_element_size_mask); // log2 elsize // next registers should be set before the jump to corresponding stub const Register from = src; // source array address @@ -1743,17 +1744,17 @@ class StubGenerator: public StubCodeGenerator { #define COUNT Address(rsp, 12+12) // Only for oop arraycopy BLOCK_COMMENT("scale indexes to element size"); - __ movl(rsi, SRC_POS); // src_pos - __ shll(rsi); // src_pos << rcx (log2 elsize) + __ movl2ptr(rsi, SRC_POS); // src_pos + __ shlptr(rsi); // src_pos << rcx (log2 elsize) assert(src_array == from, ""); - __ addl(from, rsi); // from = src_array + SRC_POS << log2 elsize - __ movl(rdi, DST_POS); // dst_pos - __ shll(rdi); // dst_pos << rcx (log2 elsize) + __ addptr(from, rsi); // from = src_array + SRC_POS << log2 elsize + __ movl2ptr(rdi, DST_POS); // dst_pos + __ shlptr(rdi); // dst_pos << rcx (log2 elsize) assert(dst_array == to, ""); - __ addl(to, rdi); // to = dst_array + DST_POS << log2 elsize - __ movl(FROM, from); // src_addr - __ movl(rdi_elsize, rcx_lh); // log2 elsize - __ movl(count, LENGTH); // elements count + __ addptr(to, rdi); // to = dst_array + DST_POS << log2 elsize + __ movptr(FROM, from); // src_addr + __ mov(rdi_elsize, rcx_lh); // log2 elsize + __ movl2ptr(count, LENGTH); // elements count BLOCK_COMMENT("choose copy loop based on element size"); __ cmpl(rdi_elsize, 0); @@ -1767,15 +1768,15 @@ class StubGenerator: public StubCodeGenerator { __ cmpl(rdi_elsize, LogBytesPerLong); __ jccb(Assembler::notEqual, L_failed); #endif - __ popl(rdi); // Do pops here since jlong_arraycopy stub does not do it. - __ popl(rsi); + __ pop(rdi); // Do pops here since jlong_arraycopy stub does not do it. + __ pop(rsi); __ jump(RuntimeAddress(entry_jlong_arraycopy)); __ BIND(L_failed); - __ xorl(rax, rax); - __ notl(rax); // return -1 - __ popl(rdi); - __ popl(rsi); + __ xorptr(rax, rax); + __ notptr(rax); // return -1 + __ pop(rdi); + __ pop(rsi); __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -1785,7 +1786,7 @@ class StubGenerator: public StubCodeGenerator { Label L_plain_copy, L_checkcast_copy; // test array classes for subtyping - __ cmpl(rcx_src_klass, dst_klass_addr); // usual case is exact equality + __ cmpptr(rcx_src_klass, dst_klass_addr); // usual case is exact equality __ jccb(Assembler::notEqual, L_checkcast_copy); // Identically typed arrays can be copied without element-wise checks. @@ -1793,15 +1794,15 @@ class StubGenerator: public StubCodeGenerator { arraycopy_range_checks(src, src_pos, dst, dst_pos, LENGTH, L_failed); __ BIND(L_plain_copy); - __ movl(count, LENGTH); // elements count - __ movl(src_pos, SRC_POS); // reload src_pos - __ leal(from, Address(src, src_pos, Address::times_4, - arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr - __ movl(dst_pos, DST_POS); // reload dst_pos - __ leal(to, Address(dst, dst_pos, Address::times_4, - arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr - __ movl(FROM, from); // src_addr - __ movl(TO, to); // dst_addr + __ movl2ptr(count, LENGTH); // elements count + __ movl2ptr(src_pos, SRC_POS); // reload src_pos + __ lea(from, Address(src, src_pos, Address::times_ptr, + arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr + __ movl2ptr(dst_pos, DST_POS); // reload dst_pos + __ lea(to, Address(dst, dst_pos, Address::times_ptr, + arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr + __ movptr(FROM, from); // src_addr + __ movptr(TO, to); // dst_addr __ movl(COUNT, count); // count __ jump(RuntimeAddress(entry_oop_arraycopy)); @@ -1821,37 +1822,37 @@ class StubGenerator: public StubCodeGenerator { Address dst_klass_lh_addr(rsi_dst_klass, lh_offset); // Before looking at dst.length, make sure dst is also an objArray. - __ movl(rsi_dst_klass, dst_klass_addr); + __ movptr(rsi_dst_klass, dst_klass_addr); __ cmpl(dst_klass_lh_addr, objArray_lh); __ jccb(Assembler::notEqual, L_failed); // It is safe to examine both src.length and dst.length. - __ movl(src_pos, SRC_POS); // reload rsi + __ movl2ptr(src_pos, SRC_POS); // reload rsi arraycopy_range_checks(src, src_pos, dst, dst_pos, LENGTH, L_failed); // (Now src_pos and dst_pos are killed, but not src and dst.) // We'll need this temp (don't forget to pop it after the type check). - __ pushl(rbx); + __ push(rbx); Register rbx_src_klass = rbx; - __ movl(rbx_src_klass, rcx_src_klass); // spill away from rcx - __ movl(rsi_dst_klass, dst_klass_addr); + __ mov(rbx_src_klass, rcx_src_klass); // spill away from rcx + __ movptr(rsi_dst_klass, dst_klass_addr); Address super_check_offset_addr(rsi_dst_klass, sco_offset); Label L_fail_array_check; generate_type_check(rbx_src_klass, super_check_offset_addr, dst_klass_addr, rdi_temp, NULL, &L_fail_array_check); // (On fall-through, we have passed the array type check.) - __ popl(rbx); + __ pop(rbx); __ jmp(L_plain_copy); __ BIND(L_fail_array_check); // Reshuffle arguments so we can call checkcast_arraycopy: // match initial saves for checkcast_arraycopy - // pushl(rsi); // already done; see above - // pushl(rdi); // already done; see above - // pushl(rbx); // already done; see above + // push(rsi); // already done; see above + // push(rdi); // already done; see above + // push(rbx); // already done; see above // Marshal outgoing arguments now, freeing registers. Address from_arg(rsp, 16+ 4); // from @@ -1866,24 +1867,24 @@ class StubGenerator: public StubCodeGenerator { // push rbx, changed the incoming offsets (why not just use rbp,??) // assert(SRC_POS_arg.disp() == SRC_POS.disp() + 4, ""); - __ movl(rbx, Address(rsi_dst_klass, ek_offset)); - __ movl(length, LENGTH_arg); // reload elements count - __ movl(src_pos, SRC_POS_arg); // reload src_pos - __ movl(dst_pos, DST_POS_arg); // reload dst_pos + __ movptr(rbx, Address(rsi_dst_klass, ek_offset)); + __ movl2ptr(length, LENGTH_arg); // reload elements count + __ movl2ptr(src_pos, SRC_POS_arg); // reload src_pos + __ movl2ptr(dst_pos, DST_POS_arg); // reload dst_pos - __ movl(ckval_arg, rbx); // destination element type + __ movptr(ckval_arg, rbx); // destination element type __ movl(rbx, Address(rbx, sco_offset)); __ movl(ckoff_arg, rbx); // corresponding class check offset __ movl(length_arg, length); // outgoing length argument - __ leal(from, Address(src, src_pos, Address::times_4, + __ lea(from, Address(src, src_pos, Address::times_ptr, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); - __ movl(from_arg, from); + __ movptr(from_arg, from); - __ leal(to, Address(dst, dst_pos, Address::times_4, + __ lea(to, Address(dst, dst_pos, Address::times_ptr, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); - __ movl(to_arg, to); + __ movptr(to_arg, to); __ jump(RuntimeAddress(entry_checkcast_arraycopy)); } @@ -1934,10 +1935,10 @@ class StubGenerator: public StubCodeGenerator { &entry_jint_arraycopy, "jint_arraycopy"); StubRoutines::_oop_disjoint_arraycopy = - generate_disjoint_copy(T_OBJECT, true, Address::times_4, &entry, + generate_disjoint_copy(T_OBJECT, true, Address::times_ptr, &entry, "oop_disjoint_arraycopy"); StubRoutines::_oop_arraycopy = - generate_conjoint_copy(T_OBJECT, true, Address::times_4, entry, + generate_conjoint_copy(T_OBJECT, true, Address::times_ptr, entry, &entry_oop_arraycopy, "oop_arraycopy"); StubRoutines::_jlong_disjoint_arraycopy = @@ -2037,21 +2038,21 @@ class StubGenerator: public StubCodeGenerator { Register java_thread = rbx; __ get_thread(java_thread); if (restore_saved_exception_pc) { - __ movl(rax, Address(java_thread, in_bytes(JavaThread::saved_exception_pc_offset()))); - __ pushl(rax); + __ movptr(rax, Address(java_thread, in_bytes(JavaThread::saved_exception_pc_offset()))); + __ push(rax); } __ enter(); // required for proper stackwalking of RuntimeStub frame // pc and rbp, already pushed - __ subl(rsp, (framesize-2) * wordSize); // prolog + __ subptr(rsp, (framesize-2) * wordSize); // prolog // Frame is now completed as far as size and linkage. int frame_complete = __ pc() - start; // push java thread (becomes first argument of C function) - __ movl(Address(rsp, thread_off * wordSize), java_thread); + __ movptr(Address(rsp, thread_off * wordSize), java_thread); // Set up last_Java_sp and last_Java_fp __ set_last_Java_frame(java_thread, rsp, rbp, NULL); @@ -2075,7 +2076,7 @@ class StubGenerator: public StubCodeGenerator { // check for pending exceptions #ifdef ASSERT Label L; - __ cmpl(Address(java_thread, Thread::pending_exception_offset()), NULL_WORD); + __ cmpptr(Address(java_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::notEqual, L); __ should_not_reach_here(); __ bind(L); @@ -2137,8 +2138,8 @@ class StubGenerator: public StubCodeGenerator { // platform dependent create_control_words(); - StubRoutines::i486::_verify_mxcsr_entry = generate_verify_mxcsr(); - StubRoutines::i486::_verify_fpu_cntrl_wrd_entry = generate_verify_fpu_cntrl_wrd(); + StubRoutines::x86::_verify_mxcsr_entry = generate_verify_mxcsr(); + StubRoutines::x86::_verify_fpu_cntrl_wrd_entry = generate_verify_fpu_cntrl_wrd(); StubRoutines::_d2i_wrapper = generate_d2i_wrapper(T_INT, CAST_FROM_FN_PTR(address, SharedRuntime::d2i)); StubRoutines::_d2l_wrapper = generate_d2i_wrapper(T_LONG, diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp index c3b61d5bf76..6964a1eb048 100644 --- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp @@ -31,6 +31,7 @@ #define __ _masm-> #define TIMES_OOP (UseCompressedOops ? Address::times_4 : Address::times_8) +#define a__ ((Assembler*)_masm)-> #ifdef PRODUCT #define BLOCK_COMMENT(str) /* nothing */ @@ -210,32 +211,32 @@ class StubGenerator: public StubCodeGenerator { // stub code __ enter(); - __ subq(rsp, -rsp_after_call_off * wordSize); + __ subptr(rsp, -rsp_after_call_off * wordSize); // save register parameters #ifndef _WIN64 - __ movq(parameters, c_rarg5); // parameters - __ movq(entry_point, c_rarg4); // entry_point + __ movptr(parameters, c_rarg5); // parameters + __ movptr(entry_point, c_rarg4); // entry_point #endif - __ movq(method, c_rarg3); // method - __ movl(result_type, c_rarg2); // result type - __ movq(result, c_rarg1); // result - __ movq(call_wrapper, c_rarg0); // call wrapper + __ movptr(method, c_rarg3); // method + __ movl(result_type, c_rarg2); // result type + __ movptr(result, c_rarg1); // result + __ movptr(call_wrapper, c_rarg0); // call wrapper // save regs belonging to calling function - __ movq(rbx_save, rbx); - __ movq(r12_save, r12); - __ movq(r13_save, r13); - __ movq(r14_save, r14); - __ movq(r15_save, r15); + __ movptr(rbx_save, rbx); + __ movptr(r12_save, r12); + __ movptr(r13_save, r13); + __ movptr(r14_save, r14); + __ movptr(r15_save, r15); #ifdef _WIN64 const Address rdi_save(rbp, rdi_off * wordSize); const Address rsi_save(rbp, rsi_off * wordSize); - __ movq(rsi_save, rsi); - __ movq(rdi_save, rdi); + __ movptr(rsi_save, rsi); + __ movptr(rdi_save, rdi); #else const Address mxcsr_save(rbp, mxcsr_off * wordSize); { @@ -243,7 +244,7 @@ class StubGenerator: public StubCodeGenerator { __ stmxcsr(mxcsr_save); __ movl(rax, mxcsr_save); __ andl(rax, MXCSR_MASK); // Only check control and mask bits - ExternalAddress mxcsr_std(StubRoutines::amd64::mxcsr_std()); + ExternalAddress mxcsr_std(StubRoutines::x86::mxcsr_std()); __ cmp32(rax, mxcsr_std); __ jcc(Assembler::equal, skip_ldmx); __ ldmxcsr(mxcsr_std); @@ -252,14 +253,14 @@ class StubGenerator: public StubCodeGenerator { #endif // Load up thread register - __ movq(r15_thread, thread); + __ movptr(r15_thread, thread); __ reinit_heapbase(); #ifdef ASSERT // make sure we have no pending exceptions { Label L; - __ cmpq(Address(r15_thread, Thread::pending_exception_offset()), (int)NULL_WORD); + __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::equal, L); __ stop("StubRoutines::call_stub: entered with pending exception"); __ bind(L); @@ -274,25 +275,25 @@ class StubGenerator: public StubCodeGenerator { __ jcc(Assembler::zero, parameters_done); Label loop; - __ movq(c_rarg2, parameters); // parameter pointer - __ movl(c_rarg1, c_rarg3); // parameter counter is in c_rarg1 + __ movptr(c_rarg2, parameters); // parameter pointer + __ movl(c_rarg1, c_rarg3); // parameter counter is in c_rarg1 __ BIND(loop); if (TaggedStackInterpreter) { - __ movq(rax, Address(c_rarg2, 0)); // get tag - __ addq(c_rarg2, wordSize); // advance to next tag - __ pushq(rax); // pass tag + __ movl(rax, Address(c_rarg2, 0)); // get tag + __ addptr(c_rarg2, wordSize); // advance to next tag + __ push(rax); // pass tag } - __ movq(rax, Address(c_rarg2, 0)); // get parameter - __ addq(c_rarg2, wordSize); // advance to next parameter - __ decrementl(c_rarg1); // decrement counter - __ pushq(rax); // pass parameter + __ movptr(rax, Address(c_rarg2, 0));// get parameter + __ addptr(c_rarg2, wordSize); // advance to next parameter + __ decrementl(c_rarg1); // decrement counter + __ push(rax); // pass parameter __ jcc(Assembler::notZero, loop); // call Java function __ BIND(parameters_done); - __ movq(rbx, method); // get methodOop - __ movq(c_rarg1, entry_point); // get entry_point - __ movq(r13, rsp); // set sender sp + __ movptr(rbx, method); // get methodOop + __ movptr(c_rarg1, entry_point); // get entry_point + __ mov(r13, rsp); // set sender sp BLOCK_COMMENT("call Java function"); __ call(c_rarg1); @@ -301,7 +302,7 @@ class StubGenerator: public StubCodeGenerator { // store result depending on type (everything that is not // T_OBJECT, T_LONG, T_FLOAT or T_DOUBLE is treated as T_INT) - __ movq(c_rarg0, result); + __ movptr(c_rarg0, result); Label is_long, is_float, is_double, exit; __ movl(c_rarg1, result_type); __ cmpl(c_rarg1, T_OBJECT); @@ -319,16 +320,16 @@ class StubGenerator: public StubCodeGenerator { __ BIND(exit); // pop parameters - __ leaq(rsp, rsp_after_call); + __ lea(rsp, rsp_after_call); #ifdef ASSERT // verify that threads correspond { Label L, S; - __ cmpq(r15_thread, thread); + __ cmpptr(r15_thread, thread); __ jcc(Assembler::notEqual, S); __ get_thread(rbx); - __ cmpq(r15_thread, rbx); + __ cmpptr(r15_thread, rbx); __ jcc(Assembler::equal, L); __ bind(S); __ jcc(Assembler::equal, L); @@ -338,24 +339,24 @@ class StubGenerator: public StubCodeGenerator { #endif // restore regs belonging to calling function - __ movq(r15, r15_save); - __ movq(r14, r14_save); - __ movq(r13, r13_save); - __ movq(r12, r12_save); - __ movq(rbx, rbx_save); + __ movptr(r15, r15_save); + __ movptr(r14, r14_save); + __ movptr(r13, r13_save); + __ movptr(r12, r12_save); + __ movptr(rbx, rbx_save); #ifdef _WIN64 - __ movq(rdi, rdi_save); - __ movq(rsi, rsi_save); + __ movptr(rdi, rdi_save); + __ movptr(rsi, rsi_save); #else __ ldmxcsr(mxcsr_save); #endif // restore rsp - __ addq(rsp, -rsp_after_call_off * wordSize); + __ addptr(rsp, -rsp_after_call_off * wordSize); // return - __ popq(rbp); + __ pop(rbp); __ ret(0); // handle return types different from T_INT @@ -398,10 +399,10 @@ class StubGenerator: public StubCodeGenerator { // verify that threads correspond { Label L, S; - __ cmpq(r15_thread, thread); + __ cmpptr(r15_thread, thread); __ jcc(Assembler::notEqual, S); __ get_thread(rbx); - __ cmpq(r15_thread, rbx); + __ cmpptr(r15_thread, rbx); __ jcc(Assembler::equal, L); __ bind(S); __ stop("StubRoutines::catch_exception: threads must correspond"); @@ -412,9 +413,9 @@ class StubGenerator: public StubCodeGenerator { // set pending exception __ verify_oop(rax); - __ movq(Address(r15_thread, Thread::pending_exception_offset()), rax); + __ movptr(Address(r15_thread, Thread::pending_exception_offset()), rax); __ lea(rscratch1, ExternalAddress((address)__FILE__)); - __ movq(Address(r15_thread, Thread::exception_file_offset()), rscratch1); + __ movptr(Address(r15_thread, Thread::exception_file_offset()), rscratch1); __ movl(Address(r15_thread, Thread::exception_line_offset()), (int) __LINE__); // complete return to VM @@ -453,7 +454,7 @@ class StubGenerator: public StubCodeGenerator { // make sure this code is only executed if there is a pending exception { Label L; - __ cmpq(Address(r15_thread, Thread::pending_exception_offset()), (int) NULL); + __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t) NULL); __ jcc(Assembler::notEqual, L); __ stop("StubRoutines::forward exception: no pending exception (1)"); __ bind(L); @@ -461,23 +462,23 @@ class StubGenerator: public StubCodeGenerator { #endif // compute exception handler into rbx - __ movq(c_rarg0, Address(rsp, 0)); + __ movptr(c_rarg0, Address(rsp, 0)); BLOCK_COMMENT("call exception_handler_for_return_address"); __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), c_rarg0); - __ movq(rbx, rax); + __ mov(rbx, rax); // setup rax & rdx, remove return address & clear pending exception - __ popq(rdx); - __ movq(rax, Address(r15_thread, Thread::pending_exception_offset())); + __ pop(rdx); + __ movptr(rax, Address(r15_thread, Thread::pending_exception_offset())); __ movptr(Address(r15_thread, Thread::pending_exception_offset()), (int)NULL_WORD); #ifdef ASSERT // make sure exception is set { Label L; - __ testq(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::notEqual, L); __ stop("StubRoutines::forward exception: no pending exception (2)"); __ bind(L); @@ -525,8 +526,8 @@ class StubGenerator: public StubCodeGenerator { StubCodeMark mark(this, "StubRoutines", "atomic_xchg_ptr"); address start = __ pc(); - __ movq(rax, c_rarg0); // Copy to eax we need a return value anyhow - __ xchgq(rax, Address(c_rarg1, 0)); // automatic LOCK + __ movptr(rax, c_rarg0); // Copy to eax we need a return value anyhow + __ xchgptr(rax, Address(c_rarg1, 0)); // automatic LOCK __ ret(0); return start; @@ -619,10 +620,10 @@ class StubGenerator: public StubCodeGenerator { StubCodeMark mark(this, "StubRoutines", "atomic_add_ptr"); address start = __ pc(); - __ movq(rax, c_rarg0); // Copy to eax we need a return value anyhow + __ movptr(rax, c_rarg0); // Copy to eax we need a return value anyhow if ( os::is_MP() ) __ lock(); - __ xaddl(Address(c_rarg1, 0), c_rarg0); - __ addl(rax, c_rarg0); + __ xaddptr(Address(c_rarg1, 0), c_rarg0); + __ addptr(rax, c_rarg0); __ ret(0); return start; @@ -655,9 +656,9 @@ class StubGenerator: public StubCodeGenerator { address start = __ pc(); __ enter(); - __ movq(rax, old_fp); // callers fp - __ movq(rax, older_fp); // the frame for ps() - __ popq(rbp); + __ movptr(rax, old_fp); // callers fp + __ movptr(rax, older_fp); // the frame for ps() + __ pop(rbp); __ ret(0); return start; @@ -678,21 +679,21 @@ class StubGenerator: public StubCodeGenerator { if (CheckJNICalls) { Label ok_ret; - __ pushq(rax); - __ subq(rsp, wordSize); // allocate a temp location + __ push(rax); + __ subptr(rsp, wordSize); // allocate a temp location __ stmxcsr(mxcsr_save); __ movl(rax, mxcsr_save); __ andl(rax, MXCSR_MASK); // Only check control and mask bits - __ cmpl(rax, *(int *)(StubRoutines::amd64::mxcsr_std())); + __ cmpl(rax, *(int *)(StubRoutines::x86::mxcsr_std())); __ jcc(Assembler::equal, ok_ret); __ warn("MXCSR changed by native JNI code, use -XX:+RestoreMXCSROnJNICall"); - __ ldmxcsr(ExternalAddress(StubRoutines::amd64::mxcsr_std())); + __ ldmxcsr(ExternalAddress(StubRoutines::x86::mxcsr_std())); __ bind(ok_ret); - __ addq(rsp, wordSize); - __ popq(rax); + __ addptr(rsp, wordSize); + __ pop(rax); } __ ret(0); @@ -708,10 +709,10 @@ class StubGenerator: public StubCodeGenerator { Label L; - __ pushq(rax); - __ pushq(c_rarg3); - __ pushq(c_rarg2); - __ pushq(c_rarg1); + __ push(rax); + __ push(c_rarg3); + __ push(c_rarg2); + __ push(c_rarg1); __ movl(rax, 0x7f800000); __ xorl(c_rarg3, c_rarg3); @@ -726,12 +727,12 @@ class StubGenerator: public StubCodeGenerator { __ cmovl(Assembler::positive, c_rarg3, rax); __ bind(L); - __ movq(inout, c_rarg3); + __ movptr(inout, c_rarg3); - __ popq(c_rarg1); - __ popq(c_rarg2); - __ popq(c_rarg3); - __ popq(rax); + __ pop(c_rarg1); + __ pop(c_rarg2); + __ pop(c_rarg3); + __ pop(rax); __ ret(0); @@ -745,10 +746,10 @@ class StubGenerator: public StubCodeGenerator { Label L; - __ pushq(rax); - __ pushq(c_rarg3); - __ pushq(c_rarg2); - __ pushq(c_rarg1); + __ push(rax); + __ push(c_rarg3); + __ push(c_rarg2); + __ push(c_rarg1); __ movl(rax, 0x7f800000); __ xorl(c_rarg3, c_rarg3); @@ -760,15 +761,15 @@ class StubGenerator: public StubCodeGenerator { __ testl(c_rarg2, c_rarg2); // signed ? min_jlong : max_jlong __ mov64(c_rarg3, 0x8000000000000000); __ mov64(rax, 0x7fffffffffffffff); - __ cmovq(Assembler::positive, c_rarg3, rax); + __ cmov(Assembler::positive, c_rarg3, rax); __ bind(L); - __ movq(inout, c_rarg3); + __ movptr(inout, c_rarg3); - __ popq(c_rarg1); - __ popq(c_rarg2); - __ popq(c_rarg3); - __ popq(rax); + __ pop(c_rarg1); + __ pop(c_rarg2); + __ pop(c_rarg3); + __ pop(rax); __ ret(0); @@ -783,19 +784,19 @@ class StubGenerator: public StubCodeGenerator { Label L; - __ pushq(rax); - __ pushq(c_rarg3); - __ pushq(c_rarg2); - __ pushq(c_rarg1); - __ pushq(c_rarg0); + __ push(rax); + __ push(c_rarg3); + __ push(c_rarg2); + __ push(c_rarg1); + __ push(c_rarg0); __ movl(rax, 0x7ff00000); __ movq(c_rarg2, inout); __ movl(c_rarg3, c_rarg2); - __ movq(c_rarg1, c_rarg2); - __ movq(c_rarg0, c_rarg2); + __ mov(c_rarg1, c_rarg2); + __ mov(c_rarg0, c_rarg2); __ negl(c_rarg3); - __ shrq(c_rarg1, 0x20); + __ shrptr(c_rarg1, 0x20); __ orl(c_rarg3, c_rarg2); __ andl(c_rarg1, 0x7fffffff); __ xorl(c_rarg2, c_rarg2); @@ -803,19 +804,19 @@ class StubGenerator: public StubCodeGenerator { __ orl(c_rarg1, c_rarg3); __ cmpl(rax, c_rarg1); __ jcc(Assembler::negative, L); // NaN -> 0 - __ testq(c_rarg0, c_rarg0); // signed ? min_jint : max_jint + __ testptr(c_rarg0, c_rarg0); // signed ? min_jint : max_jint __ movl(c_rarg2, 0x80000000); __ movl(rax, 0x7fffffff); - __ cmovl(Assembler::positive, c_rarg2, rax); + __ cmov(Assembler::positive, c_rarg2, rax); __ bind(L); - __ movq(inout, c_rarg2); + __ movptr(inout, c_rarg2); - __ popq(c_rarg0); - __ popq(c_rarg1); - __ popq(c_rarg2); - __ popq(c_rarg3); - __ popq(rax); + __ pop(c_rarg0); + __ pop(c_rarg1); + __ pop(c_rarg2); + __ pop(c_rarg3); + __ pop(rax); __ ret(0); @@ -830,19 +831,19 @@ class StubGenerator: public StubCodeGenerator { Label L; - __ pushq(rax); - __ pushq(c_rarg3); - __ pushq(c_rarg2); - __ pushq(c_rarg1); - __ pushq(c_rarg0); + __ push(rax); + __ push(c_rarg3); + __ push(c_rarg2); + __ push(c_rarg1); + __ push(c_rarg0); __ movl(rax, 0x7ff00000); __ movq(c_rarg2, inout); __ movl(c_rarg3, c_rarg2); - __ movq(c_rarg1, c_rarg2); - __ movq(c_rarg0, c_rarg2); + __ mov(c_rarg1, c_rarg2); + __ mov(c_rarg0, c_rarg2); __ negl(c_rarg3); - __ shrq(c_rarg1, 0x20); + __ shrptr(c_rarg1, 0x20); __ orl(c_rarg3, c_rarg2); __ andl(c_rarg1, 0x7fffffff); __ xorl(c_rarg2, c_rarg2); @@ -858,11 +859,11 @@ class StubGenerator: public StubCodeGenerator { __ bind(L); __ movq(inout, c_rarg2); - __ popq(c_rarg0); - __ popq(c_rarg1); - __ popq(c_rarg2); - __ popq(c_rarg3); - __ popq(rax); + __ pop(c_rarg0); + __ pop(c_rarg1); + __ pop(c_rarg2); + __ pop(c_rarg3); + __ pop(rax); __ ret(0); @@ -889,17 +890,17 @@ class StubGenerator: public StubCodeGenerator { StubCodeMark mark(this, "StubRoutines", "handler_for_unsafe_access"); address start = __ pc(); - __ pushq(0); // hole for return address-to-be - __ pushaq(); // push registers + __ push(0); // hole for return address-to-be + __ pusha(); // push registers Address next_pc(rsp, RegisterImpl::number_of_registers * BytesPerWord); - __ subq(rsp, frame::arg_reg_save_area_bytes); + __ subptr(rsp, frame::arg_reg_save_area_bytes); BLOCK_COMMENT("call handle_unsafe_access"); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, handle_unsafe_access))); - __ addq(rsp, frame::arg_reg_save_area_bytes); + __ addptr(rsp, frame::arg_reg_save_area_bytes); - __ movq(next_pc, rax); // stuff next address - __ popaq(); + __ movptr(next_pc, rax); // stuff next address + __ popa(); __ ret(0); // jump to next address return start; @@ -926,14 +927,14 @@ class StubGenerator: public StubCodeGenerator { Label exit, error; - __ pushfq(); + __ pushf(); __ incrementl(ExternalAddress((address) StubRoutines::verify_oop_count_addr())); - __ pushq(r12); + __ push(r12); // save c_rarg2 and c_rarg3 - __ pushq(c_rarg2); - __ pushq(c_rarg3); + __ push(c_rarg2); + __ push(c_rarg3); enum { // After previous pushes. @@ -946,17 +947,17 @@ class StubGenerator: public StubCodeGenerator { }; // get object - __ movq(rax, Address(rsp, oop_to_verify)); + __ movptr(rax, Address(rsp, oop_to_verify)); // make sure object is 'reasonable' - __ testq(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, exit); // if obj is NULL it is OK // Check if the oop is in the right area of memory - __ movq(c_rarg2, rax); + __ movptr(c_rarg2, rax); __ movptr(c_rarg3, (int64_t) Universe::verify_oop_mask()); - __ andq(c_rarg2, c_rarg3); + __ andptr(c_rarg2, c_rarg3); __ movptr(c_rarg3, (int64_t) Universe::verify_oop_bits()); - __ cmpq(c_rarg2, c_rarg3); + __ cmpptr(c_rarg2, c_rarg3); __ jcc(Assembler::notZero, error); // set r12 to heapbase for load_klass() @@ -964,46 +965,46 @@ class StubGenerator: public StubCodeGenerator { // make sure klass is 'reasonable' __ load_klass(rax, rax); // get klass - __ testq(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, error); // if klass is NULL it is broken // Check if the klass is in the right area of memory - __ movq(c_rarg2, rax); + __ mov(c_rarg2, rax); __ movptr(c_rarg3, (int64_t) Universe::verify_klass_mask()); - __ andq(c_rarg2, c_rarg3); + __ andptr(c_rarg2, c_rarg3); __ movptr(c_rarg3, (int64_t) Universe::verify_klass_bits()); - __ cmpq(c_rarg2, c_rarg3); + __ cmpptr(c_rarg2, c_rarg3); __ jcc(Assembler::notZero, error); // make sure klass' klass is 'reasonable' __ load_klass(rax, rax); - __ testq(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, error); // if klass' klass is NULL it is broken // Check if the klass' klass is in the right area of memory __ movptr(c_rarg3, (int64_t) Universe::verify_klass_mask()); - __ andq(rax, c_rarg3); + __ andptr(rax, c_rarg3); __ movptr(c_rarg3, (int64_t) Universe::verify_klass_bits()); - __ cmpq(rax, c_rarg3); + __ cmpptr(rax, c_rarg3); __ jcc(Assembler::notZero, error); // return if everything seems ok __ bind(exit); - __ movq(rax, Address(rsp, saved_rax)); // get saved rax back - __ popq(c_rarg3); // restore c_rarg3 - __ popq(c_rarg2); // restore c_rarg2 - __ popq(r12); // restore r12 - __ popfq(); // restore flags + __ movptr(rax, Address(rsp, saved_rax)); // get saved rax back + __ pop(c_rarg3); // restore c_rarg3 + __ pop(c_rarg2); // restore c_rarg2 + __ pop(r12); // restore r12 + __ popf(); // restore flags __ ret(3 * wordSize); // pop caller saved stuff // handle errors __ bind(error); - __ movq(rax, Address(rsp, saved_rax)); // get saved rax back - __ popq(c_rarg3); // get saved c_rarg3 back - __ popq(c_rarg2); // get saved c_rarg2 back - __ popq(r12); // get saved r12 back - __ popfq(); // get saved flags off stack -- + __ movptr(rax, Address(rsp, saved_rax)); // get saved rax back + __ pop(c_rarg3); // get saved c_rarg3 back + __ pop(c_rarg2); // get saved c_rarg2 back + __ pop(r12); // get saved r12 back + __ popf(); // get saved flags off stack -- // will be ignored - __ pushaq(); // push registers + __ pusha(); // push registers // (rip is already // already pushed) // debug(char* msg, int64_t pc, int64_t regs[]) @@ -1016,17 +1017,17 @@ class StubGenerator: public StubCodeGenerator { // * [tos + 19] saved rax - saved by caller and bashed // * = popped on exit - __ movq(c_rarg0, Address(rsp, error_msg)); // pass address of error message - __ movq(c_rarg1, Address(rsp, return_addr)); // pass return address - __ movq(c_rarg2, rsp); // pass address of regs on stack - __ movq(r12, rsp); // remember rsp - __ subq(rsp, frame::arg_reg_save_area_bytes);// windows - __ andq(rsp, -16); // align stack as required by ABI + __ movptr(c_rarg0, Address(rsp, error_msg)); // pass address of error message + __ movptr(c_rarg1, Address(rsp, return_addr)); // pass return address + __ movq(c_rarg2, rsp); // pass address of regs on stack + __ mov(r12, rsp); // remember rsp + __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows + __ andptr(rsp, -16); // align stack as required by ABI BLOCK_COMMENT("call MacroAssembler::debug"); - __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug))); - __ movq(rsp, r12); // restore rsp - __ popaq(); // pop registers (includes r12) - __ ret(3 * wordSize); // pop caller saved stuff + __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug64))); + __ mov(rsp, r12); // restore rsp + __ popa(); // pop registers (includes r12) + __ ret(3 * wordSize); // pop caller saved stuff return start; } @@ -1088,16 +1089,16 @@ class StubGenerator: public StubCodeGenerator { const Register count = c_rarg2; const Register end_from = rax; - __ cmpq(to, from); - __ leaq(end_from, Address(from, count, sf, 0)); + __ cmpptr(to, from); + __ lea(end_from, Address(from, count, sf, 0)); if (NOLp == NULL) { ExternalAddress no_overlap(no_overlap_target); __ jump_cc(Assembler::belowEqual, no_overlap); - __ cmpq(to, end_from); + __ cmpptr(to, end_from); __ jump_cc(Assembler::aboveEqual, no_overlap); } else { __ jcc(Assembler::belowEqual, (*NOLp)); - __ cmpq(to, end_from); + __ cmpptr(to, end_from); __ jcc(Assembler::aboveEqual, (*NOLp)); } } @@ -1121,14 +1122,14 @@ class StubGenerator: public StubCodeGenerator { assert(c_rarg0 == rcx && c_rarg1 == rdx && c_rarg2 == r8 && c_rarg3 == r9, "unexpected argument registers"); if (nargs >= 4) - __ movq(rax, r9); // r9 is also saved_rdi - __ movq(saved_rdi, rdi); - __ movq(saved_rsi, rsi); - __ movq(rdi, rcx); // c_rarg0 - __ movq(rsi, rdx); // c_rarg1 - __ movq(rdx, r8); // c_rarg2 + __ mov(rax, r9); // r9 is also saved_rdi + __ movptr(saved_rdi, rdi); + __ movptr(saved_rsi, rsi); + __ mov(rdi, rcx); // c_rarg0 + __ mov(rsi, rdx); // c_rarg1 + __ mov(rdx, r8); // c_rarg2 if (nargs >= 4) - __ movq(rcx, rax); // c_rarg3 (via rax) + __ mov(rcx, rax); // c_rarg3 (via rax) #else assert(c_rarg0 == rdi && c_rarg1 == rsi && c_rarg2 == rdx && c_rarg3 == rcx, "unexpected argument registers"); @@ -1139,8 +1140,8 @@ class StubGenerator: public StubCodeGenerator { const Register saved_rdi = r9; const Register saved_rsi = r10; #ifdef _WIN64 - __ movq(rdi, saved_rdi); - __ movq(rsi, saved_rsi); + __ movptr(rdi, saved_rdi); + __ movptr(rsi, saved_rsi); #endif } @@ -1160,11 +1161,11 @@ class StubGenerator: public StubCodeGenerator { case BarrierSet::G1SATBCT: case BarrierSet::G1SATBCTLogging: { - __ pushaq(); // push registers - __ movq(c_rarg0, addr); - __ movq(c_rarg1, count); + __ pusha(); // push registers + __ movptr(c_rarg0, addr); + __ movptr(c_rarg1, count); __ call(RuntimeAddress(BarrierSet::static_write_ref_array_pre)); - __ popaq(); + __ popa(); } break; case BarrierSet::CardTableModRef: @@ -1197,16 +1198,16 @@ class StubGenerator: public StubCodeGenerator { case BarrierSet::G1SATBCTLogging: { - __ pushaq(); // push registers (overkill) + __ pusha(); // push registers (overkill) // must compute element count unless barrier set interface is changed (other platforms supply count) assert_different_registers(start, end, scratch); - __ leaq(scratch, Address(end, wordSize)); - __ subq(scratch, start); - __ shrq(scratch, LogBytesPerWord); - __ movq(c_rarg0, start); - __ movq(c_rarg1, scratch); + __ lea(scratch, Address(end, wordSize)); + __ subptr(scratch, start); + __ shrptr(scratch, LogBytesPerWord); + __ mov(c_rarg0, start); + __ mov(c_rarg1, scratch); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post)); - __ popaq(); + __ popa(); } break; #endif // 0 G1 - only @@ -1218,9 +1219,9 @@ class StubGenerator: public StubCodeGenerator { Label L_loop; - __ shrq(start, CardTableModRefBS::card_shift); - __ shrq(end, CardTableModRefBS::card_shift); - __ subq(end, start); // number of bytes to copy + __ shrptr(start, CardTableModRefBS::card_shift); + __ shrptr(end, CardTableModRefBS::card_shift); + __ subptr(end, start); // number of bytes to copy intptr_t disp = (intptr_t) ct->byte_map_base; if (__ is_simm32(disp)) { @@ -1232,10 +1233,10 @@ class StubGenerator: public StubCodeGenerator { } const Register count = end; // 'end' register contains bytes count now - __ addq(start, scratch); + __ addptr(start, scratch); __ BIND(L_loop); __ movb(Address(start, count, Address::times_1), 0); - __ decrementq(count); + __ decrement(count); __ jcc(Assembler::greaterEqual, L_loop); } } @@ -1267,9 +1268,9 @@ class StubGenerator: public StubCodeGenerator { __ movq(to, Address(end_from, qword_count, Address::times_8, - 0)); __ movq(Address(end_to, qword_count, Address::times_8, - 0), to); __ BIND(L_copy_32_bytes); - __ addq(qword_count, 4); + __ addptr(qword_count, 4); __ jcc(Assembler::lessEqual, L_loop); - __ subq(qword_count, 4); + __ subptr(qword_count, 4); __ jcc(Assembler::less, L_copy_8_bytes); // Copy trailing qwords } @@ -1300,9 +1301,9 @@ class StubGenerator: public StubCodeGenerator { __ movq(to, Address(from, qword_count, Address::times_8, 0)); __ movq(Address(dest, qword_count, Address::times_8, 0), to); __ BIND(L_copy_32_bytes); - __ subq(qword_count, 4); + __ subptr(qword_count, 4); __ jcc(Assembler::greaterEqual, L_loop); - __ addq(qword_count, 4); + __ addptr(qword_count, 4); __ jcc(Assembler::greater, L_copy_8_bytes); // Copy trailing qwords } @@ -1354,45 +1355,45 @@ class StubGenerator: public StubCodeGenerator { // r9 and r10 may be used to save non-volatile registers // 'from', 'to' and 'count' are now valid - __ movq(byte_count, count); - __ shrq(count, 3); // count => qword_count + __ movptr(byte_count, count); + __ shrptr(count, 3); // count => qword_count // Copy from low to high addresses. Use 'to' as scratch. - __ leaq(end_from, Address(from, qword_count, Address::times_8, -8)); - __ leaq(end_to, Address(to, qword_count, Address::times_8, -8)); - __ negq(qword_count); // make the count negative + __ lea(end_from, Address(from, qword_count, Address::times_8, -8)); + __ lea(end_to, Address(to, qword_count, Address::times_8, -8)); + __ negptr(qword_count); // make the count negative __ jmp(L_copy_32_bytes); // Copy trailing qwords __ BIND(L_copy_8_bytes); __ movq(rax, Address(end_from, qword_count, Address::times_8, 8)); __ movq(Address(end_to, qword_count, Address::times_8, 8), rax); - __ incrementq(qword_count); + __ increment(qword_count); __ jcc(Assembler::notZero, L_copy_8_bytes); // Check for and copy trailing dword __ BIND(L_copy_4_bytes); - __ testq(byte_count, 4); + __ testl(byte_count, 4); __ jccb(Assembler::zero, L_copy_2_bytes); __ movl(rax, Address(end_from, 8)); __ movl(Address(end_to, 8), rax); - __ addq(end_from, 4); - __ addq(end_to, 4); + __ addptr(end_from, 4); + __ addptr(end_to, 4); // Check for and copy trailing word __ BIND(L_copy_2_bytes); - __ testq(byte_count, 2); + __ testl(byte_count, 2); __ jccb(Assembler::zero, L_copy_byte); __ movw(rax, Address(end_from, 8)); __ movw(Address(end_to, 8), rax); - __ addq(end_from, 2); - __ addq(end_to, 2); + __ addptr(end_from, 2); + __ addptr(end_to, 2); // Check for and copy trailing byte __ BIND(L_copy_byte); - __ testq(byte_count, 1); + __ testl(byte_count, 1); __ jccb(Assembler::zero, L_exit); __ movb(rax, Address(end_from, 8)); __ movb(Address(end_to, 8), rax); @@ -1400,7 +1401,7 @@ class StubGenerator: public StubCodeGenerator { __ BIND(L_exit); inc_counter_np(SharedRuntime::_jbyte_array_copy_ctr); restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -1450,28 +1451,28 @@ class StubGenerator: public StubCodeGenerator { // r9 and r10 may be used to save non-volatile registers // 'from', 'to' and 'count' are now valid - __ movq(byte_count, count); - __ shrq(count, 3); // count => qword_count + __ movptr(byte_count, count); + __ shrptr(count, 3); // count => qword_count // Copy from high to low addresses. // Check for and copy trailing byte - __ testq(byte_count, 1); + __ testl(byte_count, 1); __ jcc(Assembler::zero, L_copy_2_bytes); __ movb(rax, Address(from, byte_count, Address::times_1, -1)); __ movb(Address(to, byte_count, Address::times_1, -1), rax); - __ decrementq(byte_count); // Adjust for possible trailing word + __ decrement(byte_count); // Adjust for possible trailing word // Check for and copy trailing word __ BIND(L_copy_2_bytes); - __ testq(byte_count, 2); + __ testl(byte_count, 2); __ jcc(Assembler::zero, L_copy_4_bytes); __ movw(rax, Address(from, byte_count, Address::times_1, -2)); __ movw(Address(to, byte_count, Address::times_1, -2), rax); // Check for and copy trailing dword __ BIND(L_copy_4_bytes); - __ testq(byte_count, 4); + __ testl(byte_count, 4); __ jcc(Assembler::zero, L_copy_32_bytes); __ movl(rax, Address(from, qword_count, Address::times_8)); __ movl(Address(to, qword_count, Address::times_8), rax); @@ -1481,12 +1482,12 @@ class StubGenerator: public StubCodeGenerator { __ BIND(L_copy_8_bytes); __ movq(rax, Address(from, qword_count, Address::times_8, -8)); __ movq(Address(to, qword_count, Address::times_8, -8), rax); - __ decrementq(qword_count); + __ decrement(qword_count); __ jcc(Assembler::notZero, L_copy_8_bytes); inc_counter_np(SharedRuntime::_jbyte_array_copy_ctr); restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -1495,7 +1496,7 @@ class StubGenerator: public StubCodeGenerator { inc_counter_np(SharedRuntime::_jbyte_array_copy_ctr); restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -1548,20 +1549,20 @@ class StubGenerator: public StubCodeGenerator { // r9 and r10 may be used to save non-volatile registers // 'from', 'to' and 'count' are now valid - __ movq(word_count, count); - __ shrq(count, 2); // count => qword_count + __ movptr(word_count, count); + __ shrptr(count, 2); // count => qword_count // Copy from low to high addresses. Use 'to' as scratch. - __ leaq(end_from, Address(from, qword_count, Address::times_8, -8)); - __ leaq(end_to, Address(to, qword_count, Address::times_8, -8)); - __ negq(qword_count); + __ lea(end_from, Address(from, qword_count, Address::times_8, -8)); + __ lea(end_to, Address(to, qword_count, Address::times_8, -8)); + __ negptr(qword_count); __ jmp(L_copy_32_bytes); // Copy trailing qwords __ BIND(L_copy_8_bytes); __ movq(rax, Address(end_from, qword_count, Address::times_8, 8)); __ movq(Address(end_to, qword_count, Address::times_8, 8), rax); - __ incrementq(qword_count); + __ increment(qword_count); __ jcc(Assembler::notZero, L_copy_8_bytes); // Original 'dest' is trashed, so we can't use it as a @@ -1569,17 +1570,17 @@ class StubGenerator: public StubCodeGenerator { // Check for and copy trailing dword __ BIND(L_copy_4_bytes); - __ testq(word_count, 2); + __ testl(word_count, 2); __ jccb(Assembler::zero, L_copy_2_bytes); __ movl(rax, Address(end_from, 8)); __ movl(Address(end_to, 8), rax); - __ addq(end_from, 4); - __ addq(end_to, 4); + __ addptr(end_from, 4); + __ addptr(end_to, 4); // Check for and copy trailing word __ BIND(L_copy_2_bytes); - __ testq(word_count, 1); + __ testl(word_count, 1); __ jccb(Assembler::zero, L_exit); __ movw(rax, Address(end_from, 8)); __ movw(Address(end_to, 8), rax); @@ -1587,7 +1588,7 @@ class StubGenerator: public StubCodeGenerator { __ BIND(L_exit); inc_counter_np(SharedRuntime::_jshort_array_copy_ctr); restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -1637,20 +1638,20 @@ class StubGenerator: public StubCodeGenerator { // r9 and r10 may be used to save non-volatile registers // 'from', 'to' and 'count' are now valid - __ movq(word_count, count); - __ shrq(count, 2); // count => qword_count + __ movptr(word_count, count); + __ shrptr(count, 2); // count => qword_count // Copy from high to low addresses. Use 'to' as scratch. // Check for and copy trailing word - __ testq(word_count, 1); + __ testl(word_count, 1); __ jccb(Assembler::zero, L_copy_4_bytes); __ movw(rax, Address(from, word_count, Address::times_2, -2)); __ movw(Address(to, word_count, Address::times_2, -2), rax); // Check for and copy trailing dword __ BIND(L_copy_4_bytes); - __ testq(word_count, 2); + __ testl(word_count, 2); __ jcc(Assembler::zero, L_copy_32_bytes); __ movl(rax, Address(from, qword_count, Address::times_8)); __ movl(Address(to, qword_count, Address::times_8), rax); @@ -1660,12 +1661,12 @@ class StubGenerator: public StubCodeGenerator { __ BIND(L_copy_8_bytes); __ movq(rax, Address(from, qword_count, Address::times_8, -8)); __ movq(Address(to, qword_count, Address::times_8, -8), rax); - __ decrementq(qword_count); + __ decrement(qword_count); __ jcc(Assembler::notZero, L_copy_8_bytes); inc_counter_np(SharedRuntime::_jshort_array_copy_ctr); restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -1674,7 +1675,7 @@ class StubGenerator: public StubCodeGenerator { inc_counter_np(SharedRuntime::_jshort_array_copy_ctr); restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -1738,25 +1739,25 @@ class StubGenerator: public StubCodeGenerator { } // 'from', 'to' and 'count' are now valid - __ movq(dword_count, count); - __ shrq(count, 1); // count => qword_count + __ movptr(dword_count, count); + __ shrptr(count, 1); // count => qword_count // Copy from low to high addresses. Use 'to' as scratch. - __ leaq(end_from, Address(from, qword_count, Address::times_8, -8)); - __ leaq(end_to, Address(to, qword_count, Address::times_8, -8)); - __ negq(qword_count); + __ lea(end_from, Address(from, qword_count, Address::times_8, -8)); + __ lea(end_to, Address(to, qword_count, Address::times_8, -8)); + __ negptr(qword_count); __ jmp(L_copy_32_bytes); // Copy trailing qwords __ BIND(L_copy_8_bytes); __ movq(rax, Address(end_from, qword_count, Address::times_8, 8)); __ movq(Address(end_to, qword_count, Address::times_8, 8), rax); - __ incrementq(qword_count); + __ increment(qword_count); __ jcc(Assembler::notZero, L_copy_8_bytes); // Check for and copy trailing dword __ BIND(L_copy_4_bytes); - __ testq(dword_count, 1); // Only byte test since the value is 0 or 1 + __ testl(dword_count, 1); // Only byte test since the value is 0 or 1 __ jccb(Assembler::zero, L_exit); __ movl(rax, Address(end_from, 8)); __ movl(Address(end_to, 8), rax); @@ -1768,7 +1769,7 @@ class StubGenerator: public StubCodeGenerator { } inc_counter_np(SharedRuntime::_jint_array_copy_ctr); restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -1825,13 +1826,13 @@ class StubGenerator: public StubCodeGenerator { assert_clean_int(count, rax); // Make sure 'count' is clean int. // 'from', 'to' and 'count' are now valid - __ movq(dword_count, count); - __ shrq(count, 1); // count => qword_count + __ movptr(dword_count, count); + __ shrptr(count, 1); // count => qword_count // Copy from high to low addresses. Use 'to' as scratch. // Check for and copy trailing dword - __ testq(dword_count, 1); + __ testl(dword_count, 1); __ jcc(Assembler::zero, L_copy_32_bytes); __ movl(rax, Address(from, dword_count, Address::times_4, -4)); __ movl(Address(to, dword_count, Address::times_4, -4), rax); @@ -1841,7 +1842,7 @@ class StubGenerator: public StubCodeGenerator { __ BIND(L_copy_8_bytes); __ movq(rax, Address(from, qword_count, Address::times_8, -8)); __ movq(Address(to, qword_count, Address::times_8, -8), rax); - __ decrementq(qword_count); + __ decrement(qword_count); __ jcc(Assembler::notZero, L_copy_8_bytes); inc_counter_np(SharedRuntime::_jint_array_copy_ctr); @@ -1849,7 +1850,7 @@ class StubGenerator: public StubCodeGenerator { __ jmp(L_exit); } restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -1864,7 +1865,7 @@ class StubGenerator: public StubCodeGenerator { gen_write_ref_array_post_barrier(to, end_to, rax); } restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -1921,16 +1922,16 @@ class StubGenerator: public StubCodeGenerator { // 'from', 'to' and 'qword_count' are now valid // Copy from low to high addresses. Use 'to' as scratch. - __ leaq(end_from, Address(from, qword_count, Address::times_8, -8)); - __ leaq(end_to, Address(to, qword_count, Address::times_8, -8)); - __ negq(qword_count); + __ lea(end_from, Address(from, qword_count, Address::times_8, -8)); + __ lea(end_to, Address(to, qword_count, Address::times_8, -8)); + __ negptr(qword_count); __ jmp(L_copy_32_bytes); // Copy trailing qwords __ BIND(L_copy_8_bytes); __ movq(rax, Address(end_from, qword_count, Address::times_8, 8)); __ movq(Address(end_to, qword_count, Address::times_8, 8), rax); - __ incrementq(qword_count); + __ increment(qword_count); __ jcc(Assembler::notZero, L_copy_8_bytes); if (is_oop) { @@ -1938,7 +1939,7 @@ class StubGenerator: public StubCodeGenerator { } else { inc_counter_np(SharedRuntime::_jlong_array_copy_ctr); restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); } @@ -1954,7 +1955,7 @@ class StubGenerator: public StubCodeGenerator { inc_counter_np(SharedRuntime::_jlong_array_copy_ctr); } restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -2008,7 +2009,7 @@ class StubGenerator: public StubCodeGenerator { if (is_oop) { // Save to and count for store barrier - __ movq(saved_count, qword_count); + __ movptr(saved_count, qword_count); // No registers are destroyed by this call gen_write_ref_array_pre_barrier(to, saved_count); } @@ -2019,7 +2020,7 @@ class StubGenerator: public StubCodeGenerator { __ BIND(L_copy_8_bytes); __ movq(rax, Address(from, qword_count, Address::times_8, -8)); __ movq(Address(to, qword_count, Address::times_8, -8), rax); - __ decrementq(qword_count); + __ decrement(qword_count); __ jcc(Assembler::notZero, L_copy_8_bytes); if (is_oop) { @@ -2027,7 +2028,7 @@ class StubGenerator: public StubCodeGenerator { } else { inc_counter_np(SharedRuntime::_jlong_array_copy_ctr); restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); } @@ -2037,14 +2038,14 @@ class StubGenerator: public StubCodeGenerator { if (is_oop) { __ BIND(L_exit); - __ leaq(rcx, Address(to, saved_count, Address::times_8, -8)); + __ lea(rcx, Address(to, saved_count, Address::times_8, -8)); gen_write_ref_array_post_barrier(to, rcx, rax); inc_counter_np(SharedRuntime::_oop_array_copy_ctr); } else { inc_counter_np(SharedRuntime::_jlong_array_copy_ctr); } restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -2073,12 +2074,12 @@ class StubGenerator: public StubCodeGenerator { Address super_cache_addr( sub_klass, sc_offset); // if the pointers are equal, we are done (e.g., String[] elements) - __ cmpq(super_klass, sub_klass); + __ cmpptr(super_klass, sub_klass); __ jcc(Assembler::equal, L_success); // check the supertype display: Address super_check_addr(sub_klass, super_check_offset, Address::times_1, 0); - __ cmpq(super_klass, super_check_addr); // test the super type + __ cmpptr(super_klass, super_check_addr); // test the super type __ jcc(Assembler::equal, L_success); // if it was a primary super, we can just fail immediately @@ -2091,38 +2092,38 @@ class StubGenerator: public StubCodeGenerator { // This code is rarely used, so simplicity is a virtue here. inc_counter_np(SharedRuntime::_partial_subtype_ctr); { - __ pushq(rax); - __ pushq(rcx); - __ pushq(rdi); + __ push(rax); + __ push(rcx); + __ push(rdi); assert_different_registers(sub_klass, super_klass, rax, rcx, rdi); - __ movq(rdi, secondary_supers_addr); + __ movptr(rdi, secondary_supers_addr); // Load the array length. __ movl(rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes())); // Skip to start of data. - __ addq(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + __ addptr(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); // Scan rcx words at [rdi] for occurance of rax // Set NZ/Z based on last compare - __ movq(rax, super_klass); + __ movptr(rax, super_klass); if (UseCompressedOops) { // Compare against compressed form. Don't need to uncompress because // looks like orig rax is restored in popq below. __ encode_heap_oop(rax); __ repne_scanl(); } else { - __ repne_scanq(); + __ repne_scan(); } // Unspill the temp. registers: - __ popq(rdi); - __ popq(rcx); - __ popq(rax); + __ pop(rdi); + __ pop(rcx); + __ pop(rax); __ jcc(Assembler::notEqual, L_miss); } // Success. Cache the super we found and proceed in triumph. - __ movq(super_cache_addr, super_klass); // note: rax is dead + __ movptr(super_cache_addr, super_klass); // note: rax is dead __ jmp(L_success); // Fall through on failure! @@ -2202,16 +2203,16 @@ class StubGenerator: public StubCodeGenerator { saved_rip_offset, saved_rarg0_offset }; - __ subq(rsp, saved_rbp_offset * wordSize); - __ movq(Address(rsp, saved_r13_offset * wordSize), r13); - __ movq(Address(rsp, saved_r14_offset * wordSize), r14); + __ subptr(rsp, saved_rbp_offset * wordSize); + __ movptr(Address(rsp, saved_r13_offset * wordSize), r13); + __ movptr(Address(rsp, saved_r14_offset * wordSize), r14); setup_arg_regs(4); // from => rdi, to => rsi, length => rdx // ckoff => rcx, ckval => r8 // r9 and r10 may be used to save non-volatile registers #ifdef _WIN64 // last argument (#4) is on stack on Win64 const int ckval_offset = saved_rarg0_offset + 4; - __ movq(ckval, Address(rsp, ckval_offset * wordSize)); + __ movptr(ckval, Address(rsp, ckval_offset * wordSize)); #endif // check that int operands are properly extended to size_t @@ -2242,15 +2243,15 @@ class StubGenerator: public StubCodeGenerator { gen_write_ref_array_pre_barrier(to, count); // Copy from low to high addresses, indexed from the end of each array. - __ leaq(end_from, end_from_addr); - __ leaq(end_to, end_to_addr); - __ movq(r14_length, length); // save a copy of the length - assert(length == count, ""); // else fix next line: - __ negq(count); // negate and test the length + __ lea(end_from, end_from_addr); + __ lea(end_to, end_to_addr); + __ movptr(r14_length, length); // save a copy of the length + assert(length == count, ""); // else fix next line: + __ negptr(count); // negate and test the length __ jcc(Assembler::notZero, L_load_element); // Empty array: Nothing to do. - __ xorq(rax, rax); // return 0 on (trivial) success + __ xorptr(rax, rax); // return 0 on (trivial) success __ jmp(L_done); // ======== begin loop ======== @@ -2262,13 +2263,13 @@ class StubGenerator: public StubCodeGenerator { __ BIND(L_store_element); __ store_heap_oop(to_element_addr, rax_oop); // store the oop - __ incrementq(count); // increment the count toward zero + __ increment(count); // increment the count toward zero __ jcc(Assembler::zero, L_do_card_marks); // ======== loop entry is here ======== __ BIND(L_load_element); __ load_heap_oop(rax_oop, from_element_addr); // load the oop - __ testq(rax_oop, rax_oop); + __ testptr(rax_oop, rax_oop); __ jcc(Assembler::zero, L_store_element); __ load_klass(r11_klass, rax_oop);// query the object klass @@ -2280,23 +2281,23 @@ class StubGenerator: public StubCodeGenerator { // Emit GC store barriers for the oops we have copied (r14 + rdx), // and report their number to the caller. assert_different_registers(rax, r14_length, count, to, end_to, rcx); - __ leaq(end_to, to_element_addr); + __ lea(end_to, to_element_addr); gen_write_ref_array_post_barrier(to, end_to, rcx); - __ movq(rax, r14_length); // original oops - __ addq(rax, count); // K = (original - remaining) oops - __ notq(rax); // report (-1^K) to caller + __ movptr(rax, r14_length); // original oops + __ addptr(rax, count); // K = (original - remaining) oops + __ notptr(rax); // report (-1^K) to caller __ jmp(L_done); // Come here on success only. __ BIND(L_do_card_marks); - __ addq(end_to, -wordSize); // make an inclusive end pointer + __ addptr(end_to, -wordSize); // make an inclusive end pointer gen_write_ref_array_post_barrier(to, end_to, rcx); - __ xorq(rax, rax); // return 0 on success + __ xorptr(rax, rax); // return 0 on success // Common exit point (success or failure). __ BIND(L_done); - __ movq(r13, Address(rsp, saved_r13_offset * wordSize)); - __ movq(r14, Address(rsp, saved_r14_offset * wordSize)); + __ movptr(r13, Address(rsp, saved_r13_offset * wordSize)); + __ movptr(r14, Address(rsp, saved_r14_offset * wordSize)); inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr); restore_arg_regs(); __ leave(); // required for proper stackwalking of RuntimeStub frame @@ -2339,9 +2340,9 @@ class StubGenerator: public StubCodeGenerator { // bump this on entry, not on exit: inc_counter_np(SharedRuntime::_unsafe_array_copy_ctr); - __ movq(bits, from); - __ orq(bits, to); - __ orq(bits, size); + __ mov(bits, from); + __ orptr(bits, to); + __ orptr(bits, size); __ testb(bits, BytesPerLong-1); __ jccb(Assembler::zero, L_long_aligned); @@ -2353,15 +2354,15 @@ class StubGenerator: public StubCodeGenerator { __ jump_cc(Assembler::notZero, RuntimeAddress(byte_copy_entry)); __ BIND(L_short_aligned); - __ shrq(size, LogBytesPerShort); // size => short_count + __ shrptr(size, LogBytesPerShort); // size => short_count __ jump(RuntimeAddress(short_copy_entry)); __ BIND(L_int_aligned); - __ shrq(size, LogBytesPerInt); // size => int_count + __ shrptr(size, LogBytesPerInt); // size => int_count __ jump(RuntimeAddress(int_copy_entry)); __ BIND(L_long_aligned); - __ shrq(size, LogBytesPerLong); // size => qword_count + __ shrptr(size, LogBytesPerLong); // size => qword_count __ jump(RuntimeAddress(long_copy_entry)); return start; @@ -2469,7 +2470,7 @@ class StubGenerator: public StubCodeGenerator { // // if (src == NULL) return -1; - __ testq(src, src); // src oop + __ testptr(src, src); // src oop size_t j1off = __ offset(); __ jccb(Assembler::zero, L_failed_0); @@ -2478,7 +2479,7 @@ class StubGenerator: public StubCodeGenerator { __ jccb(Assembler::negative, L_failed_0); // if (dst == NULL) return -1; - __ testq(dst, dst); // dst oop + __ testptr(dst, dst); // dst oop __ jccb(Assembler::zero, L_failed_0); // if (dst_pos < 0) return -1; @@ -2509,7 +2510,7 @@ class StubGenerator: public StubCodeGenerator { // assert(src->klass() != NULL); BLOCK_COMMENT("assert klasses not null"); { Label L1, L2; - __ testq(r10_src_klass, r10_src_klass); + __ testptr(r10_src_klass, r10_src_klass); __ jcc(Assembler::notZero, L2); // it is broken if klass is NULL __ bind(L1); __ stop("broken null klass"); @@ -2574,9 +2575,9 @@ class StubGenerator: public StubCodeGenerator { __ movl(r10_offset, rax_lh); __ shrl(r10_offset, Klass::_lh_header_size_shift); - __ andq(r10_offset, Klass::_lh_header_size_mask); // array_offset - __ addq(src, r10_offset); // src array offset - __ addq(dst, r10_offset); // dst array offset + __ andptr(r10_offset, Klass::_lh_header_size_mask); // array_offset + __ addptr(src, r10_offset); // src array offset + __ addptr(dst, r10_offset); // dst array offset BLOCK_COMMENT("choose copy loop based on element size"); __ andl(rax_lh, Klass::_lh_log2_element_size_mask); // rax_lh -> rax_elsize @@ -2591,25 +2592,25 @@ class StubGenerator: public StubCodeGenerator { __ BIND(L_copy_bytes); __ cmpl(rax_elsize, 0); __ jccb(Assembler::notEqual, L_copy_shorts); - __ leaq(from, Address(src, src_pos, Address::times_1, 0));// src_addr - __ leaq(to, Address(dst, dst_pos, Address::times_1, 0));// dst_addr - __ movslq(count, r11_length); // length + __ lea(from, Address(src, src_pos, Address::times_1, 0));// src_addr + __ lea(to, Address(dst, dst_pos, Address::times_1, 0));// dst_addr + __ movl2ptr(count, r11_length); // length __ jump(RuntimeAddress(byte_copy_entry)); __ BIND(L_copy_shorts); __ cmpl(rax_elsize, LogBytesPerShort); __ jccb(Assembler::notEqual, L_copy_ints); - __ leaq(from, Address(src, src_pos, Address::times_2, 0));// src_addr - __ leaq(to, Address(dst, dst_pos, Address::times_2, 0));// dst_addr - __ movslq(count, r11_length); // length + __ lea(from, Address(src, src_pos, Address::times_2, 0));// src_addr + __ lea(to, Address(dst, dst_pos, Address::times_2, 0));// dst_addr + __ movl2ptr(count, r11_length); // length __ jump(RuntimeAddress(short_copy_entry)); __ BIND(L_copy_ints); __ cmpl(rax_elsize, LogBytesPerInt); __ jccb(Assembler::notEqual, L_copy_longs); - __ leaq(from, Address(src, src_pos, Address::times_4, 0));// src_addr - __ leaq(to, Address(dst, dst_pos, Address::times_4, 0));// dst_addr - __ movslq(count, r11_length); // length + __ lea(from, Address(src, src_pos, Address::times_4, 0));// src_addr + __ lea(to, Address(dst, dst_pos, Address::times_4, 0));// dst_addr + __ movl2ptr(count, r11_length); // length __ jump(RuntimeAddress(int_copy_entry)); __ BIND(L_copy_longs); @@ -2621,9 +2622,9 @@ class StubGenerator: public StubCodeGenerator { __ bind(L); } #endif - __ leaq(from, Address(src, src_pos, Address::times_8, 0));// src_addr - __ leaq(to, Address(dst, dst_pos, Address::times_8, 0));// dst_addr - __ movslq(count, r11_length); // length + __ lea(from, Address(src, src_pos, Address::times_8, 0));// src_addr + __ lea(to, Address(dst, dst_pos, Address::times_8, 0));// dst_addr + __ movl2ptr(count, r11_length); // length __ jump(RuntimeAddress(long_copy_entry)); // objArrayKlass @@ -2640,11 +2641,11 @@ class StubGenerator: public StubCodeGenerator { arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length, r10, L_failed); - __ leaq(from, Address(src, src_pos, TIMES_OOP, + __ lea(from, Address(src, src_pos, TIMES_OOP, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr - __ leaq(to, Address(dst, dst_pos, TIMES_OOP, - arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr - __ movslq(count, r11_length); // length + __ lea(to, Address(dst, dst_pos, TIMES_OOP, + arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr + __ movl2ptr(count, r11_length); // length __ BIND(L_plain_copy); __ jump(RuntimeAddress(oop_copy_entry)); @@ -2671,9 +2672,9 @@ class StubGenerator: public StubCodeGenerator { #endif // Marshal the base address arguments now, freeing registers. - __ leaq(from, Address(src, src_pos, TIMES_OOP, + __ lea(from, Address(src, src_pos, TIMES_OOP, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); - __ leaq(to, Address(dst, dst_pos, TIMES_OOP, + __ lea(to, Address(dst, dst_pos, TIMES_OOP, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); __ movl(count, C_RARG4); // length (reloaded) Register sco_temp = c_rarg3; // this register is free now @@ -2691,19 +2692,19 @@ class StubGenerator: public StubCodeGenerator { // Fetch destination element klass from the objArrayKlass header. int ek_offset = (klassOopDesc::header_size() * HeapWordSize + objArrayKlass::element_klass_offset_in_bytes()); - __ movq(r11_dst_klass, Address(r11_dst_klass, ek_offset)); + __ movptr(r11_dst_klass, Address(r11_dst_klass, ek_offset)); __ movl(sco_temp, Address(r11_dst_klass, sco_offset)); assert_clean_int(sco_temp, rax); // the checkcast_copy loop needs two extra arguments: assert(c_rarg3 == sco_temp, "#3 already in place"); - __ movq(C_RARG4, r11_dst_klass); // dst.klass.element_klass + __ movptr(C_RARG4, r11_dst_klass); // dst.klass.element_klass __ jump(RuntimeAddress(checkcast_copy_entry)); } __ BIND(L_failed); - __ xorq(rax, rax); - __ notq(rax); // return -1 + __ xorptr(rax, rax); + __ notptr(rax); // return -1 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -2806,10 +2807,10 @@ class StubGenerator: public StubCodeGenerator { // thread-local storage and also sets up last_Java_sp slightly // differently than the real call_VM if (restore_saved_exception_pc) { - __ movq(rax, - Address(r15_thread, - in_bytes(JavaThread::saved_exception_pc_offset()))); - __ pushq(rax); + __ movptr(rax, + Address(r15_thread, + in_bytes(JavaThread::saved_exception_pc_offset()))); + __ push(rax); } __ enter(); // required for proper stackwalking of RuntimeStub frame @@ -2817,7 +2818,7 @@ class StubGenerator: public StubCodeGenerator { assert(is_even(framesize/2), "sp not 16-byte aligned"); // return address and rbp are already in place - __ subq(rsp, (framesize-4) << LogBytesPerInt); // prolog + __ subptr(rsp, (framesize-4) << LogBytesPerInt); // prolog int frame_complete = __ pc() - start; @@ -2825,7 +2826,7 @@ class StubGenerator: public StubCodeGenerator { __ set_last_Java_frame(rsp, rbp, NULL); // Call runtime - __ movq(c_rarg0, r15_thread); + __ movptr(c_rarg0, r15_thread); BLOCK_COMMENT("call runtime_entry"); __ call(RuntimeAddress(runtime_entry)); @@ -2841,8 +2842,8 @@ class StubGenerator: public StubCodeGenerator { // check for pending exceptions #ifdef ASSERT Label L; - __ cmpq(Address(r15_thread, Thread::pending_exception_offset()), - (int) NULL); + __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), + (int32_t) NULL_WORD); __ jcc(Assembler::notEqual, L); __ should_not_reach_here(); __ bind(L); @@ -2865,7 +2866,7 @@ class StubGenerator: public StubCodeGenerator { // Generates all stubs and initializes the entry points // This platform-specific stub is needed by generate_call_stub() - StubRoutines::amd64::_mxcsr_std = generate_fp_mask("mxcsr_std", 0x0000000000001F80); + StubRoutines::x86::_mxcsr_std = generate_fp_mask("mxcsr_std", 0x0000000000001F80); // entry points that exist in all platforms Note: This is code // that could be shared among different platforms - however the @@ -2894,9 +2895,9 @@ class StubGenerator: public StubCodeGenerator { generate_handler_for_unsafe_access(); // platform dependent - StubRoutines::amd64::_get_previous_fp_entry = generate_get_previous_fp(); + StubRoutines::x86::_get_previous_fp_entry = generate_get_previous_fp(); - StubRoutines::amd64::_verify_mxcsr_entry = generate_verify_mxcsr(); + StubRoutines::x86::_verify_mxcsr_entry = generate_verify_mxcsr(); } void generate_all() { @@ -2948,15 +2949,15 @@ class StubGenerator: public StubCodeGenerator { false); // entry points that are platform specific - StubRoutines::amd64::_f2i_fixup = generate_f2i_fixup(); - StubRoutines::amd64::_f2l_fixup = generate_f2l_fixup(); - StubRoutines::amd64::_d2i_fixup = generate_d2i_fixup(); - StubRoutines::amd64::_d2l_fixup = generate_d2l_fixup(); + StubRoutines::x86::_f2i_fixup = generate_f2i_fixup(); + StubRoutines::x86::_f2l_fixup = generate_f2l_fixup(); + StubRoutines::x86::_d2i_fixup = generate_d2i_fixup(); + StubRoutines::x86::_d2l_fixup = generate_d2l_fixup(); - StubRoutines::amd64::_float_sign_mask = generate_fp_mask("float_sign_mask", 0x7FFFFFFF7FFFFFFF); - StubRoutines::amd64::_float_sign_flip = generate_fp_mask("float_sign_flip", 0x8000000080000000); - StubRoutines::amd64::_double_sign_mask = generate_fp_mask("double_sign_mask", 0x7FFFFFFFFFFFFFFF); - StubRoutines::amd64::_double_sign_flip = generate_fp_mask("double_sign_flip", 0x8000000000000000); + StubRoutines::x86::_float_sign_mask = generate_fp_mask("float_sign_mask", 0x7FFFFFFF7FFFFFFF); + StubRoutines::x86::_float_sign_flip = generate_fp_mask("float_sign_flip", 0x8000000080000000); + StubRoutines::x86::_double_sign_mask = generate_fp_mask("double_sign_mask", 0x7FFFFFFFFFFFFFFF); + StubRoutines::x86::_double_sign_flip = generate_fp_mask("double_sign_flip", 0x8000000000000000); // support for verify_oop (must happen after universe_init) StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop(); diff --git a/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.cpp b/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.cpp index 285eef97ef0..2bd98acabf1 100644 --- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.cpp @@ -28,6 +28,6 @@ // Implementation of the platform-specific part of StubRoutines - for // a description of how to extend it, see the stubRoutines.hpp file. -address StubRoutines::i486::_verify_mxcsr_entry = NULL; -address StubRoutines::i486::_verify_fpu_cntrl_wrd_entry= NULL; -address StubRoutines::i486::_call_stub_compiled_return = NULL; +address StubRoutines::x86::_verify_mxcsr_entry = NULL; +address StubRoutines::x86::_verify_fpu_cntrl_wrd_entry= NULL; +address StubRoutines::x86::_call_stub_compiled_return = NULL; diff --git a/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.hpp b/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.hpp index 8f79b51ecb2..d1943f37334 100644 --- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.hpp +++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.hpp @@ -31,7 +31,7 @@ enum platform_dependent_constants { code_size2 = 22000 // simply increase if too small (assembler will crash if too small) }; -class i486 { +class x86 { friend class StubGenerator; friend class VMStructs; @@ -54,4 +54,4 @@ class i486 { }; static bool returns_to_call_stub(address return_pc) { return (return_pc == _call_stub_return_address) || - return_pc == i486::get_call_stub_compiled_return(); } + return_pc == x86::get_call_stub_compiled_return(); } diff --git a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp index 7979f3f0b99..aaf91cad11b 100644 --- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp @@ -28,16 +28,16 @@ // Implementation of the platform-specific part of StubRoutines - for // a description of how to extend it, see the stubRoutines.hpp file. -address StubRoutines::amd64::_get_previous_fp_entry = NULL; +address StubRoutines::x86::_get_previous_fp_entry = NULL; -address StubRoutines::amd64::_verify_mxcsr_entry = NULL; +address StubRoutines::x86::_verify_mxcsr_entry = NULL; -address StubRoutines::amd64::_f2i_fixup = NULL; -address StubRoutines::amd64::_f2l_fixup = NULL; -address StubRoutines::amd64::_d2i_fixup = NULL; -address StubRoutines::amd64::_d2l_fixup = NULL; -address StubRoutines::amd64::_float_sign_mask = NULL; -address StubRoutines::amd64::_float_sign_flip = NULL; -address StubRoutines::amd64::_double_sign_mask = NULL; -address StubRoutines::amd64::_double_sign_flip = NULL; -address StubRoutines::amd64::_mxcsr_std = NULL; +address StubRoutines::x86::_f2i_fixup = NULL; +address StubRoutines::x86::_f2l_fixup = NULL; +address StubRoutines::x86::_d2i_fixup = NULL; +address StubRoutines::x86::_d2l_fixup = NULL; +address StubRoutines::x86::_float_sign_mask = NULL; +address StubRoutines::x86::_float_sign_flip = NULL; +address StubRoutines::x86::_double_sign_mask = NULL; +address StubRoutines::x86::_double_sign_flip = NULL; +address StubRoutines::x86::_mxcsr_std = NULL; diff --git a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp index da7e8fd56a5..37342b8d8fe 100644 --- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp +++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp @@ -30,13 +30,13 @@ static bool returns_to_call_stub(address return_pc) { return return_pc == _ enum platform_dependent_constants { - code_size1 = 9000, // simply increase if too small (assembler will + code_size1 = 19000, // simply increase if too small (assembler will // crash if too small) code_size2 = 22000 // simply increase if too small (assembler will // crash if too small) }; -class amd64 { +class x86 { friend class StubGenerator; private: diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp index 61eb99b99b2..093d4045778 100644 --- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp @@ -43,9 +43,9 @@ address TemplateInterpreterGenerator::generate_StackOverflowError_handler() { // #ifdef ASSERT { Label L; - __ leal(rax, Address(rbp, + __ lea(rax, Address(rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize)); - __ cmpl(rax, rsp); // rax, = maximal rsp for current rbp, + __ cmpptr(rax, rsp); // rax, = maximal rsp for current rbp, // (stack grows negative) __ jcc(Assembler::aboveEqual, L); // check if frame is complete __ stop ("interpreter frame not set up"); @@ -80,7 +80,7 @@ address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler(con address TemplateInterpreterGenerator::generate_ClassCastException_handler() { address entry = __ pc(); // object is at TOS - __ popl(rax); + __ pop(rax); // expression stack must be empty before entering the VM if an exception // happened __ empty_expression_stack(); @@ -97,7 +97,7 @@ address TemplateInterpreterGenerator::generate_exception_handler_common(const ch address entry = __ pc(); if (pass_oop) { // object is at TOS - __ popl(rbx); + __ pop(rbx); } // expression stack must be empty before entering the VM if an exception happened __ empty_expression_stack(); @@ -110,7 +110,7 @@ address TemplateInterpreterGenerator::generate_exception_handler_common(const ch if (message != NULL) { __ lea(rbx, ExternalAddress((address)message)); } else { - __ movl(rbx, NULL_WORD); + __ movptr(rbx, (int32_t)NULL_WORD); } __ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::create_exception), rax, rbx); } @@ -123,7 +123,7 @@ address TemplateInterpreterGenerator::generate_exception_handler_common(const ch address TemplateInterpreterGenerator::generate_continuation_for(TosState state) { address entry = __ pc(); // NULL last_sp until next java call - __ movl(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); __ dispatch_next(state); return entry; } @@ -160,32 +160,32 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, // In SSE mode, interpreter returns FP results in xmm0 but they need // to end up back on the FPU so it can operate on them. if (state == ftos && UseSSE >= 1) { - __ subl(rsp, wordSize); + __ subptr(rsp, wordSize); __ movflt(Address(rsp, 0), xmm0); __ fld_s(Address(rsp, 0)); - __ addl(rsp, wordSize); + __ addptr(rsp, wordSize); } else if (state == dtos && UseSSE >= 2) { - __ subl(rsp, 2*wordSize); + __ subptr(rsp, 2*wordSize); __ movdbl(Address(rsp, 0), xmm0); __ fld_d(Address(rsp, 0)); - __ addl(rsp, 2*wordSize); + __ addptr(rsp, 2*wordSize); } __ MacroAssembler::verify_FPU(state == ftos || state == dtos ? 1 : 0, "generate_return_entry_for in interpreter"); // Restore stack bottom in case i2c adjusted stack - __ movl(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); + __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); // and NULL it as marker that rsp is now tos until next java call - __ movl(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); __ restore_bcp(); __ restore_locals(); __ get_cache_and_index_at_bcp(rbx, rcx, 1); __ movl(rbx, Address(rbx, rcx, - Address::times_4, constantPoolCacheOopDesc::base_offset() + + Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::flags_offset())); - __ andl(rbx, 0xFF); - __ leal(rsp, Address(rsp, rbx, Interpreter::stackElementScale())); + __ andptr(rbx, 0xFF); + __ lea(rsp, Address(rsp, rbx, Interpreter::stackElementScale())); __ dispatch_next(state, step); return entry; } @@ -196,29 +196,29 @@ address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, i // In SSE mode, FP results are in xmm0 if (state == ftos && UseSSE > 0) { - __ subl(rsp, wordSize); + __ subptr(rsp, wordSize); __ movflt(Address(rsp, 0), xmm0); __ fld_s(Address(rsp, 0)); - __ addl(rsp, wordSize); + __ addptr(rsp, wordSize); } else if (state == dtos && UseSSE >= 2) { - __ subl(rsp, 2*wordSize); + __ subptr(rsp, 2*wordSize); __ movdbl(Address(rsp, 0), xmm0); __ fld_d(Address(rsp, 0)); - __ addl(rsp, 2*wordSize); + __ addptr(rsp, 2*wordSize); } __ MacroAssembler::verify_FPU(state == ftos || state == dtos ? 1 : 0, "generate_deopt_entry_for in interpreter"); // The stack is not extended by deopt but we must NULL last_sp as this // entry is like a "return". - __ movl(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); __ restore_bcp(); __ restore_locals(); // handle exceptions { Label L; const Register thread = rcx; __ get_thread(thread); - __ cmpl(Address(thread, Thread::pending_exception_offset()), NULL_WORD); + __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::zero, L); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_pending_exception)); __ should_not_reach_here(); @@ -254,14 +254,14 @@ address TemplateInterpreterGenerator::generate_result_handler_for(BasicType type address entry = __ pc(); switch (type) { case T_BOOLEAN: __ c2bool(rax); break; - case T_CHAR : __ andl(rax, 0xFFFF); break; + case T_CHAR : __ andptr(rax, 0xFFFF); break; case T_BYTE : __ sign_extend_byte (rax); break; case T_SHORT : __ sign_extend_short(rax); break; case T_INT : /* nothing to do */ break; case T_DOUBLE : case T_FLOAT : { const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp(); - __ popl(t); // remove return address first + __ pop(t); // remove return address first __ pop_dtos_to_rsp(); // Must return a result for interpreter or compiler. In SSE // mode, results are returned in xmm0 and the FPU stack must @@ -280,13 +280,13 @@ address TemplateInterpreterGenerator::generate_result_handler_for(BasicType type __ fld_d(Address(rsp, 0)); } // and pop the temp - __ addl(rsp, 2 * wordSize); - __ pushl(t); // restore return address + __ addptr(rsp, 2 * wordSize); + __ push(t); // restore return address } break; case T_OBJECT : // retrieve result from frame - __ movl(rax, Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize)); + __ movptr(rax, Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize)); // and verify it __ verify_oop(rax); break; @@ -322,12 +322,12 @@ void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile const Address backedge_counter (rbx, methodOopDesc::backedge_counter_offset() + InvocationCounter::counter_offset()); if (ProfileInterpreter) { // %%% Merge this into methodDataOop - __ increment(Address(rbx,methodOopDesc::interpreter_invocation_counter_offset())); + __ incrementl(Address(rbx,methodOopDesc::interpreter_invocation_counter_offset())); } // Update standard invocation counters __ movl(rax, backedge_counter); // load backedge counter - __ increment(rcx, InvocationCounter::count_increment); + __ incrementl(rcx, InvocationCounter::count_increment); __ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits __ movl(invocation_counter, rcx); // save invocation count @@ -382,10 +382,10 @@ void InterpreterGenerator::generate_counter_overflow(Label* do_continue) { // indicating if the counter overflow occurs at a backwards branch (non-NULL bcp). // The call returns the address of the verified entry point for the method or NULL // if the compilation did not complete (either went background or bailed out). - __ movl(rax, (int)false); + __ movptr(rax, (int32_t)false); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), rax); - __ movl(rbx, Address(rbp, method_offset)); // restore methodOop + __ movptr(rbx, Address(rbp, method_offset)); // restore methodOop // Preserve invariant that rsi/rdi contain bcp/locals of sender frame // and jump to the interpreted entry. @@ -433,7 +433,7 @@ void InterpreterGenerator::generate_stack_overflow_check(void) { Label after_frame_check_pop; - __ pushl(rsi); + __ push(rsi); const Register thread = rsi; @@ -443,43 +443,43 @@ void InterpreterGenerator::generate_stack_overflow_check(void) { const Address stack_size(thread, Thread::stack_size_offset()); // locals + overhead, in bytes - __ leal(rax, Address(noreg, rdx, Interpreter::stackElementScale(), overhead_size)); + __ lea(rax, Address(noreg, rdx, Interpreter::stackElementScale(), overhead_size)); #ifdef ASSERT Label stack_base_okay, stack_size_okay; // verify that thread stack base is non-zero - __ cmpl(stack_base, 0); + __ cmpptr(stack_base, (int32_t)NULL_WORD); __ jcc(Assembler::notEqual, stack_base_okay); __ stop("stack base is zero"); __ bind(stack_base_okay); // verify that thread stack size is non-zero - __ cmpl(stack_size, 0); + __ cmpptr(stack_size, 0); __ jcc(Assembler::notEqual, stack_size_okay); __ stop("stack size is zero"); __ bind(stack_size_okay); #endif // Add stack base to locals and subtract stack size - __ addl(rax, stack_base); - __ subl(rax, stack_size); + __ addptr(rax, stack_base); + __ subptr(rax, stack_size); // Use the maximum number of pages we might bang. const int max_pages = StackShadowPages > (StackRedPages+StackYellowPages) ? StackShadowPages : (StackRedPages+StackYellowPages); - __ addl(rax, max_pages * page_size); + __ addptr(rax, max_pages * page_size); // check against the current stack bottom - __ cmpl(rsp, rax); + __ cmpptr(rsp, rax); __ jcc(Assembler::above, after_frame_check_pop); - __ popl(rsi); // get saved bcp / (c++ prev state ). + __ pop(rsi); // get saved bcp / (c++ prev state ). - __ popl(rax); // get return address + __ pop(rax); // get return address __ jump(ExternalAddress(Interpreter::throw_StackOverflowError_entry())); // all done with frame size check __ bind(after_frame_check_pop); - __ popl(rsi); + __ pop(rsi); __ bind(after_frame_check); } @@ -507,18 +507,18 @@ void InterpreterGenerator::lock_method(void) { const int mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes(); __ movl(rax, access_flags); __ testl(rax, JVM_ACC_STATIC); - __ movl(rax, Address(rdi, Interpreter::local_offset_in_bytes(0))); // get receiver (assume this is frequent case) + __ movptr(rax, Address(rdi, Interpreter::local_offset_in_bytes(0))); // get receiver (assume this is frequent case) __ jcc(Assembler::zero, done); - __ movl(rax, Address(rbx, methodOopDesc::constants_offset())); - __ movl(rax, Address(rax, constantPoolOopDesc::pool_holder_offset_in_bytes())); - __ movl(rax, Address(rax, mirror_offset)); + __ movptr(rax, Address(rbx, methodOopDesc::constants_offset())); + __ movptr(rax, Address(rax, constantPoolOopDesc::pool_holder_offset_in_bytes())); + __ movptr(rax, Address(rax, mirror_offset)); __ bind(done); } // add space for monitor & lock - __ subl(rsp, entry_size); // add space for a monitor entry - __ movl(monitor_block_top, rsp); // set new monitor block top - __ movl(Address(rsp, BasicObjectLock::obj_offset_in_bytes()), rax); // store object - __ movl(rdx, rsp); // object address + __ subptr(rsp, entry_size); // add space for a monitor entry + __ movptr(monitor_block_top, rsp); // set new monitor block top + __ movptr(Address(rsp, BasicObjectLock::obj_offset_in_bytes()), rax); // store object + __ mov(rdx, rsp); // object address __ lock_object(rdx); } @@ -528,38 +528,38 @@ void InterpreterGenerator::lock_method(void) { void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { // initialize fixed part of activation frame - __ pushl(rax); // save return address + __ push(rax); // save return address __ enter(); // save old & set new rbp, - __ pushl(rsi); // set sender sp - __ pushl(NULL_WORD); // leave last_sp as null - __ movl(rsi, Address(rbx,methodOopDesc::const_offset())); // get constMethodOop - __ leal(rsi, Address(rsi,constMethodOopDesc::codes_offset())); // get codebase - __ pushl(rbx); // save methodOop + __ push(rsi); // set sender sp + __ push((int32_t)NULL_WORD); // leave last_sp as null + __ movptr(rsi, Address(rbx,methodOopDesc::const_offset())); // get constMethodOop + __ lea(rsi, Address(rsi,constMethodOopDesc::codes_offset())); // get codebase + __ push(rbx); // save methodOop if (ProfileInterpreter) { Label method_data_continue; - __ movl(rdx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); - __ testl(rdx, rdx); + __ movptr(rdx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); + __ testptr(rdx, rdx); __ jcc(Assembler::zero, method_data_continue); - __ addl(rdx, in_bytes(methodDataOopDesc::data_offset())); + __ addptr(rdx, in_bytes(methodDataOopDesc::data_offset())); __ bind(method_data_continue); - __ pushl(rdx); // set the mdp (method data pointer) + __ push(rdx); // set the mdp (method data pointer) } else { - __ pushl(0); + __ push(0); } - __ movl(rdx, Address(rbx, methodOopDesc::constants_offset())); - __ movl(rdx, Address(rdx, constantPoolOopDesc::cache_offset_in_bytes())); - __ pushl(rdx); // set constant pool cache - __ pushl(rdi); // set locals pointer + __ movptr(rdx, Address(rbx, methodOopDesc::constants_offset())); + __ movptr(rdx, Address(rdx, constantPoolOopDesc::cache_offset_in_bytes())); + __ push(rdx); // set constant pool cache + __ push(rdi); // set locals pointer if (native_call) { - __ pushl(0); // no bcp + __ push(0); // no bcp } else { - __ pushl(rsi); // set bcp + __ push(rsi); // set bcp } - __ pushl(0); // reserve word for pointer to expression stack bottom - __ movl(Address(rsp, 0), rsp); // set expression stack bottom + __ push(0); // reserve word for pointer to expression stack bottom + __ movptr(Address(rsp, 0), rsp); // set expression stack bottom } // End of helpers @@ -598,21 +598,21 @@ address InterpreterGenerator::generate_accessor_entry(void) { // these conditions first and use slow path if necessary. // rbx,: method // rcx: receiver - __ movl(rax, Address(rsp, wordSize)); + __ movptr(rax, Address(rsp, wordSize)); // check if local 0 != NULL and read field - __ testl(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, slow_path); - __ movl(rdi, Address(rbx, methodOopDesc::constants_offset())); + __ movptr(rdi, Address(rbx, methodOopDesc::constants_offset())); // read first instruction word and extract bytecode @ 1 and index @ 2 - __ movl(rdx, Address(rbx, methodOopDesc::const_offset())); + __ movptr(rdx, Address(rbx, methodOopDesc::const_offset())); __ movl(rdx, Address(rdx, constMethodOopDesc::codes_offset())); // Shift codes right to get the index on the right. // The bytecode fetched looks like <0xb4><0x2a> __ shrl(rdx, 2*BitsPerByte); __ shll(rdx, exact_log2(in_words(ConstantPoolCacheEntry::size()))); - __ movl(rdi, Address(rdi, constantPoolOopDesc::cache_offset_in_bytes())); + __ movptr(rdi, Address(rdi, constantPoolOopDesc::cache_offset_in_bytes())); // rax,: local 0 // rbx,: method @@ -629,21 +629,21 @@ address InterpreterGenerator::generate_accessor_entry(void) { __ movl(rcx, Address(rdi, rdx, - Address::times_4, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset())); + Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset())); __ shrl(rcx, 2*BitsPerByte); __ andl(rcx, 0xFF); __ cmpl(rcx, Bytecodes::_getfield); __ jcc(Assembler::notEqual, slow_path); // Note: constant pool entry is not valid before bytecode is resolved - __ movl(rcx, - Address(rdi, - rdx, - Address::times_4, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f2_offset())); + __ movptr(rcx, + Address(rdi, + rdx, + Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f2_offset())); __ movl(rdx, Address(rdi, rdx, - Address::times_4, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::flags_offset())); + Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::flags_offset())); Label notByte, notShort, notChar; const Address field_address (rax, rcx, Address::times_1); @@ -682,13 +682,14 @@ address InterpreterGenerator::generate_accessor_entry(void) { __ bind(okay); #endif // ASSERT // All the rest are a 32 bit wordsize - __ movl(rax, field_address); + // This is ok for now. Since fast accessors should be going away + __ movptr(rax, field_address); __ bind(xreturn_path); // _ireturn/_areturn - __ popl(rdi); // get return address - __ movl(rsp, rsi); // set sp to sender sp + __ pop(rdi); // get return address + __ mov(rsp, rsi); // set sp to sender sp __ jmp(rdi); // generate a vanilla interpreter entry as the slow path @@ -732,18 +733,18 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // rcx: size of parameters // rsi: sender sp - __ popl(rax); // get return address + __ pop(rax); // get return address // for natives the size of locals is zero // compute beginning of parameters (rdi) - __ leal(rdi, Address(rsp, rcx, Interpreter::stackElementScale(), -wordSize)); + __ lea(rdi, Address(rsp, rcx, Interpreter::stackElementScale(), -wordSize)); // add 2 zero-initialized slots for native calls // NULL result handler - __ pushl(NULL_WORD); + __ push((int32_t)NULL_WORD); // NULL oop temp (mirror or jni oop result) - __ pushl(NULL_WORD); + __ push((int32_t)NULL_WORD); if (inc_counter) __ movl(rcx, invocation_counter); // (pre-)fetch invocation count // initialize fixed part of activation frame @@ -818,8 +819,8 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { { Label L; const Address monitor_block_top (rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize); - __ movl(rax, monitor_block_top); - __ cmpl(rax, rsp); + __ movptr(rax, monitor_block_top); + __ cmpptr(rax, rsp); __ jcc(Assembler::equal, L); __ stop("broken stack frame setup in interpreter"); __ bind(L); @@ -838,19 +839,19 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ get_method(method); __ verify_oop(method); __ load_unsigned_word(t, Address(method, methodOopDesc::size_of_parameters_offset())); - __ shll(t, Interpreter::logStackElementSize()); - __ addl(t, 2*wordSize); // allocate two more slots for JNIEnv and possible mirror - __ subl(rsp, t); - __ andl(rsp, -(StackAlignmentInBytes)); // gcc needs 16 byte aligned stacks to do XMM intrinsics + __ shlptr(t, Interpreter::logStackElementSize()); + __ addptr(t, 2*wordSize); // allocate two more slots for JNIEnv and possible mirror + __ subptr(rsp, t); + __ andptr(rsp, -(StackAlignmentInBytes)); // gcc needs 16 byte aligned stacks to do XMM intrinsics // get signature handler { Label L; - __ movl(t, Address(method, methodOopDesc::signature_handler_offset())); - __ testl(t, t); + __ movptr(t, Address(method, methodOopDesc::signature_handler_offset())); + __ testptr(t, t); __ jcc(Assembler::notZero, L); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), method); __ get_method(method); - __ movl(t, Address(method, methodOopDesc::signature_handler_offset())); + __ movptr(t, Address(method, methodOopDesc::signature_handler_offset())); __ bind(L); } @@ -867,7 +868,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // result handler is in rax, // set result handler - __ movl(Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize), rax); + __ movptr(Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize), rax); // pass mirror handle if static call { Label L; @@ -876,34 +877,34 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ testl(t, JVM_ACC_STATIC); __ jcc(Assembler::zero, L); // get mirror - __ movl(t, Address(method, methodOopDesc:: constants_offset())); - __ movl(t, Address(t, constantPoolOopDesc::pool_holder_offset_in_bytes())); - __ movl(t, Address(t, mirror_offset)); + __ movptr(t, Address(method, methodOopDesc:: constants_offset())); + __ movptr(t, Address(t, constantPoolOopDesc::pool_holder_offset_in_bytes())); + __ movptr(t, Address(t, mirror_offset)); // copy mirror into activation frame - __ movl(Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize), t); + __ movptr(Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize), t); // pass handle to mirror - __ leal(t, Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize)); - __ movl(Address(rsp, wordSize), t); + __ lea(t, Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize)); + __ movptr(Address(rsp, wordSize), t); __ bind(L); } // get native function entry point { Label L; - __ movl(rax, Address(method, methodOopDesc::native_function_offset())); + __ movptr(rax, Address(method, methodOopDesc::native_function_offset())); ExternalAddress unsatisfied(SharedRuntime::native_method_throw_unsatisfied_link_error_entry()); - __ cmp32(rax, unsatisfied.addr()); + __ cmpptr(rax, unsatisfied.addr()); __ jcc(Assembler::notEqual, L); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), method); __ get_method(method); __ verify_oop(method); - __ movl(rax, Address(method, methodOopDesc::native_function_offset())); + __ movptr(rax, Address(method, methodOopDesc::native_function_offset())); __ bind(L); } // pass JNIEnv __ get_thread(thread); - __ leal(t, Address(thread, JavaThread::jni_environment_offset())); - __ movl(Address(rsp, 0), t); + __ lea(t, Address(thread, JavaThread::jni_environment_offset())); + __ movptr(Address(rsp, 0), t); // set_last_Java_frame_before_call // It is enough that the pc() @@ -934,14 +935,14 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ ldmxcsr(ExternalAddress(StubRoutines::addr_mxcsr_std())); } else if (CheckJNICalls ) { - __ call(RuntimeAddress(StubRoutines::i486::verify_mxcsr_entry())); + __ call(RuntimeAddress(StubRoutines::x86::verify_mxcsr_entry())); } } // Either restore the x87 floating pointer control word after returning // from the JNI call or verify that it wasn't changed. if (CheckJNICalls) { - __ call(RuntimeAddress(StubRoutines::i486::verify_fpu_cntrl_wrd_entry())); + __ call(RuntimeAddress(StubRoutines::x86::verify_fpu_cntrl_wrd_entry())); } // save potential result in ST(0) & rdx:rax @@ -975,7 +976,10 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native_trans); if(os::is_MP()) { if (UseMembar) { - __ membar(); // Force this write out before the read below + // Force this write out before the read below + __ membar(Assembler::Membar_mask_bits( + Assembler::LoadLoad | Assembler::LoadStore | + Assembler::StoreLoad | Assembler::StoreStore)); } else { // Write serialization page so VM thread can do a pseudo remote membar. // We use the current thread pointer to calculate a thread specific @@ -1008,7 +1012,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // preserved and correspond to the bcp/locals pointers. So we do a runtime call // by hand. // - __ pushl(thread); + __ push(thread); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans))); __ increment(rsp, wordSize); @@ -1023,8 +1027,8 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ reset_last_Java_frame(thread, true, true); // reset handle block - __ movl(t, Address(thread, JavaThread::active_handles_offset())); - __ movl(Address(t, JNIHandleBlock::top_offset_in_bytes()), 0); + __ movptr(t, Address(thread, JavaThread::active_handles_offset())); + __ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); // If result was an oop then unbox and save it in the frame { Label L; @@ -1033,14 +1037,14 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ cmpptr(Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize), handler.addr()); __ jcc(Assembler::notEqual, no_oop); - __ cmpl(Address(rsp, 0), NULL_WORD); + __ cmpptr(Address(rsp, 0), (int32_t)NULL_WORD); __ pop(ltos); - __ testl(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, store_result); // unbox - __ movl(rax, Address(rax, 0)); + __ movptr(rax, Address(rax, 0)); __ bind(store_result); - __ movl(Address(rbp, (frame::interpreter_frame_oop_temp_offset)*wordSize), rax); + __ movptr(Address(rbp, (frame::interpreter_frame_oop_temp_offset)*wordSize), rax); // keep stack depth as expected by pushing oop which will eventually be discarded __ push(ltos); __ bind(no_oop); @@ -1051,9 +1055,9 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ cmpl(Address(thread, JavaThread::stack_guard_state_offset()), JavaThread::stack_guard_yellow_disabled); __ jcc(Assembler::notEqual, no_reguard); - __ pushad(); + __ pusha(); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages))); - __ popad(); + __ popa(); __ bind(no_reguard); } @@ -1063,12 +1067,12 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // Can't call_VM until bcp is within reasonable. __ get_method(method); // method is junk from thread_in_native to now. __ verify_oop(method); - __ movl(rsi, Address(method,methodOopDesc::const_offset())); // get constMethodOop - __ leal(rsi, Address(rsi,constMethodOopDesc::codes_offset())); // get codebase + __ movptr(rsi, Address(method,methodOopDesc::const_offset())); // get constMethodOop + __ lea(rsi, Address(rsi,constMethodOopDesc::codes_offset())); // get codebase // handle exceptions (exception handling will handle unlocking!) { Label L; - __ cmpl(Address(thread, Thread::pending_exception_offset()), NULL_WORD); + __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::zero, L); // Note: At some point we may want to unify this with the code used in call_VM_base(); // i.e., we should use the StubRoutines::forward_exception code. For now this @@ -1089,10 +1093,10 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // to check that the object has not been unlocked by an explicit monitorexit bytecode. const Address monitor(rbp, frame::interpreter_frame_initial_sp_offset * wordSize - (int)sizeof(BasicObjectLock)); - __ leal(rdx, monitor); // address of first monitor + __ lea(rdx, monitor); // address of first monitor - __ movl(t, Address(rdx, BasicObjectLock::obj_offset_in_bytes())); - __ testl(t, t); + __ movptr(t, Address(rdx, BasicObjectLock::obj_offset_in_bytes())); + __ testptr(t, t); __ jcc(Assembler::notZero, unlock); // Entry already unlocked, need to throw exception @@ -1114,14 +1118,14 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // restore potential result in rdx:rax, call result handler to restore potential result in ST0 & handle result __ pop(ltos); - __ movl(t, Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize)); + __ movptr(t, Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize)); __ call(t); // remove activation - __ movl(t, Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); // get sender sp + __ movptr(t, Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); // get sender sp __ leave(); // remove frame anchor - __ popl(rdi); // get return address - __ movl(rsp, t); // set sp to sender sp + __ pop(rdi); // get return address + __ mov(rsp, t); // set sp to sender sp __ jmp(rdi); if (inc_counter) { @@ -1165,10 +1169,10 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { generate_stack_overflow_check(); // get return address - __ popl(rax); + __ pop(rax); // compute beginning of parameters (rdi) - __ leal(rdi, Address(rsp, rcx, Interpreter::stackElementScale(), -wordSize)); + __ lea(rdi, Address(rsp, rcx, Interpreter::stackElementScale(), -wordSize)); // rdx - # of additional locals // allocate space for locals @@ -1178,8 +1182,10 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { __ testl(rdx, rdx); __ jcc(Assembler::lessEqual, exit); // do nothing if rdx <= 0 __ bind(loop); - if (TaggedStackInterpreter) __ pushl(NULL_WORD); // push tag - __ pushl(NULL_WORD); // initialize local variables + if (TaggedStackInterpreter) { + __ push((int32_t)NULL_WORD); // push tag + } + __ push((int32_t)NULL_WORD); // initialize local variables __ decrement(rdx); // until everything initialized __ jcc(Assembler::greater, loop); __ bind(exit); @@ -1262,8 +1268,8 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { { Label L; const Address monitor_block_top (rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize); - __ movl(rax, monitor_block_top); - __ cmpl(rax, rsp); + __ movptr(rax, monitor_block_top); + __ cmpptr(rax, rsp); __ jcc(Assembler::equal, L); __ stop("broken stack frame setup in interpreter"); __ bind(L); @@ -1283,12 +1289,12 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method), rsi, true); - __ movl(rbx, Address(rbp, method_offset)); // restore methodOop - __ movl(rax, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); - __ movl(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rax); + __ movptr(rbx, Address(rbp, method_offset)); // restore methodOop + __ movptr(rax, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); + __ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rax); __ test_method_data_pointer(rax, profile_method_continue); - __ addl(rax, in_bytes(methodDataOopDesc::data_offset())); - __ movl(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rax); + __ addptr(rax, in_bytes(methodDataOopDesc::data_offset())); + __ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rax); __ jmp(profile_method_continue); } // Handle overflow of counter and compile method @@ -1482,7 +1488,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // Restore sp to interpreter_frame_last_sp even though we are going // to empty the expression stack for the exception processing. - __ movl(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); // rax,: exception // rdx: return address/pc that threw exception __ restore_bcp(); // rsi points to call/send @@ -1544,7 +1550,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // deoptimization blob's unpack entry because of the presence of // adapter frames in C2. Label caller_not_deoptimized; - __ movl(rdx, Address(rbp, frame::return_addr_offset * wordSize)); + __ movptr(rdx, Address(rbp, frame::return_addr_offset * wordSize)); __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::interpreter_contains), rdx); __ testl(rax, rax); __ jcc(Assembler::notZero, caller_not_deoptimized); @@ -1553,10 +1559,10 @@ void TemplateInterpreterGenerator::generate_throw_exception() { __ get_method(rax); __ verify_oop(rax); __ load_unsigned_word(rax, Address(rax, in_bytes(methodOopDesc::size_of_parameters_offset()))); - __ shll(rax, Interpreter::logStackElementSize()); + __ shlptr(rax, Interpreter::logStackElementSize()); __ restore_locals(); - __ subl(rdi, rax); - __ addl(rdi, wordSize); + __ subptr(rdi, rax); + __ addptr(rdi, wordSize); // Save these arguments __ get_thread(rcx); __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, Deoptimization::popframe_preserve_args), rcx, rax, rdi); @@ -1592,8 +1598,8 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // maintain this kind of invariant all the time we call a small // fixup routine to move the mutated arguments onto the top of our // expression stack if necessary. - __ movl(rax, rsp); - __ movl(rbx, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); + __ mov(rax, rsp); + __ movptr(rbx, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); __ get_thread(rcx); // PC must point into interpreter here __ set_last_Java_frame(rcx, noreg, rbp, __ pc()); @@ -1601,8 +1607,8 @@ void TemplateInterpreterGenerator::generate_throw_exception() { __ get_thread(rcx); __ reset_last_Java_frame(rcx, true, true); // Restore the last_sp and null it out - __ movl(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); - __ movl(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); __ restore_bcp(); __ restore_locals(); @@ -1624,13 +1630,13 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // preserve exception over this code sequence __ pop_ptr(rax); __ get_thread(rcx); - __ movl(Address(rcx, JavaThread::vm_result_offset()), rax); + __ movptr(Address(rcx, JavaThread::vm_result_offset()), rax); // remove the activation (without doing throws on illegalMonitorExceptions) __ remove_activation(vtos, rdx, false, true, false); // restore exception __ get_thread(rcx); - __ movl(rax, Address(rcx, JavaThread::vm_result_offset())); - __ movl(Address(rcx, JavaThread::vm_result_offset()), NULL_WORD); + __ movptr(rax, Address(rcx, JavaThread::vm_result_offset())); + __ movptr(Address(rcx, JavaThread::vm_result_offset()), (int32_t)NULL_WORD); __ verify_oop(rax); // Inbetween activations - previous activation type unknown yet @@ -1641,12 +1647,12 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // rdx: return address/pc that threw exception // rsp: expression stack of caller // rbp,: rbp, of caller - __ pushl(rax); // save exception - __ pushl(rdx); // save return address + __ push(rax); // save exception + __ push(rdx); // save return address __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), rdx); - __ movl(rbx, rax); // save exception handler - __ popl(rdx); // restore return address - __ popl(rax); // restore exception + __ mov(rbx, rax); // save exception handler + __ pop(rdx); // restore return address + __ pop(rax); // restore exception // Note that an "issuing PC" is actually the next PC after the call __ jmp(rbx); // jump to exception handler of caller } @@ -1665,7 +1671,7 @@ address TemplateInterpreterGenerator::generate_earlyret_entry_for(TosState state __ load_earlyret_value(state); __ get_thread(rcx); - __ movl(rcx, Address(rcx, JavaThread::jvmti_thread_state_offset())); + __ movptr(rcx, Address(rcx, JavaThread::jvmti_thread_state_offset())); const Address cond_addr(rcx, JvmtiThreadState::earlyret_state_offset()); // Clear the earlyret state @@ -1716,12 +1722,12 @@ address TemplateInterpreterGenerator::generate_trace_code(TosState state) { address entry = __ pc(); // prepare expression stack - __ popl(rcx); // pop return address so expression stack is 'pure' + __ pop(rcx); // pop return address so expression stack is 'pure' __ push(state); // save tosca // pass tosca registers as arguments & call tracer __ call_VM(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::trace_bytecode), rcx, rax, rdx); - __ movl(rcx, rax); // make sure return address is not destroyed by pop(state) + __ mov(rcx, rax); // make sure return address is not destroyed by pop(state) __ pop(state); // restore tosca // return @@ -1732,12 +1738,12 @@ address TemplateInterpreterGenerator::generate_trace_code(TosState state) { void TemplateInterpreterGenerator::count_bytecode() { - __ increment(ExternalAddress((address) &BytecodeCounter::_counter_value)); + __ incrementl(ExternalAddress((address) &BytecodeCounter::_counter_value)); } void TemplateInterpreterGenerator::histogram_bytecode(Template* t) { - __ increment(ExternalAddress((address) &BytecodeHistogram::_counters[t->bytecode()])); + __ incrementl(ExternalAddress((address) &BytecodeHistogram::_counters[t->bytecode()])); } @@ -1747,7 +1753,7 @@ void TemplateInterpreterGenerator::histogram_bytecode_pair(Template* t) { __ orl(rbx, ((int)t->bytecode()) << BytecodePairHistogram::log2_number_of_codes); ExternalAddress table((address) BytecodePairHistogram::_counters); Address index(noreg, rbx, Address::times_4); - __ increment(ArrayAddress(table, index)); + __ incrementl(ArrayAddress(table, index)); } diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp index 3f7d4719b5f..9caf33f6b09 100644 --- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp @@ -27,6 +27,8 @@ #define __ _masm-> +#ifndef CC_INTERP + const int method_offset = frame::interpreter_frame_method_offset * wordSize; const int bci_offset = frame::interpreter_frame_bcx_offset * wordSize; const int locals_offset = frame::interpreter_frame_locals_offset * wordSize; @@ -39,11 +41,11 @@ address TemplateInterpreterGenerator::generate_StackOverflowError_handler() { #ifdef ASSERT { Label L; - __ leaq(rax, Address(rbp, - frame::interpreter_frame_monitor_block_top_offset * - wordSize)); - __ cmpq(rax, rsp); // rax = maximal rsp for current rbp (stack - // grows negative) + __ lea(rax, Address(rbp, + frame::interpreter_frame_monitor_block_top_offset * + wordSize)); + __ cmpptr(rax, rsp); // rax = maximal rsp for current rbp (stack + // grows negative) __ jcc(Assembler::aboveEqual, L); // check if frame is complete __ stop ("interpreter frame not set up"); __ bind(L); @@ -84,7 +86,7 @@ address TemplateInterpreterGenerator::generate_ClassCastException_handler() { address entry = __ pc(); // object is at TOS - __ popq(c_rarg1); + __ pop(c_rarg1); // expression stack must be empty before entering the VM if an // exception happened @@ -104,7 +106,7 @@ address TemplateInterpreterGenerator::generate_exception_handler_common( address entry = __ pc(); if (pass_oop) { // object is at TOS - __ popq(c_rarg2); + __ pop(c_rarg2); } // expression stack must be empty before entering the VM if an // exception happened @@ -137,7 +139,7 @@ address TemplateInterpreterGenerator::generate_exception_handler_common( address TemplateInterpreterGenerator::generate_continuation_for(TosState state) { address entry = __ pc(); // NULL last_sp until next java call - __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); __ dispatch_next(state); return entry; } @@ -153,12 +155,13 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, address entry = __ pc(); // Restore stack bottom in case i2c adjusted stack - __ movq(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); + __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); // and NULL it as marker that esp is now tos until next java call - __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); __ restore_bcp(); __ restore_locals(); + __ get_cache_and_index_at_bcp(rbx, rcx, 1); __ movl(rbx, Address(rbx, rcx, Address::times_8, @@ -166,7 +169,7 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, 3 * wordSize)); __ andl(rbx, 0xFF); if (TaggedStackInterpreter) __ shll(rbx, 1); // 2 slots per parameter. - __ leaq(rsp, Address(rsp, rbx, Address::times_8)); + __ lea(rsp, Address(rsp, rbx, Address::times_8)); __ dispatch_next(state, step); return entry; } @@ -176,13 +179,13 @@ address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step) { address entry = __ pc(); // NULL last_sp until next java call - __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); __ restore_bcp(); __ restore_locals(); // handle exceptions { Label L; - __ cmpq(Address(r15_thread, Thread::pending_exception_offset()), (int) NULL); + __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t) NULL_WORD); __ jcc(Assembler::zero, L); __ call_VM(noreg, CAST_FROM_FN_PTR(address, @@ -231,7 +234,7 @@ address TemplateInterpreterGenerator::generate_result_handler_for( case T_DOUBLE : /* nothing to do */ break; case T_OBJECT : // retrieve result from frame - __ movq(rax, Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize)); + __ movptr(rax, Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize)); // and verify it __ verify_oop(rax); break; @@ -336,7 +339,7 @@ void InterpreterGenerator::generate_counter_overflow(Label* do_continue) { InterpreterRuntime::frequency_counter_overflow), c_rarg1); - __ movq(rbx, Address(rbp, method_offset)); // restore methodOop + __ movptr(rbx, Address(rbp, method_offset)); // restore methodOop // Preserve invariant that r13/r14 contain bcp/locals of sender frame // and jump to the interpreted entry. __ jmp(*do_continue, relocInfo::none); @@ -385,36 +388,36 @@ void InterpreterGenerator::generate_stack_overflow_check(void) { const Address stack_size(r15_thread, Thread::stack_size_offset()); // locals + overhead, in bytes - __ movq(rax, rdx); - __ shll(rax, Interpreter::logStackElementSize()); // 2 slots per parameter. - __ addq(rax, overhead_size); + __ mov(rax, rdx); + __ shlptr(rax, Interpreter::logStackElementSize()); // 2 slots per parameter. + __ addptr(rax, overhead_size); #ifdef ASSERT Label stack_base_okay, stack_size_okay; // verify that thread stack base is non-zero - __ cmpq(stack_base, 0); + __ cmpptr(stack_base, (int32_t)NULL_WORD); __ jcc(Assembler::notEqual, stack_base_okay); __ stop("stack base is zero"); __ bind(stack_base_okay); // verify that thread stack size is non-zero - __ cmpq(stack_size, 0); + __ cmpptr(stack_size, 0); __ jcc(Assembler::notEqual, stack_size_okay); __ stop("stack size is zero"); __ bind(stack_size_okay); #endif // Add stack base to locals and subtract stack size - __ addq(rax, stack_base); - __ subq(rax, stack_size); + __ addptr(rax, stack_base); + __ subptr(rax, stack_size); // add in the red and yellow zone sizes - __ addq(rax, (StackRedPages + StackYellowPages) * page_size); + __ addptr(rax, (StackRedPages + StackYellowPages) * page_size); // check against the current stack bottom - __ cmpq(rsp, rax); + __ cmpptr(rsp, rax); __ jcc(Assembler::above, after_frame_check); - __ popq(rax); // get return address + __ pop(rax); // get return address __ jump(ExternalAddress(Interpreter::throw_StackOverflowError_entry())); // all done with frame size check @@ -458,17 +461,17 @@ void InterpreterGenerator::lock_method(void) { __ movl(rax, access_flags); __ testl(rax, JVM_ACC_STATIC); // get receiver (assume this is frequent case) - __ movq(rax, Address(r14, Interpreter::local_offset_in_bytes(0))); + __ movptr(rax, Address(r14, Interpreter::local_offset_in_bytes(0))); __ jcc(Assembler::zero, done); - __ movq(rax, Address(rbx, methodOopDesc::constants_offset())); - __ movq(rax, Address(rax, - constantPoolOopDesc::pool_holder_offset_in_bytes())); - __ movq(rax, Address(rax, mirror_offset)); + __ movptr(rax, Address(rbx, methodOopDesc::constants_offset())); + __ movptr(rax, Address(rax, + constantPoolOopDesc::pool_holder_offset_in_bytes())); + __ movptr(rax, Address(rax, mirror_offset)); #ifdef ASSERT { Label L; - __ testq(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::notZero, L); __ stop("synchronization object is NULL"); __ bind(L); @@ -479,11 +482,11 @@ void InterpreterGenerator::lock_method(void) { } // add space for monitor & lock - __ subq(rsp, entry_size); // add space for a monitor entry - __ movq(monitor_block_top, rsp); // set new monitor block top + __ subptr(rsp, entry_size); // add space for a monitor entry + __ movptr(monitor_block_top, rsp); // set new monitor block top // store object - __ movq(Address(rsp, BasicObjectLock::obj_offset_in_bytes()), rax); - __ movq(c_rarg1, rsp); // object address + __ movptr(Address(rsp, BasicObjectLock::obj_offset_in_bytes()), rax); + __ movptr(c_rarg1, rsp); // object address __ lock_object(c_rarg1); } @@ -498,40 +501,187 @@ void InterpreterGenerator::lock_method(void) { // rdx: cp cache void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { // initialize fixed part of activation frame - __ pushq(rax); // save return address + __ push(rax); // save return address __ enter(); // save old & set new rbp - __ pushq(r13); // set sender sp - __ pushq((int)NULL_WORD); // leave last_sp as null - __ movq(r13, Address(rbx, methodOopDesc::const_offset())); // get constMethodOop - __ leaq(r13, Address(r13, constMethodOopDesc::codes_offset())); // get codebase - __ pushq(rbx); // save methodOop + __ push(r13); // set sender sp + __ push((int)NULL_WORD); // leave last_sp as null + __ movptr(r13, Address(rbx, methodOopDesc::const_offset())); // get constMethodOop + __ lea(r13, Address(r13, constMethodOopDesc::codes_offset())); // get codebase + __ push(rbx); // save methodOop if (ProfileInterpreter) { Label method_data_continue; - __ movq(rdx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); - __ testq(rdx, rdx); + __ movptr(rdx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); + __ testptr(rdx, rdx); __ jcc(Assembler::zero, method_data_continue); - __ addq(rdx, in_bytes(methodDataOopDesc::data_offset())); + __ addptr(rdx, in_bytes(methodDataOopDesc::data_offset())); __ bind(method_data_continue); - __ pushq(rdx); // set the mdp (method data pointer) + __ push(rdx); // set the mdp (method data pointer) } else { - __ pushq(0); + __ push(0); } - __ movq(rdx, Address(rbx, methodOopDesc::constants_offset())); - __ movq(rdx, Address(rdx, constantPoolOopDesc::cache_offset_in_bytes())); - __ pushq(rdx); // set constant pool cache - __ pushq(r14); // set locals pointer + __ movptr(rdx, Address(rbx, methodOopDesc::constants_offset())); + __ movptr(rdx, Address(rdx, constantPoolOopDesc::cache_offset_in_bytes())); + __ push(rdx); // set constant pool cache + __ push(r14); // set locals pointer if (native_call) { - __ pushq(0); // no bcp + __ push(0); // no bcp } else { - __ pushq(r13); // set bcp + __ push(r13); // set bcp } - __ pushq(0); // reserve word for pointer to expression stack bottom - __ movq(Address(rsp, 0), rsp); // set expression stack bottom + __ push(0); // reserve word for pointer to expression stack bottom + __ movptr(Address(rsp, 0), rsp); // set expression stack bottom } // End of helpers +// Various method entries +//------------------------------------------------------------------------------------------------------------------------ +// +// + +// Call an accessor method (assuming it is resolved, otherwise drop +// into vanilla (slow path) entry +address InterpreterGenerator::generate_accessor_entry(void) { + // rbx: methodOop + + // r13: senderSP must preserver for slow path, set SP to it on fast path + + address entry_point = __ pc(); + Label xreturn_path; + + // do fastpath for resolved accessor methods + if (UseFastAccessorMethods) { + // Code: _aload_0, _(i|a)getfield, _(i|a)return or any rewrites + // thereof; parameter size = 1 + // Note: We can only use this code if the getfield has been resolved + // and if we don't have a null-pointer exception => check for + // these conditions first and use slow path if necessary. + Label slow_path; + // If we need a safepoint check, generate full interpreter entry. + __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), + SafepointSynchronize::_not_synchronized); + + __ jcc(Assembler::notEqual, slow_path); + // rbx: method + __ movptr(rax, Address(rsp, wordSize)); + + // check if local 0 != NULL and read field + __ testptr(rax, rax); + __ jcc(Assembler::zero, slow_path); + + __ movptr(rdi, Address(rbx, methodOopDesc::constants_offset())); + // read first instruction word and extract bytecode @ 1 and index @ 2 + __ movptr(rdx, Address(rbx, methodOopDesc::const_offset())); + __ movl(rdx, Address(rdx, constMethodOopDesc::codes_offset())); + // Shift codes right to get the index on the right. + // The bytecode fetched looks like <0xb4><0x2a> + __ shrl(rdx, 2 * BitsPerByte); + __ shll(rdx, exact_log2(in_words(ConstantPoolCacheEntry::size()))); + __ movptr(rdi, Address(rdi, constantPoolOopDesc::cache_offset_in_bytes())); + + // rax: local 0 + // rbx: method + // rdx: constant pool cache index + // rdi: constant pool cache + + // check if getfield has been resolved and read constant pool cache entry + // check the validity of the cache entry by testing whether _indices field + // contains Bytecode::_getfield in b1 byte. + assert(in_words(ConstantPoolCacheEntry::size()) == 4, + "adjust shift below"); + __ movl(rcx, + Address(rdi, + rdx, + Address::times_8, + constantPoolCacheOopDesc::base_offset() + + ConstantPoolCacheEntry::indices_offset())); + __ shrl(rcx, 2 * BitsPerByte); + __ andl(rcx, 0xFF); + __ cmpl(rcx, Bytecodes::_getfield); + __ jcc(Assembler::notEqual, slow_path); + + // Note: constant pool entry is not valid before bytecode is resolved + __ movptr(rcx, + Address(rdi, + rdx, + Address::times_8, + constantPoolCacheOopDesc::base_offset() + + ConstantPoolCacheEntry::f2_offset())); + // edx: flags + __ movl(rdx, + Address(rdi, + rdx, + Address::times_8, + constantPoolCacheOopDesc::base_offset() + + ConstantPoolCacheEntry::flags_offset())); + + Label notObj, notInt, notByte, notShort; + const Address field_address(rax, rcx, Address::times_1); + + // Need to differentiate between igetfield, agetfield, bgetfield etc. + // because they are different sizes. + // Use the type from the constant pool cache + __ shrl(rdx, ConstantPoolCacheEntry::tosBits); + // Make sure we don't need to mask edx for tosBits after the above shift + ConstantPoolCacheEntry::verify_tosBits(); + + __ cmpl(rdx, atos); + __ jcc(Assembler::notEqual, notObj); + // atos + __ load_heap_oop(rax, field_address); + __ jmp(xreturn_path); + + __ bind(notObj); + __ cmpl(rdx, itos); + __ jcc(Assembler::notEqual, notInt); + // itos + __ movl(rax, field_address); + __ jmp(xreturn_path); + + __ bind(notInt); + __ cmpl(rdx, btos); + __ jcc(Assembler::notEqual, notByte); + // btos + __ load_signed_byte(rax, field_address); + __ jmp(xreturn_path); + + __ bind(notByte); + __ cmpl(rdx, stos); + __ jcc(Assembler::notEqual, notShort); + // stos + __ load_signed_word(rax, field_address); + __ jmp(xreturn_path); + + __ bind(notShort); +#ifdef ASSERT + Label okay; + __ cmpl(rdx, ctos); + __ jcc(Assembler::equal, okay); + __ stop("what type is this?"); + __ bind(okay); +#endif + // ctos + __ load_unsigned_word(rax, field_address); + + __ bind(xreturn_path); + + // _ireturn/_areturn + __ pop(rdi); + __ mov(rsp, r13); + __ jmp(rdi); + __ ret(0); + + // generate a vanilla interpreter entry as the slow path + __ bind(slow_path); + (void) generate_normal_entry(false); + } else { + (void) generate_normal_entry(false); + } + + return entry_point; +} + // Interpreter stub for calling a native method. (asm interpreter) // This sets up a somewhat different looking stack for calling the // native method than the typical interpreter frame setup. @@ -561,20 +711,20 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // rbx: methodOop // rcx: size of parameters // r13: sender sp - __ popq(rax); // get return address + __ pop(rax); // get return address // for natives the size of locals is zero // compute beginning of parameters (r14) if (TaggedStackInterpreter) __ shll(rcx, 1); // 2 slots per parameter. - __ leaq(r14, Address(rsp, rcx, Address::times_8, -wordSize)); + __ lea(r14, Address(rsp, rcx, Address::times_8, -wordSize)); // add 2 zero-initialized slots for native calls // initialize result_handler slot - __ pushq((int) NULL); + __ push((int) NULL_WORD); // slot for oop temp // (static native method holder mirror/jni oop result) - __ pushq((int) NULL); + __ push((int) NULL_WORD); if (inc_counter) { __ movl(rcx, invocation_counter); // (pre-)fetch invocation count @@ -651,8 +801,8 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { Label L; const Address monitor_block_top(rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize); - __ movq(rax, monitor_block_top); - __ cmpq(rax, rsp); + __ movptr(rax, monitor_block_top); + __ cmpptr(rax, rsp); __ jcc(Assembler::equal, L); __ stop("broken stack frame setup in interpreter"); __ bind(L); @@ -674,22 +824,22 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { methodOopDesc::size_of_parameters_offset())); __ shll(t, Interpreter::logStackElementSize()); - __ subq(rsp, t); - __ subq(rsp, frame::arg_reg_save_area_bytes); // windows - __ andq(rsp, -16); // must be 16 byte boundry (see amd64 ABI) + __ subptr(rsp, t); + __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows + __ andptr(rsp, -16); // must be 16 byte boundry (see amd64 ABI) // get signature handler { Label L; - __ movq(t, Address(method, methodOopDesc::signature_handler_offset())); - __ testq(t, t); + __ movptr(t, Address(method, methodOopDesc::signature_handler_offset())); + __ testptr(t, t); __ jcc(Assembler::notZero, L); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), method); __ get_method(method); - __ movq(t, Address(method, methodOopDesc::signature_handler_offset())); + __ movptr(t, Address(method, methodOopDesc::signature_handler_offset())); __ bind(L); } @@ -711,9 +861,9 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // result handler is in rax // set result handler - __ movq(Address(rbp, - (frame::interpreter_frame_result_handler_offset) * wordSize), - rax); + __ movptr(Address(rbp, + (frame::interpreter_frame_result_handler_offset) * wordSize), + rax); // pass mirror handle if static call { @@ -724,25 +874,25 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ testl(t, JVM_ACC_STATIC); __ jcc(Assembler::zero, L); // get mirror - __ movq(t, Address(method, methodOopDesc::constants_offset())); - __ movq(t, Address(t, constantPoolOopDesc::pool_holder_offset_in_bytes())); - __ movq(t, Address(t, mirror_offset)); + __ movptr(t, Address(method, methodOopDesc::constants_offset())); + __ movptr(t, Address(t, constantPoolOopDesc::pool_holder_offset_in_bytes())); + __ movptr(t, Address(t, mirror_offset)); // copy mirror into activation frame - __ movq(Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize), + __ movptr(Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize), t); // pass handle to mirror - __ leaq(c_rarg1, - Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize)); + __ lea(c_rarg1, + Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize)); __ bind(L); } // get native function entry point { Label L; - __ movq(rax, Address(method, methodOopDesc::native_function_offset())); + __ movptr(rax, Address(method, methodOopDesc::native_function_offset())); ExternalAddress unsatisfied(SharedRuntime::native_method_throw_unsatisfied_link_error_entry()); __ movptr(rscratch2, unsatisfied.addr()); - __ cmpq(rax, rscratch2); + __ cmpptr(rax, rscratch2); __ jcc(Assembler::notEqual, L); __ call_VM(noreg, CAST_FROM_FN_PTR(address, @@ -750,12 +900,12 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { method); __ get_method(method); __ verify_oop(method); - __ movq(rax, Address(method, methodOopDesc::native_function_offset())); + __ movptr(rax, Address(method, methodOopDesc::native_function_offset())); __ bind(L); } // pass JNIEnv - __ leaq(c_rarg0, Address(r15_thread, JavaThread::jni_environment_offset())); + __ lea(c_rarg0, Address(r15_thread, JavaThread::jni_environment_offset())); // It is enough that the pc() points into the right code // segment. It does not have to be the correct return pc. @@ -786,10 +936,10 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // register after returning from the JNI Call or verify that // it wasn't changed during -Xcheck:jni. if (RestoreMXCSROnJNICalls) { - __ ldmxcsr(ExternalAddress(StubRoutines::amd64::mxcsr_std())); + __ ldmxcsr(ExternalAddress(StubRoutines::x86::mxcsr_std())); } else if (CheckJNICalls) { - __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::amd64::verify_mxcsr_entry()))); + __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::verify_mxcsr_entry()))); } // NOTE: The order of these pushes is known to frame::interpreter_frame_result @@ -838,12 +988,12 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // preserved and correspond to the bcp/locals pointers. So we do a // runtime call by hand. // - __ movq(c_rarg0, r15_thread); - __ movq(r12, rsp); // remember sp - __ subq(rsp, frame::arg_reg_save_area_bytes); // windows - __ andq(rsp, -16); // align stack as required by ABI + __ mov(c_rarg0, r15_thread); + __ mov(r12, rsp); // remember sp + __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows + __ andptr(rsp, -16); // align stack as required by ABI __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans))); - __ movq(rsp, r12); // restore sp + __ mov(rsp, r12); // restore sp __ reinit_heapbase(); __ bind(Continue); } @@ -855,8 +1005,8 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ reset_last_Java_frame(true, true); // reset handle block - __ movq(t, Address(r15_thread, JavaThread::active_handles_offset())); - __ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD); + __ movptr(t, Address(r15_thread, JavaThread::active_handles_offset())); + __ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); // If result is an oop unbox and store it in frame where gc will see it // and result handler will pick it up @@ -864,15 +1014,15 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { { Label no_oop, store_result; __ lea(t, ExternalAddress(AbstractInterpreter::result_handler(T_OBJECT))); - __ cmpq(t, Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize)); + __ cmpptr(t, Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize)); __ jcc(Assembler::notEqual, no_oop); // retrieve result __ pop(ltos); - __ testq(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, store_result); - __ movq(rax, Address(rax, 0)); + __ movptr(rax, Address(rax, 0)); __ bind(store_result); - __ movq(Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize), rax); + __ movptr(Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize), rax); // keep stack depth as expected by pushing oop which will eventually be discarde __ push(ltos); __ bind(no_oop); @@ -885,13 +1035,13 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { JavaThread::stack_guard_yellow_disabled); __ jcc(Assembler::notEqual, no_reguard); - __ pushaq(); // XXX only save smashed registers - __ movq(r12, rsp); // remember sp - __ subq(rsp, frame::arg_reg_save_area_bytes); // windows - __ andq(rsp, -16); // align stack as required by ABI + __ pusha(); // XXX only save smashed registers + __ mov(r12, rsp); // remember sp + __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows + __ andptr(rsp, -16); // align stack as required by ABI __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages))); - __ movq(rsp, r12); // restore sp - __ popaq(); // XXX only restore smashed registers + __ mov(rsp, r12); // restore sp + __ popa(); // XXX only restore smashed registers __ reinit_heapbase(); __ bind(no_reguard); @@ -906,12 +1056,12 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // restore r13 to have legal interpreter frame, i.e., bci == 0 <=> // r13 == code_base() - __ movq(r13, Address(method, methodOopDesc::const_offset())); // get constMethodOop - __ leaq(r13, Address(r13, constMethodOopDesc::codes_offset())); // get codebase + __ movptr(r13, Address(method, methodOopDesc::const_offset())); // get constMethodOop + __ lea(r13, Address(r13, constMethodOopDesc::codes_offset())); // get codebase // handle exceptions (exception handling will handle unlocking!) { Label L; - __ cmpq(Address(r15_thread, Thread::pending_exception_offset()), (int) NULL); + __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t) NULL_WORD); __ jcc(Assembler::zero, L); // Note: At some point we may want to unify this with the code // used in call_VM_base(); i.e., we should use the @@ -942,10 +1092,10 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { wordSize - sizeof(BasicObjectLock))); // monitor expect in c_rarg1 for slow unlock path - __ leaq(c_rarg1, monitor); // address of first monitor + __ lea(c_rarg1, monitor); // address of first monitor - __ movq(t, Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes())); - __ testq(t, t); + __ movptr(t, Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes())); + __ testptr(t, t); __ jcc(Assembler::notZero, unlock); // Entry already unlocked, need to throw exception @@ -973,17 +1123,17 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ pop(ltos); __ pop(dtos); - __ movq(t, Address(rbp, - (frame::interpreter_frame_result_handler_offset) * wordSize)); + __ movptr(t, Address(rbp, + (frame::interpreter_frame_result_handler_offset) * wordSize)); __ call(t); // remove activation - __ movq(t, Address(rbp, - frame::interpreter_frame_sender_sp_offset * - wordSize)); // get sender sp + __ movptr(t, Address(rbp, + frame::interpreter_frame_sender_sp_offset * + wordSize)); // get sender sp __ leave(); // remove frame anchor - __ popq(rdi); // get return address - __ movq(rsp, t); // set sp to sender sp + __ pop(rdi); // get return address + __ mov(rsp, t); // set sp to sender sp __ jmp(rdi); if (inc_counter) { @@ -1032,11 +1182,11 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { generate_stack_overflow_check(); // get return address - __ popq(rax); + __ pop(rax); // compute beginning of parameters (r14) if (TaggedStackInterpreter) __ shll(rcx, 1); // 2 slots per parameter. - __ leaq(r14, Address(rsp, rcx, Address::times_8, -wordSize)); + __ lea(r14, Address(rsp, rcx, Address::times_8, -wordSize)); // rdx - # of additional locals // allocate space for locals @@ -1046,8 +1196,8 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { __ testl(rdx, rdx); __ jcc(Assembler::lessEqual, exit); // do nothing if rdx <= 0 __ bind(loop); - if (TaggedStackInterpreter) __ pushq((int) NULL); // push tag - __ pushq((int) NULL); // initialize local variables + if (TaggedStackInterpreter) __ push((int) NULL_WORD); // push tag + __ push((int) NULL_WORD); // initialize local variables __ decrementl(rdx); // until everything initialized __ jcc(Assembler::greater, loop); __ bind(exit); @@ -1137,8 +1287,8 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { Label L; const Address monitor_block_top (rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize); - __ movq(rax, monitor_block_top); - __ cmpq(rax, rsp); + __ movptr(rax, monitor_block_top); + __ cmpptr(rax, rsp); __ jcc(Assembler::equal, L); __ stop("broken stack frame setup in interpreter"); __ bind(L); @@ -1160,14 +1310,14 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method), r13, true); - __ movq(rbx, Address(rbp, method_offset)); // restore methodOop - __ movq(rax, Address(rbx, - in_bytes(methodOopDesc::method_data_offset()))); - __ movq(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), - rax); + __ movptr(rbx, Address(rbp, method_offset)); // restore methodOop + __ movptr(rax, Address(rbx, + in_bytes(methodOopDesc::method_data_offset()))); + __ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), + rax); __ test_method_data_pointer(rax, profile_method_continue); - __ addq(rax, in_bytes(methodDataOopDesc::data_offset())); - __ movq(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), + __ addptr(rax, in_bytes(methodDataOopDesc::data_offset())); + __ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rax); __ jmp(profile_method_continue); } @@ -1357,7 +1507,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() { Interpreter::_rethrow_exception_entry = __ pc(); // Restore sp to interpreter_frame_last_sp even though we are going // to empty the expression stack for the exception processing. - __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); // rax: exception // rdx: return address/pc that threw exception __ restore_bcp(); // r13 points to call/send @@ -1369,7 +1519,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // rax: exception // r13: exception bcp __ verify_oop(rax); - __ movq(c_rarg1, rax); + __ mov(c_rarg1, rax); // expression stack must be empty before entering the VM in case of // an exception @@ -1424,7 +1574,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // deoptimization blob's unpack entry because of the presence of // adapter frames in C2. Label caller_not_deoptimized; - __ movq(c_rarg1, Address(rbp, frame::return_addr_offset * wordSize)); + __ movptr(c_rarg1, Address(rbp, frame::return_addr_offset * wordSize)); __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::interpreter_contains), c_rarg1); __ testl(rax, rax); @@ -1437,8 +1587,8 @@ void TemplateInterpreterGenerator::generate_throw_exception() { size_of_parameters_offset()))); __ shll(rax, Interpreter::logStackElementSize()); __ restore_locals(); // XXX do we need this? - __ subq(r14, rax); - __ addq(r14, wordSize); + __ subptr(r14, rax); + __ addptr(r14, wordSize); // Save these arguments __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, Deoptimization:: @@ -1477,15 +1627,15 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // maintain this kind of invariant all the time we call a small // fixup routine to move the mutated arguments onto the top of our // expression stack if necessary. - __ movq(c_rarg1, rsp); - __ movq(c_rarg2, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); + __ mov(c_rarg1, rsp); + __ movptr(c_rarg2, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); // PC must point into interpreter here __ set_last_Java_frame(noreg, rbp, __ pc()); __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::popframe_move_outgoing_args), r15_thread, c_rarg1, c_rarg2); __ reset_last_Java_frame(true, true); // Restore the last_sp and null it out - __ movq(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); - __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); __ restore_bcp(); // XXX do we need this? __ restore_locals(); // XXX do we need this? @@ -1506,12 +1656,12 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // preserve exception over this code sequence __ pop_ptr(rax); - __ movq(Address(r15_thread, JavaThread::vm_result_offset()), rax); + __ movptr(Address(r15_thread, JavaThread::vm_result_offset()), rax); // remove the activation (without doing throws on illegalMonitorExceptions) __ remove_activation(vtos, rdx, false, true, false); // restore exception - __ movq(rax, Address(r15_thread, JavaThread::vm_result_offset())); - __ movptr(Address(r15_thread, JavaThread::vm_result_offset()), NULL_WORD); + __ movptr(rax, Address(r15_thread, JavaThread::vm_result_offset())); + __ movptr(Address(r15_thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD); __ verify_oop(rax); // In between activations - previous activation type unknown yet @@ -1522,14 +1672,14 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // rdx: return address/pc that threw exception // rsp: expression stack of caller // rbp: ebp of caller - __ pushq(rax); // save exception - __ pushq(rdx); // save return address + __ push(rax); // save exception + __ push(rdx); // save return address __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), rdx); - __ movq(rbx, rax); // save exception handler - __ popq(rdx); // restore return address - __ popq(rax); // restore exception + __ mov(rbx, rax); // save exception handler + __ pop(rdx); // restore return address + __ pop(rax); // restore exception // Note that an "issuing PC" is actually the next PC after the call __ jmp(rbx); // jump to exception // handler of caller @@ -1547,7 +1697,7 @@ address TemplateInterpreterGenerator::generate_earlyret_entry_for(TosState state __ empty_expression_stack(); __ load_earlyret_value(state); - __ movq(rdx, Address(r15_thread, JavaThread::jvmti_thread_state_offset())); + __ movptr(rdx, Address(r15_thread, JavaThread::jvmti_thread_state_offset())); Address cond_addr(rdx, JvmtiThreadState::earlyret_state_offset()); // Clear the earlyret state @@ -1609,21 +1759,21 @@ address TemplateInterpreterGenerator::generate_trace_code(TosState state) { address entry = __ pc(); __ push(state); - __ pushq(c_rarg0); - __ pushq(c_rarg1); - __ pushq(c_rarg2); - __ pushq(c_rarg3); - __ movq(c_rarg2, rax); // Pass itos + __ push(c_rarg0); + __ push(c_rarg1); + __ push(c_rarg2); + __ push(c_rarg3); + __ mov(c_rarg2, rax); // Pass itos #ifdef _WIN64 __ movflt(xmm3, xmm0); // Pass ftos #endif __ call_VM(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::trace_bytecode), c_rarg1, c_rarg2, c_rarg3); - __ popq(c_rarg3); - __ popq(c_rarg2); - __ popq(c_rarg1); - __ popq(c_rarg0); + __ pop(c_rarg3); + __ pop(c_rarg2); + __ pop(c_rarg1); + __ pop(c_rarg0); __ pop(state); __ ret(0); // return from result handler @@ -1657,10 +1807,10 @@ void TemplateInterpreterGenerator::trace_bytecode(Template* t) { assert(Interpreter::trace_code(t->tos_in()) != NULL, "entry must have been generated"); - __ movq(r12, rsp); // remember sp - __ andq(rsp, -16); // align stack as required by ABI + __ mov(r12, rsp); // remember sp + __ andptr(rsp, -16); // align stack as required by ABI __ call(RuntimeAddress(Interpreter::trace_code(t->tos_in()))); - __ movq(rsp, r12); // restore sp + __ mov(rsp, r12); // restore sp __ reinit_heapbase(); } @@ -1674,3 +1824,4 @@ void TemplateInterpreterGenerator::stop_interpreter_at() { __ bind(L); } #endif // !PRODUCT +#endif // ! CC_INTERP diff --git a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp index 24e7e12fc85..31c6975ec64 100644 --- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp @@ -119,12 +119,14 @@ void TemplateTable::patch_bytecode(Bytecodes::Code bytecode, Register bc, if (!RewriteBytecodes) return; // the pair bytecodes have already done the load. - if (load_bc_into_scratch) __ movl(bc, bytecode); + if (load_bc_into_scratch) { + __ movl(bc, bytecode); + } Label patch_done; if (JvmtiExport::can_post_breakpoint()) { Label fast_patch; // if a breakpoint is present we can't rewrite the stream directly - __ movzxb(scratch, at_bcp(0)); + __ movzbl(scratch, at_bcp(0)); __ cmpl(scratch, Bytecodes::_breakpoint); __ jcc(Assembler::notEqual, fast_patch); __ get_method(scratch); @@ -169,16 +171,16 @@ void TemplateTable::shouldnotreachhere() { void TemplateTable::aconst_null() { transition(vtos, atos); - __ xorl(rax, rax); + __ xorptr(rax, rax); } void TemplateTable::iconst(int value) { transition(vtos, itos); if (value == 0) { - __ xorl(rax, rax); + __ xorptr(rax, rax); } else { - __ movl(rax, value); + __ movptr(rax, value); } } @@ -186,12 +188,12 @@ void TemplateTable::iconst(int value) { void TemplateTable::lconst(int value) { transition(vtos, ltos); if (value == 0) { - __ xorl(rax, rax); + __ xorptr(rax, rax); } else { - __ movl(rax, value); + __ movptr(rax, value); } assert(value >= 0, "check this code"); - __ xorl(rdx, rdx); + __ xorptr(rdx, rdx); } @@ -223,7 +225,7 @@ void TemplateTable::bipush() { void TemplateTable::sipush() { transition(vtos, itos); __ load_unsigned_word(rax, at_bcp(1)); - __ bswap(rax); + __ bswapl(rax); __ sarl(rax, 16); } @@ -241,7 +243,7 @@ void TemplateTable::ldc(bool wide) { const int tags_offset = typeArrayOopDesc::header_size(T_BYTE) * wordSize; // get type - __ xorl(rdx, rdx); + __ xorptr(rdx, rdx); __ movb(rdx, Address(rax, rbx, Address::times_1, tags_offset)); // unresolved string - get the resolved string @@ -271,7 +273,7 @@ void TemplateTable::ldc(bool wide) { __ cmpl(rdx, JVM_CONSTANT_Float); __ jccb(Assembler::notEqual, notFloat); // ftos - __ fld_s( Address(rcx, rbx, Address::times_4, base_offset)); + __ fld_s( Address(rcx, rbx, Address::times_ptr, base_offset)); __ push(ftos); __ jmp(Done); @@ -288,13 +290,14 @@ void TemplateTable::ldc(bool wide) { #endif Label isOop; // atos and itos - __ movl(rax, Address(rcx, rbx, Address::times_4, base_offset)); // String is only oop type we will see here __ cmpl(rdx, JVM_CONSTANT_String); __ jccb(Assembler::equal, isOop); + __ movl(rax, Address(rcx, rbx, Address::times_ptr, base_offset)); __ push(itos); __ jmp(Done); __ bind(isOop); + __ movptr(rax, Address(rcx, rbx, Address::times_ptr, base_offset)); __ push(atos); if (VerifyOops) { @@ -316,14 +319,14 @@ void TemplateTable::ldc2_w() { __ cmpb(Address(rax, rbx, Address::times_1, tags_offset), JVM_CONSTANT_Double); __ jccb(Assembler::notEqual, Long); // dtos - __ fld_d( Address(rcx, rbx, Address::times_4, base_offset)); + __ fld_d( Address(rcx, rbx, Address::times_ptr, base_offset)); __ push(dtos); __ jmpb(Done); __ bind(Long); // ltos - __ movl(rax, Address(rcx, rbx, Address::times_4, base_offset + 0 * wordSize)); - __ movl(rdx, Address(rcx, rbx, Address::times_4, base_offset + 1 * wordSize)); + __ movptr(rax, Address(rcx, rbx, Address::times_ptr, base_offset + 0 * wordSize)); + NOT_LP64(__ movptr(rdx, Address(rcx, rbx, Address::times_ptr, base_offset + 1 * wordSize))); __ push(ltos); @@ -333,7 +336,7 @@ void TemplateTable::ldc2_w() { void TemplateTable::locals_index(Register reg, int offset) { __ load_unsigned_byte(reg, at_bcp(offset)); - __ negl(reg); + __ negptr(reg); } @@ -399,8 +402,8 @@ void TemplateTable::fast_iload() { void TemplateTable::lload() { transition(vtos, ltos); locals_index(rbx); - __ movl(rax, laddress(rbx)); - __ movl(rdx, haddress(rbx)); + __ movptr(rax, laddress(rbx)); + NOT_LP64(__ movl(rdx, haddress(rbx))); debug_only(__ verify_local_tag(frame::TagCategory2, rbx)); } @@ -421,10 +424,10 @@ void TemplateTable::dload() { // float instruction into ST0 __ movl(rax, laddress(rbx)); __ movl(rdx, haddress(rbx)); - __ pushl(rdx); // push hi first - __ pushl(rax); + __ push(rdx); // push hi first + __ push(rax); __ fld_d(Address(rsp, 0)); - __ addl(rsp, 2*wordSize); + __ addptr(rsp, 2*wordSize); debug_only(__ verify_local_tag(frame::TagCategory2, rbx)); } else { __ fld_d(daddress(rbx)); @@ -435,16 +438,16 @@ void TemplateTable::dload() { void TemplateTable::aload() { transition(vtos, atos); locals_index(rbx); - __ movl(rax, iaddress(rbx)); + __ movptr(rax, aaddress(rbx)); debug_only(__ verify_local_tag(frame::TagReference, rbx)); } void TemplateTable::locals_index_wide(Register reg) { __ movl(reg, at_bcp(2)); - __ bswap(reg); + __ bswapl(reg); __ shrl(reg, 16); - __ negl(reg); + __ negptr(reg); } @@ -459,8 +462,8 @@ void TemplateTable::wide_iload() { void TemplateTable::wide_lload() { transition(vtos, ltos); locals_index_wide(rbx); - __ movl(rax, laddress(rbx)); - __ movl(rdx, haddress(rbx)); + __ movptr(rax, laddress(rbx)); + NOT_LP64(__ movl(rdx, haddress(rbx))); debug_only(__ verify_local_tag(frame::TagCategory2, rbx)); } @@ -481,8 +484,8 @@ void TemplateTable::wide_dload() { // float instruction into ST0 __ movl(rax, laddress(rbx)); __ movl(rdx, haddress(rbx)); - __ pushl(rdx); // push hi first - __ pushl(rax); + __ push(rdx); // push hi first + __ push(rax); __ fld_d(Address(rsp, 0)); __ addl(rsp, 2*wordSize); debug_only(__ verify_local_tag(frame::TagCategory2, rbx)); @@ -495,7 +498,7 @@ void TemplateTable::wide_dload() { void TemplateTable::wide_aload() { transition(vtos, atos); locals_index_wide(rbx); - __ movl(rax, iaddress(rbx)); + __ movptr(rax, aaddress(rbx)); debug_only(__ verify_local_tag(frame::TagReference, rbx)); } @@ -509,12 +512,13 @@ void TemplateTable::index_check_without_pop(Register array, Register index) { // destroys rbx, // check array __ null_check(array, arrayOopDesc::length_offset_in_bytes()); + LP64_ONLY(__ movslq(index, index)); // check index __ cmpl(index, Address(array, arrayOopDesc::length_offset_in_bytes())); if (index != rbx) { // ??? convention: move aberrant index into rbx, for exception message assert(rbx != array, "different registers"); - __ movl(rbx, index); + __ mov(rbx, index); } __ jump_cc(Assembler::aboveEqual, ExternalAddress(Interpreter::_throw_ArrayIndexOutOfBoundsException_entry)); @@ -535,10 +539,10 @@ void TemplateTable::laload() { // rax,: index // rdx: array index_check(rdx, rax); - __ movl(rbx, rax); + __ mov(rbx, rax); // rbx,: index - __ movl(rax, Address(rdx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize)); - __ movl(rdx, Address(rdx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG) + 1 * wordSize)); + __ movptr(rax, Address(rdx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize)); + NOT_LP64(__ movl(rdx, Address(rdx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG) + 1 * wordSize))); } @@ -565,7 +569,7 @@ void TemplateTable::aaload() { // rdx: array index_check(rdx, rax); // kills rbx, // rax,: index - __ movl(rax, Address(rdx, rax, Address::times_4, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); + __ movptr(rax, Address(rdx, rax, Address::times_ptr, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); } @@ -576,7 +580,7 @@ void TemplateTable::baload() { // rax,: index // can do better code for P5 - fix this at some point __ load_signed_byte(rbx, Address(rdx, rax, Address::times_1, arrayOopDesc::base_offset_in_bytes(T_BYTE))); - __ movl(rax, rbx); + __ mov(rax, rbx); } @@ -587,7 +591,7 @@ void TemplateTable::caload() { // rax,: index // can do better code for P5 - may want to improve this at some point __ load_unsigned_word(rbx, Address(rdx, rax, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); - __ movl(rax, rbx); + __ mov(rax, rbx); } // iload followed by caload frequent pair @@ -602,7 +606,7 @@ void TemplateTable::fast_icaload() { index_check(rdx, rax); // rax,: index __ load_unsigned_word(rbx, Address(rdx, rax, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); - __ movl(rax, rbx); + __ mov(rax, rbx); } void TemplateTable::saload() { @@ -612,7 +616,7 @@ void TemplateTable::saload() { // rax,: index // can do better code for P5 - may want to improve this at some point __ load_signed_word(rbx, Address(rdx, rax, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_SHORT))); - __ movl(rax, rbx); + __ mov(rax, rbx); } @@ -625,8 +629,8 @@ void TemplateTable::iload(int n) { void TemplateTable::lload(int n) { transition(vtos, ltos); - __ movl(rax, laddress(n)); - __ movl(rdx, haddress(n)); + __ movptr(rax, laddress(n)); + NOT_LP64(__ movptr(rdx, haddress(n))); debug_only(__ verify_local_tag(frame::TagCategory2, n)); } @@ -645,10 +649,10 @@ void TemplateTable::dload(int n) { // float instruction into ST0 __ movl(rax, laddress(n)); __ movl(rdx, haddress(n)); - __ pushl(rdx); // push hi first - __ pushl(rax); + __ push(rdx); // push hi first + __ push(rax); __ fld_d(Address(rsp, 0)); - __ addl(rsp, 2*wordSize); // reset rsp + __ addptr(rsp, 2*wordSize); // reset rsp debug_only(__ verify_local_tag(frame::TagCategory2, n)); } else { __ fld_d(daddress(n)); @@ -658,7 +662,7 @@ void TemplateTable::dload(int n) { void TemplateTable::aload(int n) { transition(vtos, atos); - __ movl(rax, aaddress(n)); + __ movptr(rax, aaddress(n)); debug_only(__ verify_local_tag(frame::TagReference, n)); } @@ -740,8 +744,8 @@ void TemplateTable::istore() { void TemplateTable::lstore() { transition(ltos, vtos); locals_index(rbx); - __ movl(laddress(rbx), rax); - __ movl(haddress(rbx), rdx); + __ movptr(laddress(rbx), rax); + NOT_LP64(__ movptr(haddress(rbx), rdx)); __ tag_local(frame::TagCategory2, rbx); } @@ -759,12 +763,12 @@ void TemplateTable::dstore() { locals_index(rbx); if (TaggedStackInterpreter) { // Store double on stack and reload into locals nonadjacently - __ subl(rsp, 2 * wordSize); + __ subptr(rsp, 2 * wordSize); __ fstp_d(Address(rsp, 0)); - __ popl(rax); - __ popl(rdx); - __ movl(laddress(rbx), rax); - __ movl(haddress(rbx), rdx); + __ pop(rax); + __ pop(rdx); + __ movptr(laddress(rbx), rax); + __ movptr(haddress(rbx), rdx); __ tag_local(frame::TagCategory2, rbx); } else { __ fstp_d(daddress(rbx)); @@ -776,7 +780,7 @@ void TemplateTable::astore() { transition(vtos, vtos); __ pop_ptr(rax, rdx); // will need to pop tag too locals_index(rbx); - __ movl(aaddress(rbx), rax); + __ movptr(aaddress(rbx), rax); __ tag_local(rdx, rbx); // need to store same tag in local may be returnAddr } @@ -794,8 +798,8 @@ void TemplateTable::wide_lstore() { transition(vtos, vtos); __ pop_l(rax, rdx); locals_index_wide(rbx); - __ movl(laddress(rbx), rax); - __ movl(haddress(rbx), rdx); + __ movptr(laddress(rbx), rax); + NOT_LP64(__ movl(haddress(rbx), rdx)); __ tag_local(frame::TagCategory2, rbx); } @@ -814,7 +818,7 @@ void TemplateTable::wide_astore() { transition(vtos, vtos); __ pop_ptr(rax, rdx); locals_index_wide(rbx); - __ movl(aaddress(rbx), rax); + __ movptr(aaddress(rbx), rax); __ tag_local(rdx, rbx); } @@ -838,8 +842,8 @@ void TemplateTable::lastore() { // rdx: high(value) index_check(rcx, rbx); // prefer index in rbx, // rbx,: index - __ movl(Address(rcx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize), rax); - __ movl(Address(rcx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG) + 1 * wordSize), rdx); + __ movptr(Address(rcx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize), rax); + NOT_LP64(__ movl(Address(rcx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG) + 1 * wordSize), rdx)); } @@ -869,21 +873,21 @@ void TemplateTable::aastore() { Label is_null, ok_is_subtype, done; transition(vtos, vtos); // stack: ..., array, index, value - __ movl(rax, at_tos()); // Value + __ movptr(rax, at_tos()); // Value __ movl(rcx, at_tos_p1()); // Index - __ movl(rdx, at_tos_p2()); // Array + __ movptr(rdx, at_tos_p2()); // Array index_check_without_pop(rdx, rcx); // kills rbx, // do array store check - check for NULL value first - __ testl(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, is_null); // Move subklass into EBX - __ movl(rbx, Address(rax, oopDesc::klass_offset_in_bytes())); + __ movptr(rbx, Address(rax, oopDesc::klass_offset_in_bytes())); // Move superklass into EAX - __ movl(rax, Address(rdx, oopDesc::klass_offset_in_bytes())); - __ movl(rax, Address(rax, sizeof(oopDesc) + objArrayKlass::element_klass_offset_in_bytes())); - // Compress array+index*4+12 into a single register. Frees ECX. - __ leal(rdx, Address(rdx, rcx, Address::times_4, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); + __ movptr(rax, Address(rdx, oopDesc::klass_offset_in_bytes())); + __ movptr(rax, Address(rax, sizeof(oopDesc) + objArrayKlass::element_klass_offset_in_bytes())); + // Compress array+index*wordSize+12 into a single register. Frees ECX. + __ lea(rdx, Address(rdx, rcx, Address::times_ptr, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // Generate subtype check. Blows ECX. Resets EDI to locals. // Superklass in EAX. Subklass in EBX. @@ -895,19 +899,19 @@ void TemplateTable::aastore() { // Come here on success __ bind(ok_is_subtype); - __ movl(rax, at_rsp()); // Value - __ movl(Address(rdx, 0), rax); + __ movptr(rax, at_rsp()); // Value + __ movptr(Address(rdx, 0), rax); __ store_check(rdx); __ jmpb(done); // Have a NULL in EAX, EDX=array, ECX=index. Store NULL at ary[idx] __ bind(is_null); __ profile_null_seen(rbx); - __ movl(Address(rdx, rcx, Address::times_4, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), rax); + __ movptr(Address(rdx, rcx, Address::times_ptr, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), rax); // Pop stack arguments __ bind(done); - __ addl(rsp, 3 * Interpreter::stackElementSize()); + __ addptr(rsp, 3 * Interpreter::stackElementSize()); } @@ -947,8 +951,8 @@ void TemplateTable::istore(int n) { void TemplateTable::lstore(int n) { transition(ltos, vtos); - __ movl(laddress(n), rax); - __ movl(haddress(n), rdx); + __ movptr(laddress(n), rax); + NOT_LP64(__ movptr(haddress(n), rdx)); __ tag_local(frame::TagCategory2, n); } @@ -963,10 +967,10 @@ void TemplateTable::fstore(int n) { void TemplateTable::dstore(int n) { transition(dtos, vtos); if (TaggedStackInterpreter) { - __ subl(rsp, 2 * wordSize); + __ subptr(rsp, 2 * wordSize); __ fstp_d(Address(rsp, 0)); - __ popl(rax); - __ popl(rdx); + __ pop(rax); + __ pop(rdx); __ movl(laddress(n), rax); __ movl(haddress(n), rdx); __ tag_local(frame::TagCategory2, n); @@ -979,20 +983,20 @@ void TemplateTable::dstore(int n) { void TemplateTable::astore(int n) { transition(vtos, vtos); __ pop_ptr(rax, rdx); - __ movl(aaddress(n), rax); + __ movptr(aaddress(n), rax); __ tag_local(rdx, n); } void TemplateTable::pop() { transition(vtos, vtos); - __ addl(rsp, Interpreter::stackElementSize()); + __ addptr(rsp, Interpreter::stackElementSize()); } void TemplateTable::pop2() { transition(vtos, vtos); - __ addl(rsp, 2*Interpreter::stackElementSize()); + __ addptr(rsp, 2*Interpreter::stackElementSize()); } @@ -1099,14 +1103,14 @@ void TemplateTable::iop2(Operation op) { transition(itos, itos); switch (op) { case add : __ pop_i(rdx); __ addl (rax, rdx); break; - case sub : __ movl(rdx, rax); __ pop_i(rax); __ subl (rax, rdx); break; + case sub : __ mov(rdx, rax); __ pop_i(rax); __ subl (rax, rdx); break; case mul : __ pop_i(rdx); __ imull(rax, rdx); break; case _and : __ pop_i(rdx); __ andl (rax, rdx); break; case _or : __ pop_i(rdx); __ orl (rax, rdx); break; case _xor : __ pop_i(rdx); __ xorl (rax, rdx); break; - case shl : __ movl(rcx, rax); __ pop_i(rax); __ shll (rax); break; // implicit masking of lower 5 bits by Intel shift instr. - case shr : __ movl(rcx, rax); __ pop_i(rax); __ sarl (rax); break; // implicit masking of lower 5 bits by Intel shift instr. - case ushr : __ movl(rcx, rax); __ pop_i(rax); __ shrl (rax); break; // implicit masking of lower 5 bits by Intel shift instr. + case shl : __ mov(rcx, rax); __ pop_i(rax); __ shll (rax); break; // implicit masking of lower 5 bits by Intel shift instr. + case shr : __ mov(rcx, rax); __ pop_i(rax); __ sarl (rax); break; // implicit masking of lower 5 bits by Intel shift instr. + case ushr : __ mov(rcx, rax); __ pop_i(rax); __ shrl (rax); break; // implicit masking of lower 5 bits by Intel shift instr. default : ShouldNotReachHere(); } } @@ -1118,7 +1122,7 @@ void TemplateTable::lop2(Operation op) { switch (op) { case add : __ addl(rax, rbx); __ adcl(rdx, rcx); break; case sub : __ subl(rbx, rax); __ sbbl(rcx, rdx); - __ movl(rax, rbx); __ movl(rdx, rcx); break; + __ mov(rax, rbx); __ mov(rdx, rcx); break; case _and: __ andl(rax, rbx); __ andl(rdx, rcx); break; case _or : __ orl (rax, rbx); __ orl (rdx, rcx); break; case _xor: __ xorl(rax, rbx); __ xorl(rdx, rcx); break; @@ -1129,7 +1133,7 @@ void TemplateTable::lop2(Operation op) { void TemplateTable::idiv() { transition(itos, itos); - __ movl(rcx, rax); + __ mov(rcx, rax); __ pop_i(rax); // Note: could xor rax, and rcx and compare with (-1 ^ min_int). If // they are not equal, one could do a normal division (no correction @@ -1141,52 +1145,52 @@ void TemplateTable::idiv() { void TemplateTable::irem() { transition(itos, itos); - __ movl(rcx, rax); + __ mov(rcx, rax); __ pop_i(rax); // Note: could xor rax, and rcx and compare with (-1 ^ min_int). If // they are not equal, one could do a normal division (no correction // needed), which may speed up this implementation for the common case. // (see also JVM spec., p.243 & p.271) __ corrected_idivl(rcx); - __ movl(rax, rdx); + __ mov(rax, rdx); } void TemplateTable::lmul() { transition(ltos, ltos); __ pop_l(rbx, rcx); - __ pushl(rcx); __ pushl(rbx); - __ pushl(rdx); __ pushl(rax); + __ push(rcx); __ push(rbx); + __ push(rdx); __ push(rax); __ lmul(2 * wordSize, 0); - __ addl(rsp, 4 * wordSize); // take off temporaries + __ addptr(rsp, 4 * wordSize); // take off temporaries } void TemplateTable::ldiv() { transition(ltos, ltos); __ pop_l(rbx, rcx); - __ pushl(rcx); __ pushl(rbx); - __ pushl(rdx); __ pushl(rax); + __ push(rcx); __ push(rbx); + __ push(rdx); __ push(rax); // check if y = 0 __ orl(rax, rdx); __ jump_cc(Assembler::zero, ExternalAddress(Interpreter::_throw_ArithmeticException_entry)); __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::ldiv)); - __ addl(rsp, 4 * wordSize); // take off temporaries + __ addptr(rsp, 4 * wordSize); // take off temporaries } void TemplateTable::lrem() { transition(ltos, ltos); __ pop_l(rbx, rcx); - __ pushl(rcx); __ pushl(rbx); - __ pushl(rdx); __ pushl(rax); + __ push(rcx); __ push(rbx); + __ push(rdx); __ push(rax); // check if y = 0 __ orl(rax, rdx); __ jump_cc(Assembler::zero, ExternalAddress(Interpreter::_throw_ArithmeticException_entry)); __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::lrem)); - __ addl(rsp, 4 * wordSize); + __ addptr(rsp, 4 * wordSize); } @@ -1200,7 +1204,7 @@ void TemplateTable::lshl() { void TemplateTable::lshr() { transition(itos, ltos); - __ movl(rcx, rax); // get shift count + __ mov(rcx, rax); // get shift count __ pop_l(rax, rdx); // get shift value __ lshr(rdx, rax, true); } @@ -1208,7 +1212,7 @@ void TemplateTable::lshr() { void TemplateTable::lushr() { transition(itos, ltos); - __ movl(rcx, rax); // get shift count + __ mov(rcx, rax); // get shift count __ pop_l(rax, rdx); // get shift value __ lshr(rdx, rax); } @@ -1226,7 +1230,7 @@ void TemplateTable::fop2(Operation op) { default : ShouldNotReachHere(); } __ f2ieee(); - __ popl(rax); // pop float thing off + __ pop(rax); // pop float thing off } @@ -1280,8 +1284,8 @@ void TemplateTable::dop2(Operation op) { } __ d2ieee(); // Pop double precision number from rsp. - __ popl(rax); - __ popl(rdx); + __ pop(rax); + __ pop(rdx); } @@ -1321,7 +1325,7 @@ void TemplateTable::wide_iinc() { transition(vtos, vtos); __ movl(rdx, at_bcp(4)); // get constant locals_index_wide(rbx); - __ bswap(rdx); // swap bytes & sign-extend constant + __ bswapl(rdx); // swap bytes & sign-extend constant __ sarl(rdx, 16); __ addl(iaddress(rbx), rdx); // Note: should probably use only one movl to get both @@ -1375,62 +1379,65 @@ void TemplateTable::convert() { #endif // ASSERT // Conversion - // (Note: use pushl(rcx)/popl(rcx) for 1/2-word stack-ptr manipulation) + // (Note: use push(rcx)/pop(rcx) for 1/2-word stack-ptr manipulation) switch (bytecode()) { case Bytecodes::_i2l: __ extend_sign(rdx, rax); break; case Bytecodes::_i2f: - __ pushl(rax); // store int on tos + __ push(rax); // store int on tos __ fild_s(at_rsp()); // load int to ST0 __ f2ieee(); // truncate to float size - __ popl(rcx); // adjust rsp + __ pop(rcx); // adjust rsp break; case Bytecodes::_i2d: - __ pushl(rax); // add one slot for d2ieee() - __ pushl(rax); // store int on tos + __ push(rax); // add one slot for d2ieee() + __ push(rax); // store int on tos __ fild_s(at_rsp()); // load int to ST0 __ d2ieee(); // truncate to double size - __ popl(rcx); // adjust rsp - __ popl(rcx); + __ pop(rcx); // adjust rsp + __ pop(rcx); break; case Bytecodes::_i2b: __ shll(rax, 24); // truncate upper 24 bits __ sarl(rax, 24); // and sign-extend byte + LP64_ONLY(__ movsbl(rax, rax)); break; case Bytecodes::_i2c: __ andl(rax, 0xFFFF); // truncate upper 16 bits + LP64_ONLY(__ movzwl(rax, rax)); break; case Bytecodes::_i2s: __ shll(rax, 16); // truncate upper 16 bits __ sarl(rax, 16); // and sign-extend short + LP64_ONLY(__ movswl(rax, rax)); break; case Bytecodes::_l2i: /* nothing to do */ break; case Bytecodes::_l2f: - __ pushl(rdx); // store long on tos - __ pushl(rax); + __ push(rdx); // store long on tos + __ push(rax); __ fild_d(at_rsp()); // load long to ST0 __ f2ieee(); // truncate to float size - __ popl(rcx); // adjust rsp - __ popl(rcx); + __ pop(rcx); // adjust rsp + __ pop(rcx); break; case Bytecodes::_l2d: - __ pushl(rdx); // store long on tos - __ pushl(rax); + __ push(rdx); // store long on tos + __ push(rax); __ fild_d(at_rsp()); // load long to ST0 __ d2ieee(); // truncate to double size - __ popl(rcx); // adjust rsp - __ popl(rcx); + __ pop(rcx); // adjust rsp + __ pop(rcx); break; case Bytecodes::_f2i: - __ pushl(rcx); // reserve space for argument + __ push(rcx); // reserve space for argument __ fstp_s(at_rsp()); // pass float argument on stack __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2i), 1); break; case Bytecodes::_f2l: - __ pushl(rcx); // reserve space for argument + __ push(rcx); // reserve space for argument __ fstp_s(at_rsp()); // pass float argument on stack __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2l), 1); break; @@ -1438,21 +1445,21 @@ void TemplateTable::convert() { /* nothing to do */ break; case Bytecodes::_d2i: - __ pushl(rcx); // reserve space for argument - __ pushl(rcx); + __ push(rcx); // reserve space for argument + __ push(rcx); __ fstp_d(at_rsp()); // pass double argument on stack __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2i), 2); break; case Bytecodes::_d2l: - __ pushl(rcx); // reserve space for argument - __ pushl(rcx); + __ push(rcx); // reserve space for argument + __ push(rcx); __ fstp_d(at_rsp()); // pass double argument on stack __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2l), 2); break; case Bytecodes::_d2f: - __ pushl(rcx); // reserve space for f2ieee() + __ push(rcx); // reserve space for f2ieee() __ f2ieee(); // truncate to float size - __ popl(rcx); // adjust rsp + __ pop(rcx); // adjust rsp break; default : ShouldNotReachHere(); @@ -1465,7 +1472,7 @@ void TemplateTable::lcmp() { // y = rdx:rax __ pop_l(rbx, rcx); // get x = rcx:rbx __ lcmp2int(rcx, rbx, rdx, rax);// rcx := cmp(x, y) - __ movl(rax, rcx); + __ mov(rax, rcx); } @@ -1476,9 +1483,9 @@ void TemplateTable::float_cmp(bool is_float, int unordered_result) { } else { __ pop_dtos_to_rsp(); __ fld_d(at_rsp()); - __ popl(rdx); + __ pop(rdx); } - __ popl(rcx); + __ pop(rcx); __ fcmp2int(rax, unordered_result < 0); } @@ -1493,8 +1500,10 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { // Load up EDX with the branch displacement __ movl(rdx, at_bcp(1)); - __ bswap(rdx); + __ bswapl(rdx); if (!is_wide) __ sarl(rdx, 16); + LP64_ONLY(__ movslq(rdx, rdx)); + // Handle all the JSR stuff here, then exit. // It's much shorter and cleaner than intermingling with the @@ -1504,10 +1513,10 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { __ load_unsigned_byte(rbx, Address(rsi, rdx, Address::times_1, 0)); // compute return address as bci in rax, - __ leal(rax, at_bcp((is_wide ? 5 : 3) - in_bytes(constMethodOopDesc::codes_offset()))); - __ subl(rax, Address(rcx, methodOopDesc::const_offset())); + __ lea(rax, at_bcp((is_wide ? 5 : 3) - in_bytes(constMethodOopDesc::codes_offset()))); + __ subptr(rax, Address(rcx, methodOopDesc::const_offset())); // Adjust the bcp in ESI by the displacement in EDX - __ addl(rsi, rdx); + __ addptr(rsi, rdx); // Push return address __ push_i(rax); // jsr returns vtos @@ -1518,7 +1527,7 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { // Normal (non-jsr) branch handling // Adjust the bcp in ESI by the displacement in EDX - __ addl(rsi, rdx); + __ addptr(rsi, rdx); assert(UseLoopCounter || !UseOnStackReplacement, "on-stack-replacement requires loop counters"); Label backedge_counter_overflow; @@ -1537,7 +1546,7 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { // increment counter __ movl(rax, Address(rcx, be_offset)); // load backedge counter - __ increment(rax, InvocationCounter::count_increment); // increment counter + __ incrementl(rax, InvocationCounter::count_increment); // increment counter __ movl(Address(rcx, be_offset), rax); // store counter __ movl(rax, Address(rcx, inv_offset)); // load invocation counter @@ -1565,7 +1574,7 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { // routine while the method is being compiled, add a second test to make // sure the overflow function is called only once every overflow_frequency. const int overflow_frequency = 1024; - __ andl(rbx, overflow_frequency-1); + __ andptr(rbx, overflow_frequency-1); __ jcc(Assembler::zero, backedge_counter_overflow); } @@ -1596,14 +1605,14 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { __ bind(profile_method); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method), rsi); __ load_unsigned_byte(rbx, Address(rsi, 0)); // restore target bytecode - __ movl(rcx, Address(rbp, method_offset)); - __ movl(rcx, Address(rcx, in_bytes(methodOopDesc::method_data_offset()))); - __ movl(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rcx); + __ movptr(rcx, Address(rbp, method_offset)); + __ movptr(rcx, Address(rcx, in_bytes(methodOopDesc::method_data_offset()))); + __ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rcx); __ test_method_data_pointer(rcx, dispatch); // offset non-null mdp by MDO::data_offset() + IR::profile_method() - __ addl(rcx, in_bytes(methodDataOopDesc::data_offset())); - __ addl(rcx, rax); - __ movl(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rcx); + __ addptr(rcx, in_bytes(methodDataOopDesc::data_offset())); + __ addptr(rcx, rax); + __ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rcx); __ jmp(dispatch); } @@ -1611,8 +1620,8 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { // invocation counter overflow __ bind(backedge_counter_overflow); - __ negl(rdx); - __ addl(rdx, rsi); // branch bcp + __ negptr(rdx); + __ addptr(rdx, rsi); // branch bcp call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), rdx); __ load_unsigned_byte(rbx, Address(rsi, 0)); // restore target bytecode @@ -1621,7 +1630,7 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { // rdx: scratch // rdi: locals pointer // rsi: bcp - __ testl(rax, rax); // test result + __ testptr(rax, rax); // test result __ jcc(Assembler::zero, dispatch); // no osr if null // nmethod may have been invalidated (VM may block upon call_VM return) __ movl(rcx, Address(rax, nmethod::entry_bci_offset())); @@ -1632,19 +1641,19 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { // We need to prepare to execute the OSR method. First we must // migrate the locals and monitors off of the stack. - __ movl(rbx, rax); // save the nmethod + __ mov(rbx, rax); // save the nmethod const Register thread = rcx; __ get_thread(thread); call_VM(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::OSR_migration_begin)); // rax, is OSR buffer, move it to expected parameter location - __ movl(rcx, rax); + __ mov(rcx, rax); // pop the interpreter frame - __ movl(rdx, Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); // get sender sp + __ movptr(rdx, Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); // get sender sp __ leave(); // remove frame anchor - __ popl(rdi); // get return address - __ movl(rsp, rdx); // set sp to sender sp + __ pop(rdi); // get return address + __ mov(rsp, rdx); // set sp to sender sp Label skip; @@ -1663,29 +1672,29 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { __ jcc(Assembler::notEqual, chkint); // yes adjust to the specialized call stub return. - assert(StubRoutines::i486::get_call_stub_compiled_return() != NULL, "must be set"); - __ lea(rdi, ExternalAddress(StubRoutines::i486::get_call_stub_compiled_return())); + assert(StubRoutines::x86::get_call_stub_compiled_return() != NULL, "must be set"); + __ lea(rdi, ExternalAddress(StubRoutines::x86::get_call_stub_compiled_return())); __ jmp(skip); __ bind(chkint); // Are we returning to the interpreter? Look for sentinel - __ cmpl(Address(rdi, -8), Interpreter::return_sentinel); + __ cmpl(Address(rdi, -2*wordSize), Interpreter::return_sentinel); __ jcc(Assembler::notEqual, skip); // Adjust to compiled return back to interpreter - __ movl(rdi, Address(rdi, -4)); + __ movptr(rdi, Address(rdi, -wordSize)); __ bind(skip); // Align stack pointer for compiled code (note that caller is // responsible for undoing this fixup by remembering the old SP // in an rbp,-relative location) - __ andl(rsp, -(StackAlignmentInBytes)); + __ andptr(rsp, -(StackAlignmentInBytes)); // push the (possibly adjusted) return address - __ pushl(rdi); + __ push(rdi); // and begin the OSR nmethod __ jmp(Address(rbx, nmethod::osr_entry_point_offset())); @@ -1723,7 +1732,7 @@ void TemplateTable::if_nullcmp(Condition cc) { transition(atos, vtos); // assume branch is more often taken than not (loops use backward branches) Label not_taken; - __ testl(rax, rax); + __ testptr(rax, rax); __ jcc(j_not(cc), not_taken); branch(false, false); __ bind(not_taken); @@ -1736,7 +1745,7 @@ void TemplateTable::if_acmp(Condition cc) { // assume branch is more often taken than not (loops use backward branches) Label not_taken; __ pop_ptr(rdx); - __ cmpl(rdx, rax); + __ cmpptr(rdx, rax); __ jcc(j_not(cc), not_taken); branch(false, false); __ bind(not_taken); @@ -1747,12 +1756,12 @@ void TemplateTable::if_acmp(Condition cc) { void TemplateTable::ret() { transition(vtos, vtos); locals_index(rbx); - __ movl(rbx, iaddress(rbx)); // get return bci, compute return bcp + __ movptr(rbx, iaddress(rbx)); // get return bci, compute return bcp __ profile_ret(rbx, rcx); __ get_method(rax); - __ movl(rsi, Address(rax, methodOopDesc::const_offset())); - __ leal(rsi, Address(rsi, rbx, Address::times_1, - constMethodOopDesc::codes_offset())); + __ movptr(rsi, Address(rax, methodOopDesc::const_offset())); + __ lea(rsi, Address(rsi, rbx, Address::times_1, + constMethodOopDesc::codes_offset())); __ dispatch_next(vtos); } @@ -1760,11 +1769,11 @@ void TemplateTable::ret() { void TemplateTable::wide_ret() { transition(vtos, vtos); locals_index_wide(rbx); - __ movl(rbx, iaddress(rbx)); // get return bci, compute return bcp + __ movptr(rbx, iaddress(rbx)); // get return bci, compute return bcp __ profile_ret(rbx, rcx); __ get_method(rax); - __ movl(rsi, Address(rax, methodOopDesc::const_offset())); - __ leal(rsi, Address(rsi, rbx, Address::times_1, constMethodOopDesc::codes_offset())); + __ movptr(rsi, Address(rax, methodOopDesc::const_offset())); + __ lea(rsi, Address(rsi, rbx, Address::times_1, constMethodOopDesc::codes_offset())); __ dispatch_next(vtos); } @@ -1773,13 +1782,13 @@ void TemplateTable::tableswitch() { Label default_case, continue_execution; transition(itos, vtos); // align rsi - __ leal(rbx, at_bcp(wordSize)); - __ andl(rbx, -wordSize); + __ lea(rbx, at_bcp(wordSize)); + __ andptr(rbx, -wordSize); // load lo & hi __ movl(rcx, Address(rbx, 1 * wordSize)); __ movl(rdx, Address(rbx, 2 * wordSize)); - __ bswap(rcx); - __ bswap(rdx); + __ bswapl(rcx); + __ bswapl(rdx); // check against lo & hi __ cmpl(rax, rcx); __ jccb(Assembler::less, default_case); @@ -1787,13 +1796,13 @@ void TemplateTable::tableswitch() { __ jccb(Assembler::greater, default_case); // lookup dispatch offset __ subl(rax, rcx); - __ movl(rdx, Address(rbx, rax, Address::times_4, 3 * wordSize)); + __ movl(rdx, Address(rbx, rax, Address::times_4, 3 * BytesPerInt)); __ profile_switch_case(rax, rbx, rcx); // continue execution __ bind(continue_execution); - __ bswap(rdx); + __ bswapl(rdx); __ load_unsigned_byte(rbx, Address(rsi, rdx, Address::times_1)); - __ addl(rsi, rdx); + __ addptr(rsi, rdx); __ dispatch_only(vtos); // handle default __ bind(default_case); @@ -1812,21 +1821,21 @@ void TemplateTable::lookupswitch() { void TemplateTable::fast_linearswitch() { transition(itos, vtos); Label loop_entry, loop, found, continue_execution; - // bswap rax, so we can avoid bswapping the table entries - __ bswap(rax); + // bswapl rax, so we can avoid bswapping the table entries + __ bswapl(rax); // align rsi - __ leal(rbx, at_bcp(wordSize)); // btw: should be able to get rid of this instruction (change offsets below) - __ andl(rbx, -wordSize); + __ lea(rbx, at_bcp(wordSize)); // btw: should be able to get rid of this instruction (change offsets below) + __ andptr(rbx, -wordSize); // set counter __ movl(rcx, Address(rbx, wordSize)); - __ bswap(rcx); + __ bswapl(rcx); __ jmpb(loop_entry); // table search __ bind(loop); __ cmpl(rax, Address(rbx, rcx, Address::times_8, 2 * wordSize)); __ jccb(Assembler::equal, found); __ bind(loop_entry); - __ decrement(rcx); + __ decrementl(rcx); __ jcc(Assembler::greaterEqual, loop); // default case __ profile_switch_default(rax); @@ -1838,9 +1847,9 @@ void TemplateTable::fast_linearswitch() { __ profile_switch_case(rcx, rax, rbx); // continue execution __ bind(continue_execution); - __ bswap(rdx); + __ bswapl(rdx); __ load_unsigned_byte(rbx, Address(rsi, rdx, Address::times_1)); - __ addl(rsi, rdx); + __ addptr(rsi, rdx); __ dispatch_only(vtos); } @@ -1882,13 +1891,13 @@ void TemplateTable::fast_binaryswitch() { // setup array __ save_bcp(); - __ leal(array, at_bcp(3*wordSize)); // btw: should be able to get rid of this instruction (change offsets below) - __ andl(array, -wordSize); + __ lea(array, at_bcp(3*wordSize)); // btw: should be able to get rid of this instruction (change offsets below) + __ andptr(array, -wordSize); // initialize i & j __ xorl(i, i); // i = 0; __ movl(j, Address(array, -wordSize)); // j = length(array); // Convert j into native byteordering - __ bswap(j); + __ bswapl(j); // and start Label entry; __ jmp(entry); @@ -1906,19 +1915,19 @@ void TemplateTable::fast_binaryswitch() { // } // Convert array[h].match to native byte-ordering before compare __ movl(temp, Address(array, h, Address::times_8, 0*wordSize)); - __ bswap(temp); + __ bswapl(temp); __ cmpl(key, temp); if (VM_Version::supports_cmov()) { __ cmovl(Assembler::less , j, h); // j = h if (key < array[h].fast_match()) __ cmovl(Assembler::greaterEqual, i, h); // i = h if (key >= array[h].fast_match()) } else { Label set_i, end_of_if; - __ jccb(Assembler::greaterEqual, set_i); // { - __ movl(j, h); // j = h; - __ jmp(end_of_if); // } - __ bind(set_i); // else { - __ movl(i, h); // i = h; - __ bind(end_of_if); // } + __ jccb(Assembler::greaterEqual, set_i); // { + __ mov(j, h); // j = h; + __ jmp(end_of_if); // } + __ bind(set_i); // else { + __ mov(i, h); // i = h; + __ bind(end_of_if); // } } // while (i+1 < j) __ bind(entry); @@ -1931,30 +1940,32 @@ void TemplateTable::fast_binaryswitch() { Label default_case; // Convert array[i].match to native byte-ordering before compare __ movl(temp, Address(array, i, Address::times_8, 0*wordSize)); - __ bswap(temp); + __ bswapl(temp); __ cmpl(key, temp); __ jcc(Assembler::notEqual, default_case); // entry found -> j = offset __ movl(j , Address(array, i, Address::times_8, 1*wordSize)); __ profile_switch_case(i, key, array); - __ bswap(j); + __ bswapl(j); + LP64_ONLY(__ movslq(j, j)); __ restore_bcp(); __ restore_locals(); // restore rdi __ load_unsigned_byte(rbx, Address(rsi, j, Address::times_1)); - __ addl(rsi, j); + __ addptr(rsi, j); __ dispatch_only(vtos); // default case -> j = default offset __ bind(default_case); __ profile_switch_default(i); __ movl(j, Address(array, -2*wordSize)); - __ bswap(j); + __ bswapl(j); + LP64_ONLY(__ movslq(j, j)); __ restore_bcp(); __ restore_locals(); // restore rdi __ load_unsigned_byte(rbx, Address(rsi, j, Address::times_1)); - __ addl(rsi, j); + __ addptr(rsi, j); __ dispatch_only(vtos); } @@ -1965,8 +1976,8 @@ void TemplateTable::_return(TosState state) { if (_desc->bytecode() == Bytecodes::_return_register_finalizer) { assert(state == vtos, "only valid state"); - __ movl(rax, aaddress(0)); - __ movl(rdi, Address(rax, oopDesc::klass_offset_in_bytes())); + __ movptr(rax, aaddress(0)); + __ movptr(rdi, Address(rax, oopDesc::klass_offset_in_bytes())); __ movl(rdi, Address(rdi, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc))); __ testl(rdi, JVM_ACC_HAS_FINALIZER); Label skip_register_finalizer; @@ -2007,10 +2018,10 @@ void TemplateTable::_return(TosState state) { // requirement (1) but miss the volatile-store-volatile-load case. This final // case is placed after volatile-stores although it could just as well go // before volatile-loads. -void TemplateTable::volatile_barrier( ) { +void TemplateTable::volatile_barrier(Assembler::Membar_mask_bits order_constraint ) { // Helper function to insert a is-volatile test and memory barrier if( !os::is_MP() ) return; // Not needed on single CPU - __ membar(); + __ membar(order_constraint); } void TemplateTable::resolve_cache_and_index(int byte_no, Register Rcache, Register index) { @@ -2023,10 +2034,13 @@ void TemplateTable::resolve_cache_and_index(int byte_no, Register Rcache, Regist const int shift_count = (1 + byte_no)*BitsPerByte; Label resolved; __ get_cache_and_index_at_bcp(Rcache, index, 1); - __ movl(temp, Address(Rcache, index, Address::times_4, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset())); + __ movl(temp, Address(Rcache, + index, + Address::times_ptr, + constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset())); __ shrl(temp, shift_count); // have we resolved this bytecode? - __ andl(temp, 0xFF); + __ andptr(temp, 0xFF); __ cmpl(temp, (int)bytecode()); __ jcc(Assembler::equal, resolved); @@ -2062,16 +2076,16 @@ void TemplateTable::load_field_cp_cache_entry(Register obj, ByteSize cp_base_offset = constantPoolCacheOopDesc::base_offset(); // Field offset - __ movl(off, Address(cache, index, Address::times_4, - in_bytes(cp_base_offset + ConstantPoolCacheEntry::f2_offset()))); + __ movptr(off, Address(cache, index, Address::times_ptr, + in_bytes(cp_base_offset + ConstantPoolCacheEntry::f2_offset()))); // Flags - __ movl(flags, Address(cache, index, Address::times_4, + __ movl(flags, Address(cache, index, Address::times_ptr, in_bytes(cp_base_offset + ConstantPoolCacheEntry::flags_offset()))); // klass overwrite register if (is_static) { - __ movl(obj, Address(cache, index, Address::times_4, - in_bytes(cp_base_offset + ConstantPoolCacheEntry::f1_offset()))); + __ movptr(obj, Address(cache, index, Address::times_ptr, + in_bytes(cp_base_offset + ConstantPoolCacheEntry::f1_offset()))); } } @@ -2104,12 +2118,11 @@ void TemplateTable::load_invoke_cp_cache_entry(int byte_no, resolve_cache_and_index(byte_no, cache, index); - assert(wordSize == 4, "adjust code below"); - __ movl(method, Address(cache, index, Address::times_4, method_offset)); + __ movptr(method, Address(cache, index, Address::times_ptr, method_offset)); if (itable_index != noreg) { - __ movl(itable_index, Address(cache, index, Address::times_4, index_offset)); + __ movptr(itable_index, Address(cache, index, Address::times_ptr, index_offset)); } - __ movl(flags , Address(cache, index, Address::times_4, flags_offset )); + __ movl(flags , Address(cache, index, Address::times_ptr, flags_offset )); } @@ -2129,11 +2142,11 @@ void TemplateTable::jvmti_post_field_access(Register cache, __ jcc(Assembler::zero, L1); // cache entry pointer - __ addl(cache, in_bytes(constantPoolCacheOopDesc::base_offset())); + __ addptr(cache, in_bytes(constantPoolCacheOopDesc::base_offset())); __ shll(index, LogBytesPerWord); - __ addl(cache, index); + __ addptr(cache, index); if (is_static) { - __ movl(rax, 0); // NULL object reference + __ xorptr(rax, rax); // NULL object reference } else { __ pop(atos); // Get the object __ verify_oop(rax); @@ -2177,7 +2190,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) { __ shrl(flags, ConstantPoolCacheEntry::tosBits); assert(btos == 0, "change code, btos != 0"); // btos - __ andl(flags, 0x0f); + __ andptr(flags, 0x0f); __ jcc(Assembler::notZero, notByte); __ load_signed_byte(rax, lo ); @@ -2245,10 +2258,10 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) { // Generate code as if volatile. There just aren't enough registers to // save that information and this code is faster than the test. __ fild_d(lo); // Must load atomically - __ subl(rsp,2*wordSize); // Make space for store + __ subptr(rsp,2*wordSize); // Make space for store __ fistp_d(Address(rsp,0)); - __ popl(rax); - __ popl(rdx); + __ pop(rax); + __ pop(rdx); __ push(ltos); // Don't rewrite to _fast_lgetfield for potential volatile case. @@ -2319,16 +2332,16 @@ void TemplateTable::jvmti_post_field_mod(Register cache, Register index, bool is if (is_static) { // Life is simple. Null out the object pointer. - __ xorl(rbx, rbx); + __ xorptr(rbx, rbx); } else { // Life is harder. The stack holds the value on top, followed by the object. // We don't know the size of the value, though; it could be one or two words // depending on its type. As a result, we must find the type to determine where // the object is. Label two_word, valsize_known; - __ movl(rcx, Address(rax, rdx, Address::times_4, in_bytes(cp_base_offset + + __ movl(rcx, Address(rax, rdx, Address::times_ptr, in_bytes(cp_base_offset + ConstantPoolCacheEntry::flags_offset()))); - __ movl(rbx, rsp); + __ mov(rbx, rsp); __ shrl(rcx, ConstantPoolCacheEntry::tosBits); // Make sure we don't need to mask rcx for tosBits after the above shift ConstantPoolCacheEntry::verify_tosBits(); @@ -2336,22 +2349,22 @@ void TemplateTable::jvmti_post_field_mod(Register cache, Register index, bool is __ jccb(Assembler::equal, two_word); __ cmpl(rcx, dtos); __ jccb(Assembler::equal, two_word); - __ addl(rbx, Interpreter::expr_offset_in_bytes(1)); // one word jvalue (not ltos, dtos) + __ addptr(rbx, Interpreter::expr_offset_in_bytes(1)); // one word jvalue (not ltos, dtos) __ jmpb(valsize_known); __ bind(two_word); - __ addl(rbx, Interpreter::expr_offset_in_bytes(2)); // two words jvalue + __ addptr(rbx, Interpreter::expr_offset_in_bytes(2)); // two words jvalue __ bind(valsize_known); // setup object pointer - __ movl(rbx, Address(rbx, 0)); + __ movptr(rbx, Address(rbx, 0)); } // cache entry pointer - __ addl(rax, in_bytes(cp_base_offset)); + __ addptr(rax, in_bytes(cp_base_offset)); __ shll(rdx, LogBytesPerWord); - __ addl(rax, rdx); + __ addptr(rax, rdx); // object (tos) - __ movl(rcx, rsp); + __ mov(rcx, rsp); // rbx,: object pointer set up above (NULL if static) // rax,: cache entry pointer // rcx: jvalue object on the stack @@ -2426,7 +2439,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) { __ pop(atos); if (!is_static) pop_and_check_object(obj); - __ movl(lo, rax ); + __ movptr(lo, rax ); __ store_check(obj, lo); // Need to mark card if (!is_static) { patch_bytecode(Bytecodes::_fast_aputfield, rcx, rbx); @@ -2472,12 +2485,14 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) { if (!is_static) pop_and_check_object(obj); // Replace with real volatile test - __ pushl(rdx); - __ pushl(rax); // Must update atomically with FIST + __ push(rdx); + __ push(rax); // Must update atomically with FIST __ fild_d(Address(rsp,0)); // So load into FPU register __ fistp_d(lo); // and put into memory atomically - __ addl(rsp,2*wordSize); - volatile_barrier(); + __ addptr(rsp, 2*wordSize); + // volatile_barrier(); + volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad | + Assembler::StoreStore)); // Don't rewrite volatile version __ jmp(notVolatile); @@ -2485,8 +2500,8 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) { __ pop(ltos); // overwrites rdx if (!is_static) pop_and_check_object(obj); - __ movl(hi, rdx); - __ movl(lo, rax); + NOT_LP64(__ movptr(hi, rdx)); + __ movptr(lo, rax); if (!is_static) { patch_bytecode(Bytecodes::_fast_lputfield, rcx, rbx); } @@ -2527,7 +2542,8 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) { // Check for volatile store __ testl(rdx, rdx); __ jcc(Assembler::zero, notVolatile); - volatile_barrier( ); + volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad | + Assembler::StoreStore)); __ bind(notVolatile); } @@ -2552,10 +2568,10 @@ void TemplateTable::jvmti_post_fast_field_mod() { __ pop_ptr(rbx); // copy the object pointer from tos __ verify_oop(rbx); __ push_ptr(rbx); // put the object pointer back on tos - __ subl(rsp, sizeof(jvalue)); // add space for a jvalue object - __ movl(rcx, rsp); + __ subptr(rsp, sizeof(jvalue)); // add space for a jvalue object + __ mov(rcx, rsp); __ push_ptr(rbx); // save object pointer so we can steal rbx, - __ movl(rbx, 0); + __ xorptr(rbx, rbx); const Address lo_value(rcx, rbx, Address::times_1, 0*wordSize); const Address hi_value(rcx, rbx, Address::times_1, 1*wordSize); switch (bytecode()) { // load values into the jvalue object @@ -2563,21 +2579,28 @@ void TemplateTable::jvmti_post_fast_field_mod() { case Bytecodes::_fast_sputfield: __ movw(lo_value, rax); break; case Bytecodes::_fast_cputfield: __ movw(lo_value, rax); break; case Bytecodes::_fast_iputfield: __ movl(lo_value, rax); break; - case Bytecodes::_fast_lputfield: __ movl(hi_value, rdx); __ movl(lo_value, rax); break; + case Bytecodes::_fast_lputfield: + NOT_LP64(__ movptr(hi_value, rdx)); + __ movptr(lo_value, rax); + break; + // need to call fld_s() after fstp_s() to restore the value for below case Bytecodes::_fast_fputfield: __ fstp_s(lo_value); __ fld_s(lo_value); break; + // need to call fld_d() after fstp_d() to restore the value for below case Bytecodes::_fast_dputfield: __ fstp_d(lo_value); __ fld_d(lo_value); break; + // since rcx is not an object we don't call store_check() here - case Bytecodes::_fast_aputfield: __ movl(lo_value, rax); break; + case Bytecodes::_fast_aputfield: __ movptr(lo_value, rax); break; + default: ShouldNotReachHere(); } __ pop_ptr(rbx); // restore copy of object pointer // Save rax, and sometimes rdx because call_VM() will clobber them, // then use them for JVM/DI purposes - __ pushl(rax); - if (bytecode() == Bytecodes::_fast_lputfield) __ pushl(rdx); + __ push(rax); + if (bytecode() == Bytecodes::_fast_lputfield) __ push(rdx); // access constant pool cache entry __ get_cache_entry_pointer_at_bcp(rax, rdx, 1); __ verify_oop(rbx); @@ -2585,9 +2608,9 @@ void TemplateTable::jvmti_post_fast_field_mod() { // rax,: cache entry pointer // rcx: jvalue object on the stack __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_modification), rbx, rax, rcx); - if (bytecode() == Bytecodes::_fast_lputfield) __ popl(rdx); // restore high value - __ popl(rax); // restore lower value - __ addl(rsp, sizeof(jvalue)); // release jvalue object space + if (bytecode() == Bytecodes::_fast_lputfield) __ pop(rdx); // restore high value + __ pop(rax); // restore lower value + __ addptr(rsp, sizeof(jvalue)); // release jvalue object space __ bind(L2); } } @@ -2603,12 +2626,12 @@ void TemplateTable::fast_storefield(TosState state) { __ get_cache_and_index_at_bcp(rcx, rbx, 1); // test for volatile with rdx but rdx is tos register for lputfield. - if (bytecode() == Bytecodes::_fast_lputfield) __ pushl(rdx); - __ movl(rdx, Address(rcx, rbx, Address::times_4, in_bytes(base + + if (bytecode() == Bytecodes::_fast_lputfield) __ push(rdx); + __ movl(rdx, Address(rcx, rbx, Address::times_ptr, in_bytes(base + ConstantPoolCacheEntry::flags_offset()))); // replace index with field offset from cache entry - __ movl(rbx, Address(rcx, rbx, Address::times_4, in_bytes(base + ConstantPoolCacheEntry::f2_offset()))); + __ movptr(rbx, Address(rcx, rbx, Address::times_ptr, in_bytes(base + ConstantPoolCacheEntry::f2_offset()))); // Doug Lea believes this is not needed with current Sparcs (TSO) and Intel (PSO). // volatile_barrier( ); @@ -2620,7 +2643,7 @@ void TemplateTable::fast_storefield(TosState state) { __ testl(rdx, rdx); __ jcc(Assembler::zero, notVolatile); - if (bytecode() == Bytecodes::_fast_lputfield) __ popl(rdx); + if (bytecode() == Bytecodes::_fast_lputfield) __ pop(rdx); // Get object from stack pop_and_check_object(rcx); @@ -2635,22 +2658,26 @@ void TemplateTable::fast_storefield(TosState state) { case Bytecodes::_fast_sputfield: // fall through case Bytecodes::_fast_cputfield: __ movw(lo, rax); break; case Bytecodes::_fast_iputfield: __ movl(lo, rax); break; - case Bytecodes::_fast_lputfield: __ movl(hi, rdx); __ movl(lo, rax); break; + case Bytecodes::_fast_lputfield: + NOT_LP64(__ movptr(hi, rdx)); + __ movptr(lo, rax); + break; case Bytecodes::_fast_fputfield: __ fstp_s(lo); break; case Bytecodes::_fast_dputfield: __ fstp_d(lo); break; - case Bytecodes::_fast_aputfield: __ movl(lo, rax); __ store_check(rcx, lo); break; + case Bytecodes::_fast_aputfield: __ movptr(lo, rax); __ store_check(rcx, lo); break; default: ShouldNotReachHere(); } Label done; - volatile_barrier( ); + volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad | + Assembler::StoreStore)); __ jmpb(done); // Same code as above, but don't need rdx to test for volatile. __ bind(notVolatile); - if (bytecode() == Bytecodes::_fast_lputfield) __ popl(rdx); + if (bytecode() == Bytecodes::_fast_lputfield) __ pop(rdx); // Get object from stack pop_and_check_object(rcx); @@ -2661,10 +2688,13 @@ void TemplateTable::fast_storefield(TosState state) { case Bytecodes::_fast_sputfield: // fall through case Bytecodes::_fast_cputfield: __ movw(lo, rax); break; case Bytecodes::_fast_iputfield: __ movl(lo, rax); break; - case Bytecodes::_fast_lputfield: __ movl(hi, rdx); __ movl(lo, rax); break; + case Bytecodes::_fast_lputfield: + NOT_LP64(__ movptr(hi, rdx)); + __ movptr(lo, rax); + break; case Bytecodes::_fast_fputfield: __ fstp_s(lo); break; case Bytecodes::_fast_dputfield: __ fstp_d(lo); break; - case Bytecodes::_fast_aputfield: __ movl(lo, rax); __ store_check(rcx, lo); break; + case Bytecodes::_fast_aputfield: __ movptr(lo, rax); __ store_check(rcx, lo); break; default: ShouldNotReachHere(); } @@ -2697,7 +2727,10 @@ void TemplateTable::fast_accessfield(TosState state) { // access constant pool cache __ get_cache_and_index_at_bcp(rcx, rbx, 1); // replace index with field offset from cache entry - __ movl(rbx, Address(rcx, rbx, Address::times_4, in_bytes(constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f2_offset()))); + __ movptr(rbx, Address(rcx, + rbx, + Address::times_ptr, + in_bytes(constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f2_offset()))); // rax,: object @@ -2709,14 +2742,14 @@ void TemplateTable::fast_accessfield(TosState state) { // access field switch (bytecode()) { - case Bytecodes::_fast_bgetfield: __ movsxb(rax, lo ); break; + case Bytecodes::_fast_bgetfield: __ movsbl(rax, lo ); break; case Bytecodes::_fast_sgetfield: __ load_signed_word(rax, lo ); break; case Bytecodes::_fast_cgetfield: __ load_unsigned_word(rax, lo ); break; case Bytecodes::_fast_igetfield: __ movl(rax, lo); break; case Bytecodes::_fast_lgetfield: __ stop("should not be rewritten"); break; case Bytecodes::_fast_fgetfield: __ fld_s(lo); break; case Bytecodes::_fast_dgetfield: __ fld_d(lo); break; - case Bytecodes::_fast_agetfield: __ movl(rax, lo); __ verify_oop(rax); break; + case Bytecodes::_fast_agetfield: __ movptr(rax, lo); __ verify_oop(rax); break; default: ShouldNotReachHere(); } @@ -2728,11 +2761,14 @@ void TemplateTable::fast_accessfield(TosState state) { void TemplateTable::fast_xaccess(TosState state) { transition(vtos, state); // get receiver - __ movl(rax, aaddress(0)); + __ movptr(rax, aaddress(0)); debug_only(__ verify_local_tag(frame::TagReference, 0)); // access constant pool cache __ get_cache_and_index_at_bcp(rcx, rdx, 2); - __ movl(rbx, Address(rcx, rdx, Address::times_4, in_bytes(constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f2_offset()))); + __ movptr(rbx, Address(rcx, + rdx, + Address::times_ptr, + in_bytes(constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f2_offset()))); // make sure exception is reported in correct bcp range (getfield is next instruction) __ increment(rsi); __ null_check(rax); @@ -2740,7 +2776,7 @@ void TemplateTable::fast_xaccess(TosState state) { if (state == itos) { __ movl(rax, lo); } else if (state == atos) { - __ movl(rax, lo); + __ movptr(rax, lo); __ verify_oop(rax); } else if (state == ftos) { __ fld_s(lo); @@ -2784,7 +2820,7 @@ void TemplateTable::prepare_invoke(Register method, Register index, int byte_no, __ movl(recv, flags); __ andl(recv, 0xFF); // recv count is 0 based? - __ movl(recv, Address(rsp, recv, Interpreter::stackElementScale(), -Interpreter::expr_offset_in_bytes(1))); + __ movptr(recv, Address(rsp, recv, Interpreter::stackElementScale(), -Interpreter::expr_offset_in_bytes(1))); __ verify_oop(recv); } @@ -2794,7 +2830,7 @@ void TemplateTable::prepare_invoke(Register method, Register index, int byte_no, } if (save_flags) { - __ movl(rsi, flags); + __ mov(rsi, flags); } // compute return type @@ -2802,20 +2838,19 @@ void TemplateTable::prepare_invoke(Register method, Register index, int byte_no, // Make sure we don't need to mask flags for tosBits after the above shift ConstantPoolCacheEntry::verify_tosBits(); // load return address - { const int table = - is_invokeinterface - ? (int)Interpreter::return_5_addrs_by_index_table() - : (int)Interpreter::return_3_addrs_by_index_table(); - __ movl(flags, Address(noreg, flags, Address::times_4, table)); + { + ExternalAddress table(is_invokeinterface ? (address)Interpreter::return_5_addrs_by_index_table() : + (address)Interpreter::return_3_addrs_by_index_table()); + __ movptr(flags, ArrayAddress(table, Address(noreg, flags, Address::times_ptr))); } // push return address - __ pushl(flags); + __ push(flags); // Restore flag value from the constant pool cache, and restore rsi // for later null checks. rsi is the bytecode pointer if (save_flags) { - __ movl(flags, rsi); + __ mov(flags, rsi); __ restore_bcp(); } } @@ -2852,7 +2887,7 @@ void TemplateTable::invokevirtual_helper(Register index, Register recv, // get receiver klass __ null_check(recv, oopDesc::klass_offset_in_bytes()); // Keep recv in rcx for callee expects it there - __ movl(rax, Address(recv, oopDesc::klass_offset_in_bytes())); + __ movptr(rax, Address(recv, oopDesc::klass_offset_in_bytes())); __ verify_oop(rax); // profile this call @@ -2861,7 +2896,7 @@ void TemplateTable::invokevirtual_helper(Register index, Register recv, // get target methodOop & entry point const int base = instanceKlass::vtable_start_offset() * wordSize; assert(vtableEntry::size() * wordSize == 4, "adjust the scaling in the code below"); - __ movl(method, Address(rax, index, Address::times_4, base + vtableEntry::method_offset_in_bytes())); + __ movptr(method, Address(rax, index, Address::times_ptr, base + vtableEntry::method_offset_in_bytes())); __ jump_from_interpreted(method, rdx); } @@ -2927,19 +2962,19 @@ void TemplateTable::invokeinterface(int byte_no) { // Get receiver klass into rdx - also a null check __ restore_locals(); // restore rdi - __ movl(rdx, Address(rcx, oopDesc::klass_offset_in_bytes())); + __ movptr(rdx, Address(rcx, oopDesc::klass_offset_in_bytes())); __ verify_oop(rdx); // profile this call __ profile_virtual_call(rdx, rsi, rdi); - __ movl(rdi, rdx); // Save klassOop in rdi + __ mov(rdi, rdx); // Save klassOop in rdi // Compute start of first itableOffsetEntry (which is at the end of the vtable) const int base = instanceKlass::vtable_start_offset() * wordSize; - assert(vtableEntry::size() * wordSize == 4, "adjust the scaling in the code below"); + assert(vtableEntry::size() * wordSize == (1 << (int)Address::times_ptr), "adjust the scaling in the code below"); __ movl(rsi, Address(rdx, instanceKlass::vtable_length_offset() * wordSize)); // Get length of vtable - __ leal(rdx, Address(rdx, rsi, Address::times_4, base)); + __ lea(rdx, Address(rdx, rsi, Address::times_4, base)); if (HeapWordsPerLong > 1) { // Round up to align_object_offset boundary __ round_to(rdx, BytesPerLong); @@ -2949,20 +2984,20 @@ void TemplateTable::invokeinterface(int byte_no) { __ jmpb(entry); __ bind(search); - __ addl(rdx, itableOffsetEntry::size() * wordSize); + __ addptr(rdx, itableOffsetEntry::size() * wordSize); __ bind(entry); // Check that the entry is non-null. A null entry means that the receiver // class doesn't implement the interface, and wasn't the same as the // receiver class checked when the interface was resolved. - __ pushl(rdx); - __ movl(rdx, Address(rdx, itableOffsetEntry::interface_offset_in_bytes())); - __ testl(rdx, rdx); + __ push(rdx); + __ movptr(rdx, Address(rdx, itableOffsetEntry::interface_offset_in_bytes())); + __ testptr(rdx, rdx); __ jcc(Assembler::notZero, interface_ok); // throw exception - __ popl(rdx); // pop saved register first. - __ popl(rbx); // pop return address (pushed by prepare_invoke) + __ pop(rdx); // pop saved register first. + __ pop(rbx); // pop return address (pushed by prepare_invoke) __ restore_bcp(); // rsi must be correct for exception handler (was destroyed) __ restore_locals(); // make sure locals pointer is correct as well (was destroyed) __ call_VM(noreg, CAST_FROM_FN_PTR(address, @@ -2971,15 +3006,15 @@ void TemplateTable::invokeinterface(int byte_no) { __ should_not_reach_here(); __ bind(interface_ok); - __ popl(rdx); + __ pop(rdx); - __ cmpl(rax, Address(rdx, itableOffsetEntry::interface_offset_in_bytes())); + __ cmpptr(rax, Address(rdx, itableOffsetEntry::interface_offset_in_bytes())); __ jcc(Assembler::notEqual, search); __ movl(rdx, Address(rdx, itableOffsetEntry::offset_offset_in_bytes())); - __ addl(rdx, rdi); // Add offset to klassOop - assert(itableMethodEntry::size() * wordSize == 4, "adjust the scaling in the code below"); - __ movl(rbx, Address(rdx, rbx, Address::times_4)); + __ addptr(rdx, rdi); // Add offset to klassOop + assert(itableMethodEntry::size() * wordSize == (1 << (int)Address::times_ptr), "adjust the scaling in the code below"); + __ movptr(rbx, Address(rdx, rbx, Address::times_ptr)); // rbx,: methodOop to call // rcx: receiver // Check for abstract method error @@ -2987,12 +3022,12 @@ void TemplateTable::invokeinterface(int byte_no) { // interpreter entry point and a conditional jump to it in case of a null // method. { Label L; - __ testl(rbx, rbx); + __ testptr(rbx, rbx); __ jcc(Assembler::notZero, L); // throw exception // note: must restore interpreter registers to canonical // state for exception handling to work correctly! - __ popl(rbx); // pop return address (pushed by prepare_invoke) + __ pop(rbx); // pop return address (pushed by prepare_invoke) __ restore_bcp(); // rsi must be correct for exception handler (was destroyed) __ restore_locals(); // make sure locals pointer is correct as well (was destroyed) __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError)); @@ -3023,8 +3058,8 @@ void TemplateTable::_new() { __ get_cpool_and_tags(rcx, rax); // get instanceKlass - __ movl(rcx, Address(rcx, rdx, Address::times_4, sizeof(constantPoolOopDesc))); - __ pushl(rcx); // save the contexts of klass for initializing the header + __ movptr(rcx, Address(rcx, rdx, Address::times_ptr, sizeof(constantPoolOopDesc))); + __ push(rcx); // save the contexts of klass for initializing the header // make sure the class we're about to instantiate has been resolved. // Note: slow_case does a pop of stack, which is why we loaded class/pushed above @@ -3057,11 +3092,11 @@ void TemplateTable::_new() { const Register thread = rcx; __ get_thread(thread); - __ movl(rax, Address(thread, in_bytes(JavaThread::tlab_top_offset()))); - __ leal(rbx, Address(rax, rdx, Address::times_1)); - __ cmpl(rbx, Address(thread, in_bytes(JavaThread::tlab_end_offset()))); + __ movptr(rax, Address(thread, in_bytes(JavaThread::tlab_top_offset()))); + __ lea(rbx, Address(rax, rdx, Address::times_1)); + __ cmpptr(rbx, Address(thread, in_bytes(JavaThread::tlab_end_offset()))); __ jcc(Assembler::above, allow_shared_alloc ? allocate_shared : slow_case); - __ movl(Address(thread, in_bytes(JavaThread::tlab_top_offset())), rbx); + __ movptr(Address(thread, in_bytes(JavaThread::tlab_top_offset())), rbx); if (ZeroTLAB) { // the fields have been already cleared __ jmp(initialize_header); @@ -3079,9 +3114,9 @@ void TemplateTable::_new() { Label retry; __ bind(retry); - __ mov32(rax, heap_top); - __ leal(rbx, Address(rax, rdx, Address::times_1)); - __ cmp32(rbx, ExternalAddress((address)Universe::heap()->end_addr())); + __ movptr(rax, heap_top); + __ lea(rbx, Address(rax, rdx, Address::times_1)); + __ cmpptr(rbx, ExternalAddress((address)Universe::heap()->end_addr())); __ jcc(Assembler::above, slow_case); // Compare rax, with the top addr, and if still equal, store the new @@ -3091,8 +3126,7 @@ void TemplateTable::_new() { // rax,: object begin // rbx,: object end // rdx: instance size in bytes - if (os::is_MP()) __ lock(); - __ cmpxchgptr(rbx, heap_top); + __ locked_cmpxchgptr(rbx, heap_top); // if someone beat us on the allocation, try again, otherwise continue __ jcc(Assembler::notEqual, retry); @@ -3124,8 +3158,8 @@ void TemplateTable::_new() { // initialize remaining object fields: rdx was a multiple of 8 { Label loop; __ bind(loop); - __ movl(Address(rax, rdx, Address::times_8, sizeof(oopDesc) - 1*oopSize), rcx); - __ movl(Address(rax, rdx, Address::times_8, sizeof(oopDesc) - 2*oopSize), rcx); + __ movptr(Address(rax, rdx, Address::times_8, sizeof(oopDesc) - 1*oopSize), rcx); + NOT_LP64(__ movptr(Address(rax, rdx, Address::times_8, sizeof(oopDesc) - 2*oopSize), rcx)); __ decrement(rdx); __ jcc(Assembler::notZero, loop); } @@ -3133,15 +3167,15 @@ void TemplateTable::_new() { // initialize object header only. __ bind(initialize_header); if (UseBiasedLocking) { - __ popl(rcx); // get saved klass back in the register. - __ movl(rbx, Address(rcx, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); - __ movl(Address(rax, oopDesc::mark_offset_in_bytes ()), rbx); + __ pop(rcx); // get saved klass back in the register. + __ movptr(rbx, Address(rcx, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + __ movptr(Address(rax, oopDesc::mark_offset_in_bytes ()), rbx); } else { - __ movl(Address(rax, oopDesc::mark_offset_in_bytes ()), - (int)markOopDesc::prototype()); // header - __ popl(rcx); // get saved klass back in the register. + __ movptr(Address(rax, oopDesc::mark_offset_in_bytes ()), + (int32_t)markOopDesc::prototype()); // header + __ pop(rcx); // get saved klass back in the register. } - __ movl(Address(rax, oopDesc::klass_offset_in_bytes()), rcx); // klass + __ movptr(Address(rax, oopDesc::klass_offset_in_bytes()), rcx); // klass { SkipIfEqual skip_if(_masm, &DTraceAllocProbes, 0); @@ -3157,7 +3191,7 @@ void TemplateTable::_new() { // slow case __ bind(slow_case); - __ popl(rcx); // restore stack pointer to what it was when we came in. + __ pop(rcx); // restore stack pointer to what it was when we came in. __ get_constant_pool(rax); __ get_unsigned_2_byte_index_at_bcp(rdx, 1); call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::_new), rax, rdx); @@ -3194,7 +3228,7 @@ void TemplateTable::arraylength() { void TemplateTable::checkcast() { transition(atos, atos); Label done, is_null, ok_is_subtype, quicked, resolved; - __ testl(rax, rax); // Object is in EAX + __ testptr(rax, rax); // Object is in EAX __ jcc(Assembler::zero, is_null); // Get cpool & tags index @@ -3211,24 +3245,24 @@ void TemplateTable::checkcast() { // Get superklass in EAX and subklass in EBX __ bind(quicked); - __ movl(rdx, rax); // Save object in EDX; EAX needed for subtype check - __ movl(rax, Address(rcx, rbx, Address::times_4, sizeof(constantPoolOopDesc))); + __ mov(rdx, rax); // Save object in EDX; EAX needed for subtype check + __ movptr(rax, Address(rcx, rbx, Address::times_ptr, sizeof(constantPoolOopDesc))); __ bind(resolved); - __ movl(rbx, Address(rdx, oopDesc::klass_offset_in_bytes())); + __ movptr(rbx, Address(rdx, oopDesc::klass_offset_in_bytes())); // Generate subtype check. Blows ECX. Resets EDI. Object in EDX. // Superklass in EAX. Subklass in EBX. __ gen_subtype_check( rbx, ok_is_subtype ); // Come here on failure - __ pushl(rdx); + __ push(rdx); // object is at TOS __ jump(ExternalAddress(Interpreter::_throw_ClassCastException_entry)); // Come here on success __ bind(ok_is_subtype); - __ movl(rax,rdx); // Restore object in EDX + __ mov(rax,rdx); // Restore object in EDX // Collect counts on whether this check-cast sees NULLs a lot or not. if (ProfileInterpreter) { @@ -3245,7 +3279,7 @@ void TemplateTable::checkcast() { void TemplateTable::instanceof() { transition(atos, itos); Label done, is_null, ok_is_subtype, quicked, resolved; - __ testl(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, is_null); // Get cpool & tags index @@ -3258,13 +3292,13 @@ void TemplateTable::instanceof() { __ push(atos); call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc) ); __ pop_ptr(rdx); - __ movl(rdx, Address(rdx, oopDesc::klass_offset_in_bytes())); + __ movptr(rdx, Address(rdx, oopDesc::klass_offset_in_bytes())); __ jmp(resolved); // Get superklass in EAX and subklass in EDX __ bind(quicked); - __ movl(rdx, Address(rax, oopDesc::klass_offset_in_bytes())); - __ movl(rax, Address(rcx, rbx, Address::times_4, sizeof(constantPoolOopDesc))); + __ movptr(rdx, Address(rax, oopDesc::klass_offset_in_bytes())); + __ movptr(rax, Address(rcx, rbx, Address::times_ptr, sizeof(constantPoolOopDesc))); __ bind(resolved); @@ -3306,7 +3340,7 @@ void TemplateTable::_breakpoint() { // get the unpatched byte code __ get_method(rcx); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::get_original_bytecode_at), rcx, rsi); - __ movl(rbx, rax); + __ mov(rbx, rax); // post the breakpoint event __ get_method(rcx); @@ -3362,50 +3396,50 @@ void TemplateTable::monitorenter() { // find a free slot in the monitor block (result in rdx) { Label entry, loop, exit; - __ movl(rcx, monitor_block_top); // points to current entry, starting with top-most entry - __ leal(rbx, monitor_block_bot); // points to word before bottom of monitor block + __ movptr(rcx, monitor_block_top); // points to current entry, starting with top-most entry + __ lea(rbx, monitor_block_bot); // points to word before bottom of monitor block __ jmpb(entry); __ bind(loop); - __ cmpl(Address(rcx, BasicObjectLock::obj_offset_in_bytes()), NULL_WORD); // check if current entry is used + __ cmpptr(Address(rcx, BasicObjectLock::obj_offset_in_bytes()), (int32_t)NULL_WORD); // check if current entry is used // TODO - need new func here - kbt if (VM_Version::supports_cmov()) { - __ cmovl(Assembler::equal, rdx, rcx); // if not used then remember entry in rdx + __ cmov(Assembler::equal, rdx, rcx); // if not used then remember entry in rdx } else { Label L; __ jccb(Assembler::notEqual, L); - __ movl(rdx, rcx); // if not used then remember entry in rdx + __ mov(rdx, rcx); // if not used then remember entry in rdx __ bind(L); } - __ cmpl(rax, Address(rcx, BasicObjectLock::obj_offset_in_bytes())); // check if current entry is for same object - __ jccb(Assembler::equal, exit); // if same object then stop searching - __ addl(rcx, entry_size); // otherwise advance to next entry + __ cmpptr(rax, Address(rcx, BasicObjectLock::obj_offset_in_bytes())); // check if current entry is for same object + __ jccb(Assembler::equal, exit); // if same object then stop searching + __ addptr(rcx, entry_size); // otherwise advance to next entry __ bind(entry); - __ cmpl(rcx, rbx); // check if bottom reached + __ cmpptr(rcx, rbx); // check if bottom reached __ jcc(Assembler::notEqual, loop); // if not at bottom then check this entry __ bind(exit); } - __ testl(rdx, rdx); // check if a slot has been found - __ jccb(Assembler::notZero, allocated); // if found, continue with that one + __ testptr(rdx, rdx); // check if a slot has been found + __ jccb(Assembler::notZero, allocated); // if found, continue with that one // allocate one if there's no free slot { Label entry, loop; // 1. compute new pointers // rsp: old expression stack top - __ movl(rdx, monitor_block_bot); // rdx: old expression stack bottom - __ subl(rsp, entry_size); // move expression stack top - __ subl(rdx, entry_size); // move expression stack bottom - __ movl(rcx, rsp); // set start value for copy loop - __ movl(monitor_block_bot, rdx); // set new monitor block top + __ movptr(rdx, monitor_block_bot); // rdx: old expression stack bottom + __ subptr(rsp, entry_size); // move expression stack top + __ subptr(rdx, entry_size); // move expression stack bottom + __ mov(rcx, rsp); // set start value for copy loop + __ movptr(monitor_block_bot, rdx); // set new monitor block top __ jmp(entry); // 2. move expression stack contents __ bind(loop); - __ movl(rbx, Address(rcx, entry_size)); // load expression stack word from old location - __ movl(Address(rcx, 0), rbx); // and store it at new location - __ addl(rcx, wordSize); // advance to next word + __ movptr(rbx, Address(rcx, entry_size)); // load expression stack word from old location + __ movptr(Address(rcx, 0), rbx); // and store it at new location + __ addptr(rcx, wordSize); // advance to next word __ bind(entry); - __ cmpl(rcx, rdx); // check if bottom reached + __ cmpptr(rcx, rdx); // check if bottom reached __ jcc(Assembler::notEqual, loop); // if not at bottom then copy next word } @@ -3417,7 +3451,7 @@ void TemplateTable::monitorenter() { // The object has already been poped from the stack, so the expression stack looks correct. __ increment(rsi); - __ movl(Address(rdx, BasicObjectLock::obj_offset_in_bytes()), rax); // store object + __ movptr(Address(rdx, BasicObjectLock::obj_offset_in_bytes()), rax); // store object __ lock_object(rdx); // check to make sure this monitor doesn't cause stack overflow after locking @@ -3442,16 +3476,16 @@ void TemplateTable::monitorexit() { // find matching slot { Label entry, loop; - __ movl(rdx, monitor_block_top); // points to current entry, starting with top-most entry - __ leal(rbx, monitor_block_bot); // points to word before bottom of monitor block + __ movptr(rdx, monitor_block_top); // points to current entry, starting with top-most entry + __ lea(rbx, monitor_block_bot); // points to word before bottom of monitor block __ jmpb(entry); __ bind(loop); - __ cmpl(rax, Address(rdx, BasicObjectLock::obj_offset_in_bytes())); // check if current entry is for same object + __ cmpptr(rax, Address(rdx, BasicObjectLock::obj_offset_in_bytes())); // check if current entry is for same object __ jcc(Assembler::equal, found); // if same object then stop searching - __ addl(rdx, entry_size); // otherwise advance to next entry + __ addptr(rdx, entry_size); // otherwise advance to next entry __ bind(entry); - __ cmpl(rdx, rbx); // check if bottom reached + __ cmpptr(rdx, rbx); // check if bottom reached __ jcc(Assembler::notEqual, loop); // if not at bottom then check this entry } @@ -3476,7 +3510,8 @@ void TemplateTable::monitorexit() { void TemplateTable::wide() { transition(vtos, vtos); __ load_unsigned_byte(rbx, at_bcp(1)); - __ jmp(Address(noreg, rbx, Address::times_4, int(Interpreter::_wentry_point))); + ExternalAddress wtable((address)Interpreter::_wentry_point); + __ jump(ArrayAddress(wtable, Address(noreg, rbx, Address::times_ptr))); // Note: the rsi increment step is part of the individual wide bytecode implementations } @@ -3490,10 +3525,10 @@ void TemplateTable::multianewarray() { // last dim is on top of stack; we want address of first one: // first_addr = last_addr + (ndims - 1) * stackElementSize - 1*wordsize // the latter wordSize to point to the beginning of the array. - __ leal( rax, Address(rsp, rax, Interpreter::stackElementScale(), -wordSize)); + __ lea( rax, Address(rsp, rax, Interpreter::stackElementScale(), -wordSize)); call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::multianewarray), rax); // pass in rax, __ load_unsigned_byte(rbx, at_bcp(3)); - __ leal(rsp, Address(rsp, rbx, Interpreter::stackElementScale())); // get rid of counts + __ lea(rsp, Address(rsp, rbx, Interpreter::stackElementScale())); // get rid of counts } #endif /* !CC_INTERP */ diff --git a/hotspot/src/cpu/x86/vm/templateTable_x86_32.hpp b/hotspot/src/cpu/x86/vm/templateTable_x86_32.hpp index 58f09235684..f02b9b1ea14 100644 --- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.hpp +++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.hpp @@ -26,7 +26,7 @@ Bytecodes::Code code); static void invokevirtual_helper(Register index, Register recv, Register flags); - static void volatile_barrier( ); + static void volatile_barrier(Assembler::Membar_mask_bits order_constraint ); // Helpers static void index_check(Register array, Register index); diff --git a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp index c831b0cdc38..b239d635b43 100644 --- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp @@ -25,6 +25,8 @@ #include "incls/_precompiled.incl" #include "incls/_templateTable_x86_64.cpp.incl" +#ifndef CC_INTERP + #define __ _masm-> // Platform-dependent initialization @@ -317,7 +319,7 @@ void TemplateTable::ldc(bool wide) { __ jmp(Done); __ bind(isOop); - __ movq(rax, Address(rcx, rbx, Address::times_8, base_offset)); + __ movptr(rax, Address(rcx, rbx, Address::times_8, base_offset)); __ push_ptr(rax); if (VerifyOops) { @@ -355,8 +357,8 @@ void TemplateTable::ldc2_w() { void TemplateTable::locals_index(Register reg, int offset) { __ load_unsigned_byte(reg, at_bcp(offset)); - __ negq(reg); - if (TaggedStackInterpreter) __ shlq(reg, 1); // index = index*2 + __ negptr(reg); + if (TaggedStackInterpreter) __ shlptr(reg, 1); // index = index*2 } void TemplateTable::iload() { @@ -443,7 +445,7 @@ void TemplateTable::dload() { void TemplateTable::aload() { transition(vtos, atos); locals_index(rbx); - __ movq(rax, aaddress(rbx)); + __ movptr(rax, aaddress(rbx)); debug_only(__ verify_local_tag(frame::TagReference, rbx)); } @@ -451,8 +453,8 @@ void TemplateTable::locals_index_wide(Register reg) { __ movl(reg, at_bcp(2)); __ bswapl(reg); __ shrl(reg, 16); - __ negq(reg); - if (TaggedStackInterpreter) __ shlq(reg, 1); // index = index*2 + __ negptr(reg); + if (TaggedStackInterpreter) __ shlptr(reg, 1); // index = index*2 } void TemplateTable::wide_iload() { @@ -486,7 +488,7 @@ void TemplateTable::wide_dload() { void TemplateTable::wide_aload() { transition(vtos, atos); locals_index_wide(rbx); - __ movq(rax, aaddress(rbx)); + __ movptr(rax, aaddress(rbx)); debug_only(__ verify_local_tag(frame::TagReference, rbx)); } @@ -495,7 +497,7 @@ void TemplateTable::index_check(Register array, Register index) { // check array __ null_check(array, arrayOopDesc::length_offset_in_bytes()); // sign extend index for use by indexed load - __ movslq(index, index); + __ movl2ptr(index, index); // check index __ cmpl(index, Address(array, arrayOopDesc::length_offset_in_bytes())); if (index != rbx) { @@ -642,7 +644,7 @@ void TemplateTable::dload(int n) { void TemplateTable::aload(int n) { transition(vtos, atos); - __ movq(rax, aaddress(n)); + __ movptr(rax, aaddress(n)); debug_only(__ verify_local_tag(frame::TagReference, n)); } @@ -757,7 +759,7 @@ void TemplateTable::astore() { transition(vtos, vtos); __ pop_ptr(rax, rdx); // will need to pop tag too locals_index(rbx); - __ movq(aaddress(rbx), rax); + __ movptr(aaddress(rbx), rax); __ tag_local(rdx, rbx); // store tag from stack, might be returnAddr } @@ -797,7 +799,7 @@ void TemplateTable::wide_astore() { transition(vtos, vtos); __ pop_ptr(rax, rdx); // will need to pop tag too locals_index_wide(rbx); - __ movq(aaddress(rbx), rax); + __ movptr(aaddress(rbx), rax); __ tag_local(rdx, rbx); // store tag from stack, might be returnAddr } @@ -861,25 +863,25 @@ void TemplateTable::aastore() { Label is_null, ok_is_subtype, done; transition(vtos, vtos); // stack: ..., array, index, value - __ movq(rax, at_tos()); // value + __ movptr(rax, at_tos()); // value __ movl(rcx, at_tos_p1()); // index - __ movq(rdx, at_tos_p2()); // array + __ movptr(rdx, at_tos_p2()); // array index_check(rdx, rcx); // kills rbx // do array store check - check for NULL value first - __ testq(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, is_null); // Move subklass into rbx __ load_klass(rbx, rax); // Move superklass into rax __ load_klass(rax, rdx); - __ movq(rax, Address(rax, - sizeof(oopDesc) + - objArrayKlass::element_klass_offset_in_bytes())); + __ movptr(rax, Address(rax, + sizeof(oopDesc) + + objArrayKlass::element_klass_offset_in_bytes())); // Compress array + index*oopSize + 12 into a single register. Frees rcx. - __ leaq(rdx, Address(rdx, rcx, - UseCompressedOops ? Address::times_4 : Address::times_8, - arrayOopDesc::base_offset_in_bytes(T_OBJECT))); + __ lea(rdx, Address(rdx, rcx, + UseCompressedOops ? Address::times_4 : Address::times_8, + arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // Generate subtype check. Blows rcx, rdi // Superklass in rax. Subklass in rbx. @@ -891,7 +893,7 @@ void TemplateTable::aastore() { // Come here on success __ bind(ok_is_subtype); - __ movq(rax, at_tos()); // Value + __ movptr(rax, at_tos()); // Value __ store_heap_oop(Address(rdx, 0), rax); __ store_check(rdx); __ jmp(done); @@ -906,7 +908,7 @@ void TemplateTable::aastore() { // Pop stack arguments __ bind(done); - __ addq(rsp, 3 * Interpreter::stackElementSize()); + __ addptr(rsp, 3 * Interpreter::stackElementSize()); } void TemplateTable::bastore() { @@ -968,18 +970,18 @@ void TemplateTable::dstore(int n) { void TemplateTable::astore(int n) { transition(vtos, vtos); __ pop_ptr(rax, rdx); - __ movq(aaddress(n), rax); + __ movptr(aaddress(n), rax); __ tag_local(rdx, n); } void TemplateTable::pop() { transition(vtos, vtos); - __ addq(rsp, Interpreter::stackElementSize()); + __ addptr(rsp, Interpreter::stackElementSize()); } void TemplateTable::pop2() { transition(vtos, vtos); - __ addq(rsp, 2 * Interpreter::stackElementSize()); + __ addptr(rsp, 2 * Interpreter::stackElementSize()); } void TemplateTable::dup() { @@ -1090,11 +1092,11 @@ void TemplateTable::iop2(Operation op) { void TemplateTable::lop2(Operation op) { transition(ltos, ltos); switch (op) { - case add : __ pop_l(rdx); __ addq (rax, rdx); break; - case sub : __ movq(rdx, rax); __ pop_l(rax); __ subq (rax, rdx); break; - case _and : __ pop_l(rdx); __ andq (rax, rdx); break; - case _or : __ pop_l(rdx); __ orq (rax, rdx); break; - case _xor : __ pop_l(rdx); __ xorq (rax, rdx); break; + case add : __ pop_l(rdx); __ addptr (rax, rdx); break; + case sub : __ mov(rdx, rax); __ pop_l(rax); __ subptr (rax, rdx); break; + case _and : __ pop_l(rdx); __ andptr (rax, rdx); break; + case _or : __ pop_l(rdx); __ orptr (rax, rdx); break; + case _xor : __ pop_l(rdx); __ xorptr (rax, rdx); break; default : ShouldNotReachHere(); } } @@ -1130,7 +1132,7 @@ void TemplateTable::lmul() { void TemplateTable::ldiv() { transition(ltos, ltos); - __ movq(rcx, rax); + __ mov(rcx, rax); __ pop_l(rax); // generate explicit div0 check __ testq(rcx, rcx); @@ -1145,7 +1147,7 @@ void TemplateTable::ldiv() { void TemplateTable::lrem() { transition(ltos, ltos); - __ movq(rcx, rax); + __ mov(rcx, rax); __ pop_l(rax); __ testq(rcx, rcx); __ jump_cc(Assembler::zero, @@ -1155,7 +1157,7 @@ void TemplateTable::lrem() { // needed), which may speed up this implementation for the common case. // (see also JVM spec., p.243 & p.271) __ corrected_idivq(rcx); // kills rbx - __ movq(rax, rdx); + __ mov(rax, rdx); } void TemplateTable::lshl() { @@ -1184,7 +1186,7 @@ void TemplateTable::fop2(Operation op) { switch (op) { case add: __ addss(xmm0, at_rsp()); - __ addq(rsp, Interpreter::stackElementSize()); + __ addptr(rsp, Interpreter::stackElementSize()); break; case sub: __ movflt(xmm1, xmm0); @@ -1193,7 +1195,7 @@ void TemplateTable::fop2(Operation op) { break; case mul: __ mulss(xmm0, at_rsp()); - __ addq(rsp, Interpreter::stackElementSize()); + __ addptr(rsp, Interpreter::stackElementSize()); break; case div: __ movflt(xmm1, xmm0); @@ -1216,7 +1218,7 @@ void TemplateTable::dop2(Operation op) { switch (op) { case add: __ addsd(xmm0, at_rsp()); - __ addq(rsp, 2 * Interpreter::stackElementSize()); + __ addptr(rsp, 2 * Interpreter::stackElementSize()); break; case sub: __ movdbl(xmm1, xmm0); @@ -1225,7 +1227,7 @@ void TemplateTable::dop2(Operation op) { break; case mul: __ mulsd(xmm0, at_rsp()); - __ addq(rsp, 2 * Interpreter::stackElementSize()); + __ addptr(rsp, 2 * Interpreter::stackElementSize()); break; case div: __ movdbl(xmm1, xmm0); @@ -1486,7 +1488,7 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { if (!is_wide) { __ sarl(rdx, 16); } - __ movslq(rdx, rdx); + __ movl2ptr(rdx, rdx); // Handle all the JSR stuff here, then exit. // It's much shorter and cleaner than intermingling with the non-JSR @@ -1496,11 +1498,11 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { __ load_unsigned_byte(rbx, Address(r13, rdx, Address::times_1, 0)); // compute return address as bci in rax - __ leaq(rax, at_bcp((is_wide ? 5 : 3) - + __ lea(rax, at_bcp((is_wide ? 5 : 3) - in_bytes(constMethodOopDesc::codes_offset()))); - __ subq(rax, Address(rcx, methodOopDesc::const_offset())); + __ subptr(rax, Address(rcx, methodOopDesc::const_offset())); // Adjust the bcp in r13 by the displacement in rdx - __ addq(r13, rdx); + __ addptr(r13, rdx); // jsr returns atos that is not an oop __ push_i(rax); __ dispatch_only(vtos); @@ -1510,7 +1512,7 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { // Normal (non-jsr) branch handling // Adjust the bcp in r13 by the displacement in rdx - __ addq(r13, rdx); + __ addptr(r13, rdx); assert(UseLoopCounter || !UseOnStackReplacement, "on-stack-replacement requires loop counters"); @@ -1594,25 +1596,25 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method), r13); __ load_unsigned_byte(rbx, Address(r13, 0)); // restore target bytecode - __ movq(rcx, Address(rbp, method_offset)); - __ movq(rcx, Address(rcx, - in_bytes(methodOopDesc::method_data_offset()))); - __ movq(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), - rcx); + __ movptr(rcx, Address(rbp, method_offset)); + __ movptr(rcx, Address(rcx, + in_bytes(methodOopDesc::method_data_offset()))); + __ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), + rcx); __ test_method_data_pointer(rcx, dispatch); // offset non-null mdp by MDO::data_offset() + IR::profile_method() - __ addq(rcx, in_bytes(methodDataOopDesc::data_offset())); - __ addq(rcx, rax); - __ movq(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), - rcx); + __ addptr(rcx, in_bytes(methodDataOopDesc::data_offset())); + __ addptr(rcx, rax); + __ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), + rcx); __ jmp(dispatch); } if (UseOnStackReplacement) { // invocation counter overflow __ bind(backedge_counter_overflow); - __ negq(rdx); - __ addq(rdx, r13); // branch bcp + __ negptr(rdx); + __ addptr(rdx, r13); // branch bcp // IcoResult frequency_counter_overflow([JavaThread*], address branch_bcp) __ call_VM(noreg, CAST_FROM_FN_PTR(address, @@ -1625,7 +1627,7 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { // rdx: scratch // r14: locals pointer // r13: bcp - __ testq(rax, rax); // test result + __ testptr(rax, rax); // test result __ jcc(Assembler::zero, dispatch); // no osr if null // nmethod may have been invalidated (VM may block upon call_VM return) __ movl(rcx, Address(rax, nmethod::entry_bci_offset())); @@ -1636,12 +1638,12 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { // We need to prepare to execute the OSR method. First we must // migrate the locals and monitors off of the stack. - __ movq(r13, rax); // save the nmethod + __ mov(r13, rax); // save the nmethod call_VM(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::OSR_migration_begin)); // eax is OSR buffer, move it to expected parameter location - __ movq(j_rarg0, rax); + __ mov(j_rarg0, rax); // We use j_rarg definitions here so that registers don't conflict as parameter // registers change across platforms as we are in the midst of a calling @@ -1651,18 +1653,18 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { const Register sender_sp = j_rarg1; // pop the interpreter frame - __ movq(sender_sp, Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); // get sender sp + __ movptr(sender_sp, Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); // get sender sp __ leave(); // remove frame anchor - __ popq(retaddr); // get return address - __ movq(rsp, sender_sp); // set sp to sender sp + __ pop(retaddr); // get return address + __ mov(rsp, sender_sp); // set sp to sender sp // Ensure compiled code always sees stack at proper alignment - __ andq(rsp, -(StackAlignmentInBytes)); + __ andptr(rsp, -(StackAlignmentInBytes)); // unlike x86 we need no specialized return from compiled code // to the interpreter or the call stub. // push the return address - __ pushq(retaddr); + __ push(retaddr); // and begin the OSR nmethod __ jmp(Address(r13, nmethod::osr_entry_point_offset())); @@ -1698,7 +1700,7 @@ void TemplateTable::if_nullcmp(Condition cc) { transition(atos, vtos); // assume branch is more often taken than not (loops use backward branches) Label not_taken; - __ testq(rax, rax); + __ testptr(rax, rax); __ jcc(j_not(cc), not_taken); branch(false, false); __ bind(not_taken); @@ -1710,7 +1712,7 @@ void TemplateTable::if_acmp(Condition cc) { // assume branch is more often taken than not (loops use backward branches) Label not_taken; __ pop_ptr(rdx); - __ cmpq(rdx, rax); + __ cmpptr(rdx, rax); __ jcc(j_not(cc), not_taken); branch(false, false); __ bind(not_taken); @@ -1720,23 +1722,23 @@ void TemplateTable::if_acmp(Condition cc) { void TemplateTable::ret() { transition(vtos, vtos); locals_index(rbx); - __ movq(rbx, aaddress(rbx)); // get return bci, compute return bcp + __ movslq(rbx, iaddress(rbx)); // get return bci, compute return bcp __ profile_ret(rbx, rcx); __ get_method(rax); - __ movq(r13, Address(rax, methodOopDesc::const_offset())); - __ leaq(r13, Address(r13, rbx, Address::times_1, - constMethodOopDesc::codes_offset())); + __ movptr(r13, Address(rax, methodOopDesc::const_offset())); + __ lea(r13, Address(r13, rbx, Address::times_1, + constMethodOopDesc::codes_offset())); __ dispatch_next(vtos); } void TemplateTable::wide_ret() { transition(vtos, vtos); locals_index_wide(rbx); - __ movq(rbx, aaddress(rbx)); // get return bci, compute return bcp + __ movptr(rbx, aaddress(rbx)); // get return bci, compute return bcp __ profile_ret(rbx, rcx); __ get_method(rax); - __ movq(r13, Address(rax, methodOopDesc::const_offset())); - __ leaq(r13, Address(r13, rbx, Address::times_1, constMethodOopDesc::codes_offset())); + __ movptr(r13, Address(rax, methodOopDesc::const_offset())); + __ lea(r13, Address(r13, rbx, Address::times_1, constMethodOopDesc::codes_offset())); __ dispatch_next(vtos); } @@ -1744,8 +1746,8 @@ void TemplateTable::tableswitch() { Label default_case, continue_execution; transition(itos, vtos); // align r13 - __ leaq(rbx, at_bcp(BytesPerInt)); - __ andq(rbx, -BytesPerInt); + __ lea(rbx, at_bcp(BytesPerInt)); + __ andptr(rbx, -BytesPerInt); // load lo & hi __ movl(rcx, Address(rbx, BytesPerInt)); __ movl(rdx, Address(rbx, 2 * BytesPerInt)); @@ -1763,9 +1765,9 @@ void TemplateTable::tableswitch() { // continue execution __ bind(continue_execution); __ bswapl(rdx); - __ movslq(rdx, rdx); + __ movl2ptr(rdx, rdx); __ load_unsigned_byte(rbx, Address(r13, rdx, Address::times_1)); - __ addq(r13, rdx); + __ addptr(r13, rdx); __ dispatch_only(vtos); // handle default __ bind(default_case); @@ -1785,10 +1787,10 @@ void TemplateTable::fast_linearswitch() { // bswap rax so we can avoid bswapping the table entries __ bswapl(rax); // align r13 - __ leaq(rbx, at_bcp(BytesPerInt)); // btw: should be able to get rid of - // this instruction (change offsets - // below) - __ andq(rbx, -BytesPerInt); + __ lea(rbx, at_bcp(BytesPerInt)); // btw: should be able to get rid of + // this instruction (change offsets + // below) + __ andptr(rbx, -BytesPerInt); // set counter __ movl(rcx, Address(rbx, BytesPerInt)); __ bswapl(rcx); @@ -1811,9 +1813,9 @@ void TemplateTable::fast_linearswitch() { // continue execution __ bind(continue_execution); __ bswapl(rdx); - __ movslq(rdx, rdx); + __ movl2ptr(rdx, rdx); __ load_unsigned_byte(rbx, Address(r13, rdx, Address::times_1)); - __ addq(r13, rdx); + __ addptr(r13, rdx); __ dispatch_only(vtos); } @@ -1853,11 +1855,11 @@ void TemplateTable::fast_binaryswitch() { const Register temp = rsi; // Find array start - __ leaq(array, at_bcp(3 * BytesPerInt)); // btw: should be able to - // get rid of this - // instruction (change - // offsets below) - __ andq(array, -BytesPerInt); + __ lea(array, at_bcp(3 * BytesPerInt)); // btw: should be able to + // get rid of this + // instruction (change + // offsets below) + __ andptr(array, -BytesPerInt); // Initialize i & j __ xorl(i, i); // i = 0; @@ -1909,9 +1911,9 @@ void TemplateTable::fast_binaryswitch() { __ movl(j , Address(array, i, Address::times_8, BytesPerInt)); __ profile_switch_case(i, key, array); __ bswapl(j); - __ movslq(j, j); + __ movl2ptr(j, j); __ load_unsigned_byte(rbx, Address(r13, j, Address::times_1)); - __ addq(r13, j); + __ addptr(r13, j); __ dispatch_only(vtos); // default case -> j = default offset @@ -1919,9 +1921,9 @@ void TemplateTable::fast_binaryswitch() { __ profile_switch_default(i); __ movl(j, Address(array, -2 * BytesPerInt)); __ bswapl(j); - __ movslq(j, j); + __ movl2ptr(j, j); __ load_unsigned_byte(rbx, Address(r13, j, Address::times_1)); - __ addq(r13, j); + __ addptr(r13, j); __ dispatch_only(vtos); } @@ -1933,7 +1935,7 @@ void TemplateTable::_return(TosState state) { if (_desc->bytecode() == Bytecodes::_return_register_finalizer) { assert(state == vtos, "only valid state"); - __ movq(c_rarg1, aaddress(0)); + __ movptr(c_rarg1, aaddress(0)); __ load_klass(rdi, c_rarg1); __ movl(rdi, Address(rdi, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc))); __ testl(rdi, JVM_ACC_HAS_FINALIZER); @@ -2044,9 +2046,9 @@ void TemplateTable::load_field_cp_cache_entry(Register obj, ByteSize cp_base_offset = constantPoolCacheOopDesc::base_offset(); // Field offset - __ movq(off, Address(cache, index, Address::times_8, - in_bytes(cp_base_offset + - ConstantPoolCacheEntry::f2_offset()))); + __ movptr(off, Address(cache, index, Address::times_8, + in_bytes(cp_base_offset + + ConstantPoolCacheEntry::f2_offset()))); // Flags __ movl(flags, Address(cache, index, Address::times_8, in_bytes(cp_base_offset + @@ -2054,9 +2056,9 @@ void TemplateTable::load_field_cp_cache_entry(Register obj, // klass overwrite register if (is_static) { - __ movq(obj, Address(cache, index, Address::times_8, - in_bytes(cp_base_offset + - ConstantPoolCacheEntry::f1_offset()))); + __ movptr(obj, Address(cache, index, Address::times_8, + in_bytes(cp_base_offset + + ConstantPoolCacheEntry::f1_offset()))); } } @@ -2088,9 +2090,9 @@ void TemplateTable::load_invoke_cp_cache_entry(int byte_no, resolve_cache_and_index(byte_no, cache, index); assert(wordSize == 8, "adjust code below"); - __ movq(method, Address(cache, index, Address::times_8, method_offset)); + __ movptr(method, Address(cache, index, Address::times_8, method_offset)); if (itable_index != noreg) { - __ movq(itable_index, + __ movptr(itable_index, Address(cache, index, Address::times_8, index_offset)); } __ movl(flags , Address(cache, index, Address::times_8, flags_offset)); @@ -2116,13 +2118,13 @@ void TemplateTable::jvmti_post_field_access(Register cache, Register index, __ get_cache_and_index_at_bcp(c_rarg2, c_rarg3, 1); // cache entry pointer - __ addq(c_rarg2, in_bytes(constantPoolCacheOopDesc::base_offset())); + __ addptr(c_rarg2, in_bytes(constantPoolCacheOopDesc::base_offset())); __ shll(c_rarg3, LogBytesPerWord); - __ addq(c_rarg2, c_rarg3); + __ addptr(c_rarg2, c_rarg3); if (is_static) { __ xorl(c_rarg1, c_rarg1); // NULL object reference } else { - __ movq(c_rarg1, at_tos()); // get object pointer without popping it + __ movptr(c_rarg1, at_tos()); // get object pointer without popping it __ verify_oop(c_rarg1); } // c_rarg1: object pointer or NULL @@ -2319,20 +2321,20 @@ void TemplateTable::jvmti_post_field_mod(Register cache, Register index, bool is // Make sure we don't need to mask rcx for tosBits after the // above shift ConstantPoolCacheEntry::verify_tosBits(); - __ movq(c_rarg1, at_tos_p1()); // initially assume a one word jvalue + __ movptr(c_rarg1, at_tos_p1()); // initially assume a one word jvalue __ cmpl(c_rarg3, ltos); - __ cmovq(Assembler::equal, - c_rarg1, at_tos_p2()); // ltos (two word jvalue) + __ cmovptr(Assembler::equal, + c_rarg1, at_tos_p2()); // ltos (two word jvalue) __ cmpl(c_rarg3, dtos); - __ cmovq(Assembler::equal, - c_rarg1, at_tos_p2()); // dtos (two word jvalue) + __ cmovptr(Assembler::equal, + c_rarg1, at_tos_p2()); // dtos (two word jvalue) } // cache entry pointer - __ addq(c_rarg2, in_bytes(cp_base_offset)); + __ addptr(c_rarg2, in_bytes(cp_base_offset)); __ shll(rscratch1, LogBytesPerWord); - __ addq(c_rarg2, rscratch1); + __ addptr(c_rarg2, rscratch1); // object (tos) - __ movq(c_rarg3, rsp); + __ mov(c_rarg3, rsp); // c_rarg1: object pointer set up above (NULL if static) // c_rarg2: cache entry pointer // c_rarg3: jvalue object on the stack @@ -2510,8 +2512,8 @@ void TemplateTable::jvmti_post_fast_field_mod() { __ pop_ptr(rbx); // copy the object pointer from tos __ verify_oop(rbx); __ push_ptr(rbx); // put the object pointer back on tos - __ subq(rsp, sizeof(jvalue)); // add space for a jvalue object - __ movq(c_rarg3, rsp); + __ subptr(rsp, sizeof(jvalue)); // add space for a jvalue object + __ mov(c_rarg3, rsp); const Address field(c_rarg3, 0); switch (bytecode()) { // load values into the jvalue object @@ -2529,7 +2531,7 @@ void TemplateTable::jvmti_post_fast_field_mod() { // Save rax because call_VM() will clobber it, then use it for // JVMTI purposes - __ pushq(rax); + __ push(rax); // access constant pool cache entry __ get_cache_entry_pointer_at_bcp(c_rarg2, rax, 1); __ verify_oop(rbx); @@ -2540,8 +2542,8 @@ void TemplateTable::jvmti_post_fast_field_mod() { CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_modification), rbx, c_rarg2, c_rarg3); - __ popq(rax); // restore lower value - __ addq(rsp, sizeof(jvalue)); // release jvalue object space + __ pop(rax); // restore lower value + __ addptr(rsp, sizeof(jvalue)); // release jvalue object space __ bind(L2); } } @@ -2562,8 +2564,8 @@ void TemplateTable::fast_storefield(TosState state) { ConstantPoolCacheEntry::flags_offset()))); // replace index with field offset from cache entry - __ movq(rbx, Address(rcx, rbx, Address::times_8, - in_bytes(base + ConstantPoolCacheEntry::f2_offset()))); + __ movptr(rbx, Address(rcx, rbx, Address::times_8, + in_bytes(base + ConstantPoolCacheEntry::f2_offset()))); // [jk] not needed currently // volatile_barrier(Assembler::Membar_mask_bits(Assembler::LoadStore | @@ -2632,15 +2634,15 @@ void TemplateTable::fast_accessfield(TosState state) { // access constant pool cache entry __ get_cache_entry_pointer_at_bcp(c_rarg2, rcx, 1); __ verify_oop(rax); - __ movq(r12, rax); // save object pointer before call_VM() clobbers it - __ movq(c_rarg1, rax); + __ mov(r12, rax); // save object pointer before call_VM() clobbers it + __ mov(c_rarg1, rax); // c_rarg1: object pointer copied above // c_rarg2: cache entry pointer __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_access), c_rarg1, c_rarg2); - __ movq(rax, r12); // restore object pointer + __ mov(rax, r12); // restore object pointer __ reinit_heapbase(); __ bind(L1); } @@ -2656,9 +2658,9 @@ void TemplateTable::fast_accessfield(TosState state) { // __ shrl(rdx, ConstantPoolCacheEntry::volatileField); // __ andl(rdx, 0x1); // } - __ movq(rbx, Address(rcx, rbx, Address::times_8, - in_bytes(constantPoolCacheOopDesc::base_offset() + - ConstantPoolCacheEntry::f2_offset()))); + __ movptr(rbx, Address(rcx, rbx, Address::times_8, + in_bytes(constantPoolCacheOopDesc::base_offset() + + ConstantPoolCacheEntry::f2_offset()))); // rax: object __ verify_oop(rax); @@ -2709,17 +2711,17 @@ void TemplateTable::fast_xaccess(TosState state) { transition(vtos, state); // get receiver - __ movq(rax, aaddress(0)); + __ movptr(rax, aaddress(0)); debug_only(__ verify_local_tag(frame::TagReference, 0)); // access constant pool cache __ get_cache_and_index_at_bcp(rcx, rdx, 2); - __ movq(rbx, - Address(rcx, rdx, Address::times_8, - in_bytes(constantPoolCacheOopDesc::base_offset() + - ConstantPoolCacheEntry::f2_offset()))); + __ movptr(rbx, + Address(rcx, rdx, Address::times_8, + in_bytes(constantPoolCacheOopDesc::base_offset() + + ConstantPoolCacheEntry::f2_offset()))); // make sure exception is reported in correct bcp range (getfield is // next instruction) - __ incrementq(r13); + __ increment(r13); __ null_check(rax); switch (state) { case itos: @@ -2749,7 +2751,7 @@ void TemplateTable::fast_xaccess(TosState state) { // __ bind(notVolatile); // } - __ decrementq(r13); + __ decrement(r13); } @@ -2788,7 +2790,7 @@ void TemplateTable::prepare_invoke(Register method, __ movl(recv, flags); __ andl(recv, 0xFF); if (TaggedStackInterpreter) __ shll(recv, 1); // index*2 - __ movq(recv, Address(rsp, recv, Address::times_8, + __ movptr(recv, Address(rsp, recv, Address::times_8, -Interpreter::expr_offset_in_bytes(1))); __ verify_oop(recv); } @@ -2811,11 +2813,11 @@ void TemplateTable::prepare_invoke(Register method, ExternalAddress return_5((address)Interpreter::return_5_addrs_by_index_table()); ExternalAddress return_3((address)Interpreter::return_3_addrs_by_index_table()); __ lea(rscratch1, (is_invokeinterface ? return_5 : return_3)); - __ movq(flags, Address(rscratch1, flags, Address::times_8)); + __ movptr(flags, Address(rscratch1, flags, Address::times_8)); } // push return address - __ pushq(flags); + __ push(flags); // Restore flag field from the constant pool cache, and restore esi // for later null checks. r13 is the bytecode pointer @@ -2867,10 +2869,10 @@ void TemplateTable::invokevirtual_helper(Register index, const int base = instanceKlass::vtable_start_offset() * wordSize; assert(vtableEntry::size() * wordSize == 8, "adjust the scaling in the code below"); - __ movq(method, Address(rax, index, + __ movptr(method, Address(rax, index, Address::times_8, base + vtableEntry::method_offset_in_bytes())); - __ movq(rdx, Address(method, methodOopDesc::interpreter_entry_offset())); + __ movptr(rdx, Address(method, methodOopDesc::interpreter_entry_offset())); __ jump_from_interpreted(method, rdx); } @@ -2940,7 +2942,7 @@ void TemplateTable::invokeinterface(int byte_no) { // profile this call __ profile_virtual_call(rdx, r13, r14); - __ movq(r14, rdx); // Save klassOop in r14 + __ mov(r14, rdx); // Save klassOop in r14 // Compute start of first itableOffsetEntry (which is at the end of // the vtable) @@ -2950,18 +2952,18 @@ void TemplateTable::invokeinterface(int byte_no) { "adjust the scaling in the code below"); __ movl(r13, Address(rdx, instanceKlass::vtable_length_offset() * wordSize)); - __ leaq(rdx, Address(rdx, r13, Address::times_8, base)); + __ lea(rdx, Address(rdx, r13, Address::times_8, base)); if (HeapWordsPerLong > 1) { // Round up to align_object_offset boundary - __ round_to_q(rdx, BytesPerLong); + __ round_to(rdx, BytesPerLong); } Label entry, search, interface_ok; __ jmpb(entry); __ bind(search); - __ addq(rdx, itableOffsetEntry::size() * wordSize); + __ addptr(rdx, itableOffsetEntry::size() * wordSize); __ bind(entry); @@ -2969,13 +2971,13 @@ void TemplateTable::invokeinterface(int byte_no) { // receiver class doesn't implement the interface, and wasn't the // same as the receiver class checked when the interface was // resolved. - __ pushq(rdx); - __ movq(rdx, Address(rdx, itableOffsetEntry::interface_offset_in_bytes())); - __ testq(rdx, rdx); + __ push(rdx); + __ movptr(rdx, Address(rdx, itableOffsetEntry::interface_offset_in_bytes())); + __ testptr(rdx, rdx); __ jcc(Assembler::notZero, interface_ok); // throw exception - __ popq(rdx); // pop saved register first. - __ popq(rbx); // pop return address (pushed by prepare_invoke) + __ pop(rdx); // pop saved register first. + __ pop(rbx); // pop return address (pushed by prepare_invoke) __ restore_bcp(); // r13 must be correct for exception handler (was // destroyed) __ restore_locals(); // make sure locals pointer is correct as well @@ -2986,17 +2988,17 @@ void TemplateTable::invokeinterface(int byte_no) { __ should_not_reach_here(); __ bind(interface_ok); - __ popq(rdx); + __ pop(rdx); - __ cmpq(rax, Address(rdx, itableOffsetEntry::interface_offset_in_bytes())); + __ cmpptr(rax, Address(rdx, itableOffsetEntry::interface_offset_in_bytes())); __ jcc(Assembler::notEqual, search); __ movl(rdx, Address(rdx, itableOffsetEntry::offset_offset_in_bytes())); - __ addq(rdx, r14); // Add offset to klassOop + __ addptr(rdx, r14); // Add offset to klassOop assert(itableMethodEntry::size() * wordSize == 8, "adjust the scaling in the code below"); - __ movq(rbx, Address(rdx, rbx, Address::times_8)); + __ movptr(rbx, Address(rdx, rbx, Address::times_8)); // rbx: methodOop to call // rcx: receiver // Check for abstract method error @@ -3005,12 +3007,12 @@ void TemplateTable::invokeinterface(int byte_no) { // conditional jump to it in case of a null method. { Label L; - __ testq(rbx, rbx); + __ testptr(rbx, rbx); __ jcc(Assembler::notZero, L); // throw exception // note: must restore interpreter registers to canonical // state for exception handling to work correctly! - __ popq(rbx); // pop return address (pushed by prepare_invoke) + __ pop(rbx); // pop return address (pushed by prepare_invoke) __ restore_bcp(); // r13 must be correct for exception handler // (was destroyed) __ restore_locals(); // make sure locals pointer is correct as @@ -3023,7 +3025,7 @@ void TemplateTable::invokeinterface(int byte_no) { __ bind(L); } - __ movq(rcx, Address(rbx, methodOopDesc::interpreter_entry_offset())); + __ movptr(rcx, Address(rbx, methodOopDesc::interpreter_entry_offset())); // do the call // rcx: receiver @@ -3047,8 +3049,8 @@ void TemplateTable::_new() { __ get_cpool_and_tags(rsi, rax); // get instanceKlass - __ movq(rsi, Address(rsi, rdx, - Address::times_8, sizeof(constantPoolOopDesc))); + __ movptr(rsi, Address(rsi, rdx, + Address::times_8, sizeof(constantPoolOopDesc))); // make sure the class we're about to instantiate has been // resolved. Note: slow_case does a pop of stack, which is why we @@ -3084,11 +3086,11 @@ void TemplateTable::_new() { Universe::heap()->supports_inline_contig_alloc() && !CMSIncrementalMode; if (UseTLAB) { - __ movq(rax, Address(r15_thread, in_bytes(JavaThread::tlab_top_offset()))); - __ leaq(rbx, Address(rax, rdx, Address::times_1)); - __ cmpq(rbx, Address(r15_thread, in_bytes(JavaThread::tlab_end_offset()))); + __ movptr(rax, Address(r15_thread, in_bytes(JavaThread::tlab_top_offset()))); + __ lea(rbx, Address(rax, rdx, Address::times_1)); + __ cmpptr(rbx, Address(r15_thread, in_bytes(JavaThread::tlab_end_offset()))); __ jcc(Assembler::above, allow_shared_alloc ? allocate_shared : slow_case); - __ movq(Address(r15_thread, in_bytes(JavaThread::tlab_top_offset())), rbx); + __ movptr(Address(r15_thread, in_bytes(JavaThread::tlab_top_offset())), rbx); if (ZeroTLAB) { // the fields have been already cleared __ jmp(initialize_header); @@ -3109,13 +3111,13 @@ void TemplateTable::_new() { __ lea(RtopAddr, top); __ lea(RendAddr, end); - __ movq(rax, Address(RtopAddr, 0)); + __ movptr(rax, Address(RtopAddr, 0)); // For retries rax gets set by cmpxchgq Label retry; __ bind(retry); - __ leaq(rbx, Address(rax, rdx, Address::times_1)); - __ cmpq(rbx, Address(RendAddr, 0)); + __ lea(rbx, Address(rax, rdx, Address::times_1)); + __ cmpptr(rbx, Address(RendAddr, 0)); __ jcc(Assembler::above, slow_case); // Compare rax with the top addr, and if still equal, store the new @@ -3128,7 +3130,7 @@ void TemplateTable::_new() { if (os::is_MP()) { __ lock(); } - __ cmpxchgq(rbx, Address(RtopAddr, 0)); + __ cmpxchgptr(rbx, Address(RtopAddr, 0)); // if someone beat us on the allocation, try again, otherwise continue __ jcc(Assembler::notEqual, retry); @@ -3157,8 +3159,8 @@ void TemplateTable::_new() { // initialize object header only. __ bind(initialize_header); if (UseBiasedLocking) { - __ movq(rscratch1, Address(rsi, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); - __ movq(Address(rax, oopDesc::mark_offset_in_bytes()), rscratch1); + __ movptr(rscratch1, Address(rsi, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + __ movptr(Address(rax, oopDesc::mark_offset_in_bytes()), rscratch1); } else { __ movptr(Address(rax, oopDesc::mark_offset_in_bytes()), (intptr_t) markOopDesc::prototype()); // header (address 0x1) @@ -3215,7 +3217,7 @@ void TemplateTable::arraylength() { void TemplateTable::checkcast() { transition(atos, atos); Label done, is_null, ok_is_subtype, quicked, resolved; - __ testq(rax, rax); // object is in rax + __ testptr(rax, rax); // object is in rax __ jcc(Assembler::zero, is_null); // Get cpool & tags index @@ -3228,7 +3230,7 @@ void TemplateTable::checkcast() { JVM_CONSTANT_Class); __ jcc(Assembler::equal, quicked); __ push(atos); // save receiver for result, and for GC - __ movq(r12, rcx); // save rcx XXX + __ mov(r12, rcx); // save rcx XXX call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc)); __ movq(rcx, r12); // restore rcx XXX __ reinit_heapbase(); @@ -3237,8 +3239,8 @@ void TemplateTable::checkcast() { // Get superklass in rax and subklass in rbx __ bind(quicked); - __ movq(rdx, rax); // Save object in rdx; rax needed for subtype check - __ movq(rax, Address(rcx, rbx, + __ mov(rdx, rax); // Save object in rdx; rax needed for subtype check + __ movptr(rax, Address(rcx, rbx, Address::times_8, sizeof(constantPoolOopDesc))); __ bind(resolved); @@ -3255,7 +3257,7 @@ void TemplateTable::checkcast() { // Come here on success __ bind(ok_is_subtype); - __ movq(rax, rdx); // Restore object in rdx + __ mov(rax, rdx); // Restore object in rdx // Collect counts on whether this check-cast sees NULLs a lot or not. if (ProfileInterpreter) { @@ -3271,7 +3273,7 @@ void TemplateTable::checkcast() { void TemplateTable::instanceof() { transition(atos, itos); Label done, is_null, ok_is_subtype, quicked, resolved; - __ testq(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, is_null); // Get cpool & tags index @@ -3285,7 +3287,7 @@ void TemplateTable::instanceof() { __ jcc(Assembler::equal, quicked); __ push(atos); // save receiver for result, and for GC - __ movq(r12, rcx); // save rcx + __ mov(r12, rcx); // save rcx call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc)); __ movq(rcx, r12); // restore rcx __ reinit_heapbase(); @@ -3296,8 +3298,8 @@ void TemplateTable::instanceof() { // Get superklass in rax and subklass in rdx __ bind(quicked); __ load_klass(rdx, rax); - __ movq(rax, Address(rcx, rbx, - Address::times_8, sizeof(constantPoolOopDesc))); + __ movptr(rax, Address(rcx, rbx, + Address::times_8, sizeof(constantPoolOopDesc))); __ bind(resolved); @@ -3340,7 +3342,7 @@ void TemplateTable::_breakpoint() { CAST_FROM_FN_PTR(address, InterpreterRuntime::get_original_bytecode_at), c_rarg1, r13); - __ movq(rbx, rax); + __ mov(rbx, rax); // post the breakpoint event __ get_method(c_rarg1); @@ -3398,52 +3400,52 @@ void TemplateTable::monitorenter() { // find a free slot in the monitor block (result in c_rarg1) { Label entry, loop, exit; - __ movq(c_rarg3, monitor_block_top); // points to current entry, + __ movptr(c_rarg3, monitor_block_top); // points to current entry, // starting with top-most entry - __ leaq(c_rarg2, monitor_block_bot); // points to word before bottom + __ lea(c_rarg2, monitor_block_bot); // points to word before bottom // of monitor block __ jmpb(entry); __ bind(loop); // check if current entry is used - __ cmpq(Address(c_rarg3, BasicObjectLock::obj_offset_in_bytes()), (int) NULL); + __ cmpptr(Address(c_rarg3, BasicObjectLock::obj_offset_in_bytes()), (int32_t) NULL_WORD); // if not used then remember entry in c_rarg1 - __ cmovq(Assembler::equal, c_rarg1, c_rarg3); + __ cmov(Assembler::equal, c_rarg1, c_rarg3); // check if current entry is for same object - __ cmpq(rax, Address(c_rarg3, BasicObjectLock::obj_offset_in_bytes())); + __ cmpptr(rax, Address(c_rarg3, BasicObjectLock::obj_offset_in_bytes())); // if same object then stop searching __ jccb(Assembler::equal, exit); // otherwise advance to next entry - __ addq(c_rarg3, entry_size); + __ addptr(c_rarg3, entry_size); __ bind(entry); // check if bottom reached - __ cmpq(c_rarg3, c_rarg2); + __ cmpptr(c_rarg3, c_rarg2); // if not at bottom then check this entry __ jcc(Assembler::notEqual, loop); __ bind(exit); } - __ testq(c_rarg1, c_rarg1); // check if a slot has been found + __ testptr(c_rarg1, c_rarg1); // check if a slot has been found __ jcc(Assembler::notZero, allocated); // if found, continue with that one // allocate one if there's no free slot { Label entry, loop; - // 1. compute new pointers // rsp: old expression stack top - __ movq(c_rarg1, monitor_block_bot); // c_rarg1: old expression stack bottom - __ subq(rsp, entry_size); // move expression stack top - __ subq(c_rarg1, entry_size); // move expression stack bottom - __ movq(c_rarg3, rsp); // set start value for copy loop - __ movq(monitor_block_bot, c_rarg1); // set new monitor block bottom + // 1. compute new pointers // rsp: old expression stack top + __ movptr(c_rarg1, monitor_block_bot); // c_rarg1: old expression stack bottom + __ subptr(rsp, entry_size); // move expression stack top + __ subptr(c_rarg1, entry_size); // move expression stack bottom + __ mov(c_rarg3, rsp); // set start value for copy loop + __ movptr(monitor_block_bot, c_rarg1); // set new monitor block bottom __ jmp(entry); // 2. move expression stack contents __ bind(loop); - __ movq(c_rarg2, Address(c_rarg3, entry_size)); // load expression stack - // word from old location - __ movq(Address(c_rarg3, 0), c_rarg2); // and store it at new location - __ addq(c_rarg3, wordSize); // advance to next word + __ movptr(c_rarg2, Address(c_rarg3, entry_size)); // load expression stack + // word from old location + __ movptr(Address(c_rarg3, 0), c_rarg2); // and store it at new location + __ addptr(c_rarg3, wordSize); // advance to next word __ bind(entry); - __ cmpq(c_rarg3, c_rarg1); // check if bottom reached + __ cmpptr(c_rarg3, c_rarg1); // check if bottom reached __ jcc(Assembler::notEqual, loop); // if not at bottom then // copy next word } @@ -3456,10 +3458,10 @@ void TemplateTable::monitorenter() { // handling for async. exceptions work correctly. // The object has already been poped from the stack, so the // expression stack looks correct. - __ incrementq(r13); + __ increment(r13); // store object - __ movq(Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes()), rax); + __ movptr(Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes()), rax); __ lock_object(c_rarg1); // check to make sure this monitor doesn't cause stack overflow after locking @@ -3489,22 +3491,22 @@ void TemplateTable::monitorexit() { // find matching slot { Label entry, loop; - __ movq(c_rarg1, monitor_block_top); // points to current entry, + __ movptr(c_rarg1, monitor_block_top); // points to current entry, // starting with top-most entry - __ leaq(c_rarg2, monitor_block_bot); // points to word before bottom + __ lea(c_rarg2, monitor_block_bot); // points to word before bottom // of monitor block __ jmpb(entry); __ bind(loop); // check if current entry is for same object - __ cmpq(rax, Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes())); + __ cmpptr(rax, Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes())); // if same object then stop searching __ jcc(Assembler::equal, found); // otherwise advance to next entry - __ addq(c_rarg1, entry_size); + __ addptr(c_rarg1, entry_size); __ bind(entry); // check if bottom reached - __ cmpq(c_rarg1, c_rarg2); + __ cmpptr(c_rarg1, c_rarg2); // if not at bottom then check this entry __ jcc(Assembler::notEqual, loop); } @@ -3541,11 +3543,12 @@ void TemplateTable::multianewarray() { // last dim is on top of stack; we want address of first one: // first_addr = last_addr + (ndims - 1) * wordSize if (TaggedStackInterpreter) __ shll(rax, 1); // index*2 - __ leaq(c_rarg1, Address(rsp, rax, Address::times_8, -wordSize)); + __ lea(c_rarg1, Address(rsp, rax, Address::times_8, -wordSize)); call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::multianewarray), c_rarg1); __ load_unsigned_byte(rbx, at_bcp(3)); if (TaggedStackInterpreter) __ shll(rbx, 1); // index*2 - __ leaq(rsp, Address(rsp, rbx, Address::times_8)); + __ lea(rsp, Address(rsp, rbx, Address::times_8)); } +#endif // !CC_INTERP diff --git a/hotspot/src/cpu/x86/vm/vm_version_x86_32.cpp b/hotspot/src/cpu/x86/vm/vm_version_x86_32.cpp index d65cc0cc3e6..839a4cdaeda 100644 --- a/hotspot/src/cpu/x86/vm/vm_version_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/vm_version_x86_32.cpp @@ -67,23 +67,23 @@ class VM_Version_StubGenerator: public StubCodeGenerator { // // void getPsrInfo(VM_Version::CpuidInfo* cpuid_info); // - __ pushl(rbp); - __ movl(rbp, Address(rsp, 8)); // cpuid_info address - __ pushl(rbx); - __ pushl(rsi); - __ pushfd(); // preserve rbx, and flags - __ popl(rax); - __ pushl(rax); - __ movl(rcx, rax); + __ push(rbp); + __ movptr(rbp, Address(rsp, 8)); // cpuid_info address + __ push(rbx); + __ push(rsi); + __ pushf(); // preserve rbx, and flags + __ pop(rax); + __ push(rax); + __ mov(rcx, rax); // // if we are unable to change the AC flag, we have a 386 // __ xorl(rax, EFL_AC); - __ pushl(rax); - __ popfd(); - __ pushfd(); - __ popl(rax); - __ cmpl(rax, rcx); + __ push(rax); + __ popf(); + __ pushf(); + __ pop(rax); + __ cmpptr(rax, rcx); __ jccb(Assembler::notEqual, detect_486); __ movl(rax, CPU_FAMILY_386); @@ -95,13 +95,13 @@ class VM_Version_StubGenerator: public StubCodeGenerator { // not support the "cpuid" instruction. // __ bind(detect_486); - __ movl(rax, rcx); + __ mov(rax, rcx); __ xorl(rax, EFL_ID); - __ pushl(rax); - __ popfd(); - __ pushfd(); - __ popl(rax); - __ cmpl(rcx, rax); + __ push(rax); + __ popf(); + __ pushf(); + __ pop(rax); + __ cmpptr(rcx, rax); __ jccb(Assembler::notEqual, detect_586); __ bind(cpu486); @@ -113,13 +113,13 @@ class VM_Version_StubGenerator: public StubCodeGenerator { // at this point, we have a chip which supports the "cpuid" instruction // __ bind(detect_586); - __ xorl(rax, rax); + __ xorptr(rax, rax); __ cpuid(); - __ orl(rax, rax); + __ orptr(rax, rax); __ jcc(Assembler::equal, cpu486); // if cpuid doesn't support an input // value of at least 1, we give up and // assume a 486 - __ leal(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid0_offset()))); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid0_offset()))); __ movl(Address(rsi, 0), rax); __ movl(Address(rsi, 4), rbx); __ movl(Address(rsi, 8), rcx); @@ -134,13 +134,13 @@ class VM_Version_StubGenerator: public StubCodeGenerator { __ movl(rax, 4); // and rcx already set to 0x0 __ xorl(rcx, rcx); __ cpuid(); - __ pushl(rax); + __ push(rax); __ andl(rax, 0x1f); // Determine if valid cache parameters used __ orl(rax, rax); // rax,[4:0] == 0 indicates invalid cache - __ popl(rax); + __ pop(rax); __ jccb(Assembler::equal, std_cpuid1); - __ leal(rsi, Address(rbp, in_bytes(VM_Version::dcp_cpuid4_offset()))); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::dcp_cpuid4_offset()))); __ movl(Address(rsi, 0), rax); __ movl(Address(rsi, 4), rbx); __ movl(Address(rsi, 8), rcx); @@ -152,7 +152,7 @@ class VM_Version_StubGenerator: public StubCodeGenerator { __ bind(std_cpuid1); __ movl(rax, 1); __ cpuid(); - __ leal(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid1_offset()))); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid1_offset()))); __ movl(Address(rsi, 0), rax); __ movl(Address(rsi, 4), rbx); __ movl(Address(rsi, 8), rcx); @@ -171,7 +171,7 @@ class VM_Version_StubGenerator: public StubCodeGenerator { // __ movl(rax, 0x80000008); __ cpuid(); - __ leal(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid8_offset()))); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid8_offset()))); __ movl(Address(rsi, 0), rax); __ movl(Address(rsi, 4), rbx); __ movl(Address(rsi, 8), rcx); @@ -183,7 +183,7 @@ class VM_Version_StubGenerator: public StubCodeGenerator { __ bind(ext_cpuid5); __ movl(rax, 0x80000005); __ cpuid(); - __ leal(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid5_offset()))); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid5_offset()))); __ movl(Address(rsi, 0), rax); __ movl(Address(rsi, 4), rbx); __ movl(Address(rsi, 8), rcx); @@ -195,7 +195,7 @@ class VM_Version_StubGenerator: public StubCodeGenerator { __ bind(ext_cpuid1); __ movl(rax, 0x80000001); __ cpuid(); - __ leal(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid1_offset()))); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid1_offset()))); __ movl(Address(rsi, 0), rax); __ movl(Address(rsi, 4), rbx); __ movl(Address(rsi, 8), rcx); @@ -205,10 +205,10 @@ class VM_Version_StubGenerator: public StubCodeGenerator { // return // __ bind(done); - __ popfd(); - __ popl(rsi); - __ popl(rbx); - __ popl(rbp); + __ popf(); + __ pop(rsi); + __ pop(rbx); + __ pop(rbp); __ ret(0); # undef __ diff --git a/hotspot/src/cpu/x86/vm/vm_version_x86_64.cpp b/hotspot/src/cpu/x86/vm/vm_version_x86_64.cpp index 71be1f8a20e..709d82e6e68 100644 --- a/hotspot/src/cpu/x86/vm/vm_version_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/vm_version_x86_64.cpp @@ -60,17 +60,17 @@ class VM_Version_StubGenerator: public StubCodeGenerator { // // rcx and rdx are first and second argument registers on windows - __ pushq(rbp); - __ movq(rbp, c_rarg0); // cpuid_info address - __ pushq(rbx); - __ pushq(rsi); + __ push(rbp); + __ mov(rbp, c_rarg0); // cpuid_info address + __ push(rbx); + __ push(rsi); // // we have a chip which supports the "cpuid" instruction // __ xorl(rax, rax); __ cpuid(); - __ leaq(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid0_offset()))); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid0_offset()))); __ movl(Address(rsi, 0), rax); __ movl(Address(rsi, 4), rbx); __ movl(Address(rsi, 8), rcx); @@ -85,13 +85,13 @@ class VM_Version_StubGenerator: public StubCodeGenerator { __ movl(rax, 4); __ xorl(rcx, rcx); // L1 cache __ cpuid(); - __ pushq(rax); + __ push(rax); __ andl(rax, 0x1f); // Determine if valid cache parameters used __ orl(rax, rax); // eax[4:0] == 0 indicates invalid cache - __ popq(rax); + __ pop(rax); __ jccb(Assembler::equal, std_cpuid1); - __ leaq(rsi, Address(rbp, in_bytes(VM_Version::dcp_cpuid4_offset()))); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::dcp_cpuid4_offset()))); __ movl(Address(rsi, 0), rax); __ movl(Address(rsi, 4), rbx); __ movl(Address(rsi, 8), rcx); @@ -103,7 +103,7 @@ class VM_Version_StubGenerator: public StubCodeGenerator { __ bind(std_cpuid1); __ movl(rax, 1); __ cpuid(); - __ leaq(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid1_offset()))); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid1_offset()))); __ movl(Address(rsi, 0), rax); __ movl(Address(rsi, 4), rbx); __ movl(Address(rsi, 8), rcx); @@ -122,7 +122,7 @@ class VM_Version_StubGenerator: public StubCodeGenerator { // __ movl(rax, 0x80000008); __ cpuid(); - __ leaq(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid8_offset()))); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid8_offset()))); __ movl(Address(rsi, 0), rax); __ movl(Address(rsi, 4), rbx); __ movl(Address(rsi, 8), rcx); @@ -134,7 +134,7 @@ class VM_Version_StubGenerator: public StubCodeGenerator { __ bind(ext_cpuid5); __ movl(rax, 0x80000005); __ cpuid(); - __ leaq(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid5_offset()))); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid5_offset()))); __ movl(Address(rsi, 0), rax); __ movl(Address(rsi, 4), rbx); __ movl(Address(rsi, 8), rcx); @@ -146,7 +146,7 @@ class VM_Version_StubGenerator: public StubCodeGenerator { __ bind(ext_cpuid1); __ movl(rax, 0x80000001); __ cpuid(); - __ leaq(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid1_offset()))); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid1_offset()))); __ movl(Address(rsi, 0), rax); __ movl(Address(rsi, 4), rbx); __ movl(Address(rsi, 8), rcx); @@ -156,9 +156,9 @@ class VM_Version_StubGenerator: public StubCodeGenerator { // return // __ bind(done); - __ popq(rsi); - __ popq(rbx); - __ popq(rbp); + __ pop(rsi); + __ pop(rbx); + __ pop(rbp); __ ret(0); # undef __ diff --git a/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp b/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp index 09d37901e61..cfa1edd6299 100644 --- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp @@ -49,7 +49,7 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { #ifndef PRODUCT if (CountCompiledCalls) { - __ increment(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr())); + __ incrementl(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr())); } #endif /* PRODUCT */ @@ -58,7 +58,7 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { // get receiver klass address npe_addr = __ pc(); - __ movl(rax, Address(rcx, oopDesc::klass_offset_in_bytes())); + __ movptr(rax, Address(rcx, oopDesc::klass_offset_in_bytes())); // compute entry offset (in words) int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size(); #ifndef PRODUCT @@ -76,12 +76,12 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { const Register method = rbx; // load methodOop and target address - __ movl(method, Address(rax, entry_offset*wordSize + vtableEntry::method_offset_in_bytes())); + __ movptr(method, Address(rax, entry_offset*wordSize + vtableEntry::method_offset_in_bytes())); if (DebugVtables) { Label L; - __ cmpl(method, NULL_WORD); + __ cmpptr(method, (int32_t)NULL_WORD); __ jcc(Assembler::equal, L); - __ cmpl(Address(method, methodOopDesc::from_compiled_offset()), NULL_WORD); + __ cmpptr(Address(method, methodOopDesc::from_compiled_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::notZero, L); __ stop("Vtable entry is NULL"); __ bind(L); @@ -114,7 +114,7 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { #ifndef PRODUCT if (CountCompiledCalls) { - __ increment(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr())); + __ incrementl(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr())); } #endif /* PRODUCT */ // get receiver (need to skip return address on top of stack) @@ -123,16 +123,16 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { // get receiver klass (also an implicit null-check) address npe_addr = __ pc(); - __ movl(rbx, Address(rcx, oopDesc::klass_offset_in_bytes())); + __ movptr(rbx, Address(rcx, oopDesc::klass_offset_in_bytes())); - __ movl(rsi, rbx); // Save klass in free register + __ mov(rsi, rbx); // Save klass in free register // Most registers are in use, so save a few - __ pushl(rdx); + __ push(rdx); // compute itable entry offset (in words) const int base = instanceKlass::vtable_start_offset() * wordSize; assert(vtableEntry::size() * wordSize == 4, "adjust the scaling in the code below"); __ movl(rdx, Address(rbx, instanceKlass::vtable_length_offset() * wordSize)); // Get length of vtable - __ leal(rbx, Address(rbx, rdx, Address::times_4, base)); + __ lea(rbx, Address(rbx, rdx, Address::times_ptr, base)); if (HeapWordsPerLong > 1) { // Round up to align_object_offset boundary __ round_to(rbx, BytesPerLong); @@ -143,16 +143,16 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { __ jmpb(entry); __ bind(next); - __ addl(rbx, itableOffsetEntry::size() * wordSize); + __ addptr(rbx, itableOffsetEntry::size() * wordSize); __ bind(entry); // If the entry is NULL then we've reached the end of the table // without finding the expected interface, so throw an exception - __ movl(rdx, Address(rbx, itableOffsetEntry::interface_offset_in_bytes())); - __ testl(rdx, rdx); + __ movptr(rdx, Address(rbx, itableOffsetEntry::interface_offset_in_bytes())); + __ testptr(rdx, rdx); __ jcc(Assembler::zero, throw_icce); - __ cmpl(rax, rdx); + __ cmpptr(rax, rdx); __ jcc(Assembler::notEqual, next); // We found a hit, move offset into rbx, @@ -163,10 +163,10 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { // Get methodOop and entrypoint for compiler const Register method = rbx; - __ movl(method, Address(rsi, rdx, Address::times_1, method_offset)); + __ movptr(method, Address(rsi, rdx, Address::times_1, method_offset)); // Restore saved register, before possible trap. - __ popl(rdx); + __ pop(rdx); // method (rbx): methodOop // rcx: receiver @@ -174,9 +174,9 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { #ifdef ASSERT if (DebugVtables) { Label L1; - __ cmpl(method, NULL_WORD); + __ cmpptr(method, (int32_t)NULL_WORD); __ jcc(Assembler::equal, L1); - __ cmpl(Address(method, methodOopDesc::from_compiled_offset()), NULL_WORD); + __ cmpptr(Address(method, methodOopDesc::from_compiled_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::notZero, L1); __ stop("methodOop is null"); __ bind(L1); @@ -188,7 +188,7 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { __ bind(throw_icce); // Restore saved register - __ popl(rdx); + __ pop(rdx); __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry())); masm->flush(); diff --git a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp index 931b3aa900a..7ae875b73cc 100644 --- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp @@ -79,14 +79,14 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { // load methodOop and target address const Register method = rbx; - __ movq(method, Address(rax, - entry_offset * wordSize + - vtableEntry::method_offset_in_bytes())); + __ movptr(method, Address(rax, + entry_offset * wordSize + + vtableEntry::method_offset_in_bytes())); if (DebugVtables) { Label L; - __ cmpq(method, (int)NULL); + __ cmpptr(method, (int32_t)NULL_WORD); __ jcc(Assembler::equal, L); - __ cmpq(Address(method, methodOopDesc::from_compiled_offset()), (int)NULL_WORD); + __ cmpptr(Address(method, methodOopDesc::from_compiled_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::notZero, L); __ stop("Vtable entry is NULL"); __ bind(L); @@ -138,7 +138,7 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { // when there are mistakes in this assembly code that could generate // a spurious fault. Ask me how I know... - __ pushq(j_rarg1); // Most registers are in use, so save one + __ push(j_rarg1); // Most registers are in use, so save one // compute itable entry offset (in words) const int base = instanceKlass::vtable_start_offset() * wordSize; @@ -147,27 +147,27 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { // Get length of vtable __ movl(j_rarg1, Address(rbx, instanceKlass::vtable_length_offset() * wordSize)); - __ leaq(rbx, Address(rbx, j_rarg1, Address::times_8, base)); + __ lea(rbx, Address(rbx, j_rarg1, Address::times_8, base)); if (HeapWordsPerLong > 1) { // Round up to align_object_offset boundary - __ round_to_q(rbx, BytesPerLong); + __ round_to(rbx, BytesPerLong); } Label hit, next, entry, throw_icce; __ jmpb(entry); __ bind(next); - __ addq(rbx, itableOffsetEntry::size() * wordSize); + __ addptr(rbx, itableOffsetEntry::size() * wordSize); __ bind(entry); // If the entry is NULL then we've reached the end of the table // without finding the expected interface, so throw an exception - __ movq(j_rarg1, Address(rbx, itableOffsetEntry::interface_offset_in_bytes())); - __ testq(j_rarg1, j_rarg1); + __ movptr(j_rarg1, Address(rbx, itableOffsetEntry::interface_offset_in_bytes())); + __ testptr(j_rarg1, j_rarg1); __ jcc(Assembler::zero, throw_icce); - __ cmpq(rax, j_rarg1); + __ cmpptr(rax, j_rarg1); __ jccb(Assembler::notEqual, next); // We found a hit, move offset into j_rarg1 @@ -184,10 +184,10 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { __ load_klass(rax, j_rarg0); const Register method = rbx; - __ movq(method, Address(rax, j_rarg1, Address::times_1, method_offset)); + __ movptr(method, Address(rax, j_rarg1, Address::times_1, method_offset)); // Restore saved register, before possible trap. - __ popq(j_rarg1); + __ pop(j_rarg1); // method (rbx): methodOop // j_rarg0: receiver @@ -196,9 +196,9 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { #ifdef ASSERT if (DebugVtables) { Label L2; - __ cmpq(method, (int)NULL); + __ cmpptr(method, (int32_t)NULL_WORD); __ jcc(Assembler::equal, L2); - __ cmpq(Address(method, methodOopDesc::from_compiled_offset()), (int)NULL_WORD); + __ cmpptr(Address(method, methodOopDesc::from_compiled_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::notZero, L2); __ stop("compiler entrypoint is null"); __ bind(L2); @@ -212,7 +212,7 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { __ bind(throw_icce); // Restore saved register - __ popq(j_rarg1); + __ pop(j_rarg1); __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry())); __ flush(); diff --git a/hotspot/src/cpu/x86/vm/x86_32.ad b/hotspot/src/cpu/x86/vm/x86_32.ad index 35db833e9ef..a4a4199312d 100644 --- a/hotspot/src/cpu/x86/vm/x86_32.ad +++ b/hotspot/src/cpu/x86/vm/x86_32.ad @@ -236,7 +236,7 @@ reg_class xdb_reg7( XMM7a,XMM7b ); // This is a block of C++ code which provides values, functions, and // definitions necessary in the rest of the architecture description source %{ -#define RELOC_IMM32 Assembler::imm32_operand +#define RELOC_IMM32 Assembler::imm_operand #define RELOC_DISP32 Assembler::disp32_operand #define __ _masm. @@ -593,11 +593,11 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { if (VerifyStackAtCalls) { Label L; MacroAssembler masm(&cbuf); - masm.pushl(rax); - masm.movl(rax, rsp); - masm.andl(rax, StackAlignmentInBytes-1); - masm.cmpl(rax, StackAlignmentInBytes-wordSize); - masm.popl(rax); + masm.push(rax); + masm.mov(rax, rsp); + masm.andptr(rax, StackAlignmentInBytes-1); + masm.cmpptr(rax, StackAlignmentInBytes-wordSize); + masm.pop(rax); masm.jcc(Assembler::equal, L); masm.stop("Stack is not properly aligned!"); masm.bind(L); @@ -1150,7 +1150,8 @@ void emit_java_to_interp(CodeBuffer &cbuf ) { __ relocate(static_stub_Relocation::spec(mark), RELOC_IMM32); // static stub relocation also tags the methodOop in the code-stream. __ movoop(rbx, (jobject)NULL); // method is zapped till fixup time - __ jump(RuntimeAddress((address)-1)); + // This is recognized as unresolved by relocs/nativeInst/ic code + __ jump(RuntimeAddress(__ pc())); __ end_a_stub(); // Update current stubs pointer and restore code_end. @@ -1181,7 +1182,7 @@ void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { #ifdef ASSERT uint code_size = cbuf.code_size(); #endif - masm.cmpl(rax, Address(rcx, oopDesc::klass_offset_in_bytes())); + masm.cmpptr(rax, Address(rcx, oopDesc::klass_offset_in_bytes())); masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); /* WARNING these NOPs are critical so that verified entry point is properly @@ -1687,20 +1688,20 @@ encode %{ // Compare super with sub directly, since super is not in its own SSA. // The compiler used to emit this test, but we fold it in here, // to allow platform-specific tweaking on sparc. - __ cmpl(Reax, Resi); + __ cmpptr(Reax, Resi); __ jcc(Assembler::equal, hit); #ifndef PRODUCT - __ increment(ExternalAddress((address)&SharedRuntime::_partial_subtype_ctr)); + __ incrementl(ExternalAddress((address)&SharedRuntime::_partial_subtype_ctr)); #endif //PRODUCT - __ movl(Redi,Address(Resi,sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())); + __ movptr(Redi,Address(Resi,sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())); __ movl(Recx,Address(Redi,arrayOopDesc::length_offset_in_bytes())); - __ addl(Redi,arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + __ addptr(Redi,arrayOopDesc::base_offset_in_bytes(T_OBJECT)); __ repne_scan(); __ jcc(Assembler::notEqual, miss); - __ movl(Address(Resi,sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()),Reax); + __ movptr(Address(Resi,sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()),Reax); __ bind(hit); if( $primary ) - __ xorl(Redi,Redi); + __ xorptr(Redi,Redi); __ bind(miss); %} @@ -1749,15 +1750,15 @@ encode %{ // optimizer if the C function is a pure function. __ ffree(0); } else if (rt == T_FLOAT) { - __ leal(rsp, Address(rsp, -4)); + __ lea(rsp, Address(rsp, -4)); __ fstp_s(Address(rsp, 0)); __ movflt(xmm0, Address(rsp, 0)); - __ leal(rsp, Address(rsp, 4)); + __ lea(rsp, Address(rsp, 4)); } else if (rt == T_DOUBLE) { - __ leal(rsp, Address(rsp, -8)); + __ lea(rsp, Address(rsp, -8)); __ fstp_d(Address(rsp, 0)); __ movdbl(xmm0, Address(rsp, 0)); - __ leal(rsp, Address(rsp, 8)); + __ lea(rsp, Address(rsp, 8)); } } %} @@ -2888,10 +2889,10 @@ encode %{ __ jccb(Assembler::equal, done); __ jccb(Assembler::above, inc); __ bind(nan); - __ decrement(as_Register($dst$$reg)); + __ decrement(as_Register($dst$$reg)); // NO L qqq __ jmpb(done); __ bind(inc); - __ increment(as_Register($dst$$reg)); + __ increment(as_Register($dst$$reg)); // NO L qqq __ bind(done); %} @@ -3158,7 +3159,7 @@ encode %{ enc_class mov_i2x(regXD dst, eRegI src) %{ MacroAssembler _masm(&cbuf); - __ movd(as_XMMRegister($dst$$reg), as_Register($src$$reg)); + __ movdl(as_XMMRegister($dst$$reg), as_Register($src$$reg)); %} @@ -3258,30 +3259,30 @@ encode %{ } if (EmitSync & 1) { // set box->dhw = unused_mark (3) - // Force all sync thru slow-path: slow_enter() and slow_exit() - masm.movl (Address(boxReg, 0), intptr_t(markOopDesc::unused_mark())) ; - masm.cmpl (rsp, 0) ; - } else - if (EmitSync & 2) { - Label DONE_LABEL ; + // Force all sync thru slow-path: slow_enter() and slow_exit() + masm.movptr (Address(boxReg, 0), int32_t(markOopDesc::unused_mark())) ; + masm.cmpptr (rsp, (int32_t)0) ; + } else + if (EmitSync & 2) { + Label DONE_LABEL ; if (UseBiasedLocking) { // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument. masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); } - masm.movl (tmpReg, Address(objReg, 0)) ; // fetch markword - masm.orl (tmpReg, 0x1); - masm.movl (Address(boxReg, 0), tmpReg); // Anticipate successful CAS + masm.movptr(tmpReg, Address(objReg, 0)) ; // fetch markword + masm.orptr (tmpReg, 0x1); + masm.movptr(Address(boxReg, 0), tmpReg); // Anticipate successful CAS if (os::is_MP()) { masm.lock(); } - masm.cmpxchg(boxReg, Address(objReg, 0)); // Updates tmpReg + masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg masm.jcc(Assembler::equal, DONE_LABEL); // Recursive locking - masm.subl(tmpReg, rsp); - masm.andl(tmpReg, 0xFFFFF003 ); - masm.movl(Address(boxReg, 0), tmpReg); - masm.bind(DONE_LABEL) ; - } else { - // Possible cases that we'll encounter in fast_lock + masm.subptr(tmpReg, rsp); + masm.andptr(tmpReg, (int32_t) 0xFFFFF003 ); + masm.movptr(Address(boxReg, 0), tmpReg); + masm.bind(DONE_LABEL) ; + } else { + // Possible cases that we'll encounter in fast_lock // ------------------------------------------------ // * Inflated // -- unlocked @@ -3310,15 +3311,15 @@ encode %{ masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); } - masm.movl (tmpReg, Address(objReg, 0)) ; // [FETCH] - masm.testl (tmpReg, 0x02) ; // Inflated v (Stack-locked or neutral) + masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH] + masm.testptr(tmpReg, 0x02) ; // Inflated v (Stack-locked or neutral) masm.jccb (Assembler::notZero, IsInflated) ; // Attempt stack-locking ... - masm.orl (tmpReg, 0x1); - masm.movl (Address(boxReg, 0), tmpReg); // Anticipate successful CAS + masm.orptr (tmpReg, 0x1); + masm.movptr(Address(boxReg, 0), tmpReg); // Anticipate successful CAS if (os::is_MP()) { masm.lock(); } - masm.cmpxchg(boxReg, Address(objReg, 0)); // Updates tmpReg + masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg if (_counters != NULL) { masm.cond_inc32(Assembler::equal, ExternalAddress((address)_counters->fast_path_entry_count_addr())); @@ -3326,9 +3327,9 @@ encode %{ masm.jccb (Assembler::equal, DONE_LABEL); // Recursive locking - masm.subl(tmpReg, rsp); - masm.andl(tmpReg, 0xFFFFF003 ); - masm.movl(Address(boxReg, 0), tmpReg); + masm.subptr(tmpReg, rsp); + masm.andptr(tmpReg, 0xFFFFF003 ); + masm.movptr(Address(boxReg, 0), tmpReg); if (_counters != NULL) { masm.cond_inc32(Assembler::equal, ExternalAddress((address)_counters->fast_path_entry_count_addr())); @@ -3360,36 +3361,33 @@ encode %{ // This is convenient but results a ST-before-CAS penalty. The following CAS suffers // additional latency as we have another ST in the store buffer that must drain. - if (EmitSync & 8192) { - masm.movl (Address(boxReg, 0), 3) ; // results in ST-before-CAS penalty - masm.get_thread (scrReg) ; - masm.movl (boxReg, tmpReg); // consider: LEA box, [tmp-2] - masm.movl (tmpReg, 0); // consider: xor vs mov - if (os::is_MP()) { masm.lock(); } - masm.cmpxchg (scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; - } else + if (EmitSync & 8192) { + masm.movptr(Address(boxReg, 0), 3) ; // results in ST-before-CAS penalty + masm.get_thread (scrReg) ; + masm.movptr(boxReg, tmpReg); // consider: LEA box, [tmp-2] + masm.movptr(tmpReg, 0); // consider: xor vs mov + if (os::is_MP()) { masm.lock(); } + masm.cmpxchgptr(scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; + } else if ((EmitSync & 128) == 0) { // avoid ST-before-CAS - masm.movl (scrReg, boxReg) ; - masm.movl (boxReg, tmpReg); // consider: LEA box, [tmp-2] + masm.movptr(scrReg, boxReg) ; + masm.movptr(boxReg, tmpReg); // consider: LEA box, [tmp-2] // Using a prefetchw helps avoid later RTS->RTO upgrades and cache probes if ((EmitSync & 2048) && VM_Version::supports_3dnow() && os::is_MP()) { // prefetchw [eax + Offset(_owner)-2] - masm.emit_raw (0x0F) ; - masm.emit_raw (0x0D) ; - masm.emit_raw (0x48) ; - masm.emit_raw (ObjectMonitor::owner_offset_in_bytes()-2) ; + masm.prefetchw(Address(rax, ObjectMonitor::owner_offset_in_bytes()-2)); } if ((EmitSync & 64) == 0) { // Optimistic form: consider XORL tmpReg,tmpReg - masm.movl (tmpReg, 0 ) ; - } else { + masm.movptr(tmpReg, 0 ) ; + } else { // Can suffer RTS->RTO upgrades on shared or cold $ lines // Test-And-CAS instead of CAS - masm.movl (tmpReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; // rax, = m->_owner - masm.testl (tmpReg, tmpReg) ; // Locked ? - masm.jccb (Assembler::notZero, DONE_LABEL) ; + masm.movptr(tmpReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; // rax, = m->_owner + masm.testptr(tmpReg, tmpReg) ; // Locked ? + masm.jccb (Assembler::notZero, DONE_LABEL) ; } // Appears unlocked - try to swing _owner from null to non-null. @@ -3401,41 +3399,38 @@ encode %{ // (rsp or the address of the box) into m->owner is harmless. // Invariant: tmpReg == 0. tmpReg is EAX which is the implicit cmpxchg comparand. if (os::is_MP()) { masm.lock(); } - masm.cmpxchg (scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; - masm.movl (Address(scrReg, 0), 3) ; // box->_displaced_header = 3 - masm.jccb (Assembler::notZero, DONE_LABEL) ; + masm.cmpxchgptr(scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; + masm.movptr(Address(scrReg, 0), 3) ; // box->_displaced_header = 3 + masm.jccb (Assembler::notZero, DONE_LABEL) ; masm.get_thread (scrReg) ; // beware: clobbers ICCs - masm.movl (Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2), scrReg) ; - masm.xorl (boxReg, boxReg) ; // set icc.ZFlag = 1 to indicate success - - // If the CAS fails we can either retry or pass control to the slow-path. - // We use the latter tactic. + masm.movptr(Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2), scrReg) ; + masm.xorptr(boxReg, boxReg) ; // set icc.ZFlag = 1 to indicate success + + // If the CAS fails we can either retry or pass control to the slow-path. + // We use the latter tactic. // Pass the CAS result in the icc.ZFlag into DONE_LABEL // If the CAS was successful ... // Self has acquired the lock // Invariant: m->_recursions should already be 0, so we don't need to explicitly set it. // Intentional fall-through into DONE_LABEL ... } else { - masm.movl (Address(boxReg, 0), 3) ; // results in ST-before-CAS penalty - masm.movl (boxReg, tmpReg) ; + masm.movptr(Address(boxReg, 0), 3) ; // results in ST-before-CAS penalty + masm.movptr(boxReg, tmpReg) ; // Using a prefetchw helps avoid later RTS->RTO upgrades and cache probes if ((EmitSync & 2048) && VM_Version::supports_3dnow() && os::is_MP()) { // prefetchw [eax + Offset(_owner)-2] - masm.emit_raw (0x0F) ; - masm.emit_raw (0x0D) ; - masm.emit_raw (0x48) ; - masm.emit_raw (ObjectMonitor::owner_offset_in_bytes()-2) ; + masm.prefetchw(Address(rax, ObjectMonitor::owner_offset_in_bytes()-2)); } if ((EmitSync & 64) == 0) { // Optimistic form - masm.xorl (tmpReg, tmpReg) ; - } else { + masm.xorptr (tmpReg, tmpReg) ; + } else { // Can suffer RTS->RTO upgrades on shared or cold $ lines - masm.movl (tmpReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; // rax, = m->_owner - masm.testl (tmpReg, tmpReg) ; // Locked ? - masm.jccb (Assembler::notZero, DONE_LABEL) ; + masm.movptr(tmpReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; // rax, = m->_owner + masm.testptr(tmpReg, tmpReg) ; // Locked ? + masm.jccb (Assembler::notZero, DONE_LABEL) ; } // Appears unlocked - try to swing _owner from null to non-null. @@ -3443,7 +3438,7 @@ encode %{ // Invariant: tmpReg == 0. tmpReg is EAX which is the implicit cmpxchg comparand. masm.get_thread (scrReg) ; if (os::is_MP()) { masm.lock(); } - masm.cmpxchg (scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; + masm.cmpxchgptr(scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; // If the CAS fails we can either retry or pass control to the slow-path. // We use the latter tactic. @@ -3514,19 +3509,19 @@ encode %{ if (EmitSync & 4) { // Disable - inhibit all inlining. Force control through the slow-path - masm.cmpl (rsp, 0) ; - } else + masm.cmpptr (rsp, 0) ; + } else if (EmitSync & 8) { Label DONE_LABEL ; if (UseBiasedLocking) { masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); } // classic stack-locking code ... - masm.movl (tmpReg, Address(boxReg, 0)) ; - masm.testl (tmpReg, tmpReg) ; + masm.movptr(tmpReg, Address(boxReg, 0)) ; + masm.testptr(tmpReg, tmpReg) ; masm.jcc (Assembler::zero, DONE_LABEL) ; if (os::is_MP()) { masm.lock(); } - masm.cmpxchg(tmpReg, Address(objReg, 0)); // Uses EAX which is box + masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses EAX which is box masm.bind(DONE_LABEL); } else { Label DONE_LABEL, Stacked, CheckSucc, Inflated ; @@ -3536,12 +3531,12 @@ encode %{ if (UseBiasedLocking) { masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); } - - masm.cmpl (Address(boxReg, 0), 0) ; // Examine the displaced header - masm.movl (tmpReg, Address(objReg, 0)) ; // Examine the object's markword + + masm.cmpptr(Address(boxReg, 0), 0) ; // Examine the displaced header + masm.movptr(tmpReg, Address(objReg, 0)) ; // Examine the object's markword masm.jccb (Assembler::zero, DONE_LABEL) ; // 0 indicates recursive stack-lock - masm.testl (tmpReg, 0x02) ; // Inflated? + masm.testptr(tmpReg, 0x02) ; // Inflated? masm.jccb (Assembler::zero, Stacked) ; masm.bind (Inflated) ; @@ -3571,11 +3566,8 @@ encode %{ masm.get_thread (boxReg) ; if ((EmitSync & 4096) && VM_Version::supports_3dnow() && os::is_MP()) { - // prefetchw [ebx + Offset(_owner)-2] - masm.emit_raw (0x0F) ; - masm.emit_raw (0x0D) ; - masm.emit_raw (0x4B) ; - masm.emit_raw (ObjectMonitor::owner_offset_in_bytes()-2) ; + // prefetchw [ebx + Offset(_owner)-2] + masm.prefetchw(Address(rbx, ObjectMonitor::owner_offset_in_bytes()-2)); } // Note that we could employ various encoding schemes to reduce @@ -3584,22 +3576,22 @@ encode %{ // In practice the chain of fetches doesn't seem to impact performance, however. if ((EmitSync & 65536) == 0 && (EmitSync & 256)) { // Attempt to reduce branch density - AMD's branch predictor. - masm.xorl (boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; - masm.orl (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; - masm.orl (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; - masm.orl (boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; - masm.jccb (Assembler::notZero, DONE_LABEL) ; - masm.movl (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), 0) ; - masm.jmpb (DONE_LABEL) ; - } else { - masm.xorl (boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; - masm.orl (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; - masm.jccb (Assembler::notZero, DONE_LABEL) ; - masm.movl (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; - masm.orl (boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; - masm.jccb (Assembler::notZero, CheckSucc) ; - masm.movl (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), 0) ; - masm.jmpb (DONE_LABEL) ; + masm.xorptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; + masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; + masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; + masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; + masm.jccb (Assembler::notZero, DONE_LABEL) ; + masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), 0) ; + masm.jmpb (DONE_LABEL) ; + } else { + masm.xorptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; + masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; + masm.jccb (Assembler::notZero, DONE_LABEL) ; + masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; + masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; + masm.jccb (Assembler::notZero, CheckSucc) ; + masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), 0) ; + masm.jmpb (DONE_LABEL) ; } // The Following code fragment (EmitSync & 65536) improves the performance of @@ -3615,9 +3607,9 @@ encode %{ masm.bind (CheckSucc) ; // Optional pre-test ... it's safe to elide this - if ((EmitSync & 16) == 0) { - masm.cmpl (Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), 0) ; - masm.jccb (Assembler::zero, LGoSlowPath) ; + if ((EmitSync & 16) == 0) { + masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), 0) ; + masm.jccb (Assembler::zero, LGoSlowPath) ; } // We have a classic Dekker-style idiom: @@ -3645,39 +3637,37 @@ encode %{ // // We currently use (3), although it's likely that switching to (2) // is correct for the future. - - masm.movl (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), 0) ; - if (os::is_MP()) { - if (VM_Version::supports_sse2() && 1 == FenceInstruction) { - masm.emit_raw (0x0F) ; // MFENCE ... - masm.emit_raw (0xAE) ; - masm.emit_raw (0xF0) ; - } else { - masm.lock () ; masm.addl (Address(rsp, 0), 0) ; + + masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), 0) ; + if (os::is_MP()) { + if (VM_Version::supports_sse2() && 1 == FenceInstruction) { + masm.mfence(); + } else { + masm.lock () ; masm.addptr(Address(rsp, 0), 0) ; } } // Ratify _succ remains non-null - masm.cmpl (Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), 0) ; - masm.jccb (Assembler::notZero, LSuccess) ; + masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), 0) ; + masm.jccb (Assembler::notZero, LSuccess) ; - masm.xorl (boxReg, boxReg) ; // box is really EAX + masm.xorptr(boxReg, boxReg) ; // box is really EAX if (os::is_MP()) { masm.lock(); } - masm.cmpxchg(rsp, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); + masm.cmpxchgptr(rsp, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); masm.jccb (Assembler::notEqual, LSuccess) ; // Since we're low on registers we installed rsp as a placeholding in _owner. // Now install Self over rsp. This is safe as we're transitioning from // non-null to non=null masm.get_thread (boxReg) ; - masm.movl (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), boxReg) ; + masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), boxReg) ; // Intentional fall-through into LGoSlowPath ... - masm.bind (LGoSlowPath) ; - masm.orl (boxReg, 1) ; // set ICC.ZF=0 to indicate failure - masm.jmpb (DONE_LABEL) ; + masm.bind (LGoSlowPath) ; + masm.orptr(boxReg, 1) ; // set ICC.ZF=0 to indicate failure + masm.jmpb (DONE_LABEL) ; - masm.bind (LSuccess) ; - masm.xorl (boxReg, boxReg) ; // set ICC.ZF=1 to indicate success - masm.jmpb (DONE_LABEL) ; + masm.bind (LSuccess) ; + masm.xorptr(boxReg, boxReg) ; // set ICC.ZF=1 to indicate success + masm.jmpb (DONE_LABEL) ; } masm.bind (Stacked) ; @@ -3686,9 +3676,9 @@ encode %{ // Try to reset the header to displaced header. // The "box" value on the stack is stable, so we can reload // and be assured we observe the same value as above. - masm.movl (tmpReg, Address(boxReg, 0)) ; + masm.movptr(tmpReg, Address(boxReg, 0)) ; if (os::is_MP()) { masm.lock(); } - masm.cmpxchg(tmpReg, Address(objReg, 0)); // Uses EAX which is box + masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses EAX which is box // Intention fall-thru into DONE_LABEL @@ -3720,12 +3710,12 @@ encode %{ int count_offset = java_lang_String::count_offset_in_bytes(); int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); - masm.movl(rax, Address(rsi, value_offset)); + masm.movptr(rax, Address(rsi, value_offset)); masm.movl(rcx, Address(rsi, offset_offset)); - masm.leal(rax, Address(rax, rcx, Address::times_2, base_offset)); - masm.movl(rbx, Address(rdi, value_offset)); + masm.lea(rax, Address(rax, rcx, Address::times_2, base_offset)); + masm.movptr(rbx, Address(rdi, value_offset)); masm.movl(rcx, Address(rdi, offset_offset)); - masm.leal(rbx, Address(rbx, rcx, Address::times_2, base_offset)); + masm.lea(rbx, Address(rbx, rcx, Address::times_2, base_offset)); // Compute the minimum of the string lengths(rsi) and the // difference of the string lengths (stack) @@ -3736,14 +3726,14 @@ encode %{ masm.movl(rsi, Address(rsi, count_offset)); masm.movl(rcx, rdi); masm.subl(rdi, rsi); - masm.pushl(rdi); + masm.push(rdi); masm.cmovl(Assembler::lessEqual, rsi, rcx); } else { masm.movl(rdi, Address(rdi, count_offset)); masm.movl(rcx, Address(rsi, count_offset)); masm.movl(rsi, rdi); masm.subl(rdi, rcx); - masm.pushl(rdi); + masm.push(rdi); masm.jcc(Assembler::lessEqual, ECX_GOOD_LABEL); masm.movl(rsi, rcx); // rsi holds min, rcx is unused @@ -3761,14 +3751,14 @@ encode %{ // Compare first characters masm.subl(rcx, rdi); masm.jcc(Assembler::notZero, POP_LABEL); - masm.decrement(rsi); + masm.decrementl(rsi); masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL); { // Check after comparing first character to see if strings are equivalent Label LSkip2; // Check if the strings start at same location - masm.cmpl(rbx,rax); + masm.cmpptr(rbx,rax); masm.jcc(Assembler::notEqual, LSkip2); // Check if the length difference is zero (from stack) @@ -3780,8 +3770,8 @@ encode %{ } // Shift rax, and rbx, to the end of the arrays, negate min - masm.leal(rax, Address(rax, rsi, Address::times_2, 2)); - masm.leal(rbx, Address(rbx, rsi, Address::times_2, 2)); + masm.lea(rax, Address(rax, rsi, Address::times_2, 2)); + masm.lea(rbx, Address(rbx, rsi, Address::times_2, 2)); masm.negl(rsi); // Compare the rest of the characters @@ -3790,18 +3780,18 @@ encode %{ masm.load_unsigned_word(rdi, Address(rax, rsi, Address::times_2, 0)); masm.subl(rcx, rdi); masm.jcc(Assembler::notZero, POP_LABEL); - masm.increment(rsi); + masm.incrementl(rsi); masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL); // Strings are equal up to min length. Return the length difference. masm.bind(LENGTH_DIFF_LABEL); - masm.popl(rcx); + masm.pop(rcx); masm.jmp(DONE_LABEL); // Discard the stored length difference masm.bind(POP_LABEL); - masm.addl(rsp, 4); - + masm.addptr(rsp, 4); + // That's it masm.bind(DONE_LABEL); %} @@ -4315,7 +4305,8 @@ encode %{ enc_class enc_membar_volatile %{ MacroAssembler masm(&cbuf); - masm.membar(); + masm.membar(Assembler::Membar_mask_bits(Assembler::StoreLoad | + Assembler::StoreStore)); %} // Atomically load the volatile long @@ -11151,7 +11142,7 @@ instruct convXI2XD_reg(regXD dst, eRegI src) format %{ "MOVD $dst,$src\n\t" "CVTDQ2PD $dst,$dst\t# i2d" %} ins_encode %{ - __ movd($dst$$XMMRegister, $src$$Register); + __ movdl($dst$$XMMRegister, $src$$Register); __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); %} ins_pipe(pipe_slow); // XXX @@ -11249,7 +11240,7 @@ instruct convI2X_reg(regX dst, eRegI src) %{ format %{ "MOVD $dst,$src\n\t" "CVTDQ2PS $dst,$dst\t# i2f" %} ins_encode %{ - __ movd($dst$$XMMRegister, $src$$Register); + __ movdl($dst$$XMMRegister, $src$$Register); __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); %} ins_pipe(pipe_slow); // XXX @@ -12262,7 +12253,7 @@ instruct cmpL3_reg_reg(eSIRegI dst, eRegL src1, eRegL src2, eFlagsReg flags ) %{ "done:" %} ins_encode %{ Label p_one, m_one, done; - __ xorl($dst$$Register, $dst$$Register); + __ xorptr($dst$$Register, $dst$$Register); __ cmpl(HIGH_FROM_LOW($src1$$Register), HIGH_FROM_LOW($src2$$Register)); __ jccb(Assembler::less, m_one); __ jccb(Assembler::greater, p_one); @@ -12270,10 +12261,10 @@ instruct cmpL3_reg_reg(eSIRegI dst, eRegL src1, eRegL src2, eFlagsReg flags ) %{ __ jccb(Assembler::below, m_one); __ jccb(Assembler::equal, done); __ bind(p_one); - __ increment($dst$$Register); + __ incrementl($dst$$Register); __ jmpb(done); __ bind(m_one); - __ decrement($dst$$Register); + __ decrementl($dst$$Register); __ bind(done); %} ins_pipe( pipe_slow ); diff --git a/hotspot/src/cpu/x86/vm/x86_64.ad b/hotspot/src/cpu/x86/vm/x86_64.ad index 302994148c0..62b46da14b0 100644 --- a/hotspot/src/cpu/x86/vm/x86_64.ad +++ b/hotspot/src/cpu/x86/vm/x86_64.ad @@ -478,7 +478,7 @@ reg_class int_no_rcx_reg(RAX, // Class for all int registers except RAX, RDX (and RSP) reg_class int_no_rax_rdx_reg(RBP, - RDI + RDI, RSI, RCX, RBX, @@ -552,7 +552,7 @@ reg_class double_reg(XMM0, XMM0_H, // This is a block of C++ code which provides values, functions, and // definitions necessary in the rest of the architecture description source %{ -#define RELOC_IMM64 Assembler::imm64_operand +#define RELOC_IMM64 Assembler::imm_operand #define RELOC_DISP32 Assembler::disp32_operand #define __ _masm. @@ -962,11 +962,11 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const if (VerifyStackAtCalls) { Label L; MacroAssembler masm(&cbuf); - masm.pushq(rax); - masm.movq(rax, rsp); - masm.andq(rax, StackAlignmentInBytes-1); - masm.cmpq(rax, StackAlignmentInBytes-wordSize); - masm.popq(rax); + masm.push(rax); + masm.mov(rax, rsp); + masm.andptr(rax, StackAlignmentInBytes-1); + masm.cmpptr(rax, StackAlignmentInBytes-wordSize); + masm.pop(rax); masm.jcc(Assembler::equal, L); masm.stop("Stack is not properly aligned!"); masm.bind(L); @@ -1817,6 +1817,7 @@ void emit_java_to_interp(CodeBuffer& cbuf) __ relocate(static_stub_Relocation::spec(mark), RELOC_IMM64); // static stub relocation also tags the methodOop in the code-stream. __ movoop(rbx, (jobject) NULL); // method is zapped till fixup time + // This is recognized as unresolved by relocs/nativeinst/ic code __ jump(RuntimeAddress(__ pc())); // Update current stubs pointer and restore code_end. @@ -1863,9 +1864,9 @@ void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const #endif if (UseCompressedOops) { masm.load_klass(rscratch1, j_rarg0); - masm.cmpq(rax, rscratch1); + masm.cmpptr(rax, rscratch1); } else { - masm.cmpq(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); + masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); } masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); @@ -1949,7 +1950,7 @@ int emit_deopt_handler(CodeBuffer& cbuf) __ call(next, relocInfo::none); // reloc none is fine since it is a disp32 __ bind(next); // adjust it so it matches "the_pc" - __ subq(Address(rsp, 0), __ offset() - offset); + __ subptr(Address(rsp, 0), __ offset() - offset); __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); __ end_a_stub(); @@ -2577,23 +2578,23 @@ encode %{ // Compare super with sub directly, since super is not in its own SSA. // The compiler used to emit this test, but we fold it in here, // to allow platform-specific tweaking on sparc. - __ cmpq(Rrax, Rrsi); + __ cmpptr(Rrax, Rrsi); __ jcc(Assembler::equal, hit); #ifndef PRODUCT __ lea(Rrcx, ExternalAddress((address)&SharedRuntime::_partial_subtype_ctr)); __ incrementl(Address(Rrcx, 0)); #endif //PRODUCT - __ movq(Rrdi, Address(Rrsi, - sizeof(oopDesc) + + __ movptr(Rrdi, Address(Rrsi, + sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())); __ movl(Rrcx, Address(Rrdi, arrayOopDesc::length_offset_in_bytes())); - __ addq(Rrdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + __ addptr(Rrdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); if (UseCompressedOops) { __ encode_heap_oop(Rrax); __ repne_scanl(); __ jcc(Assembler::notEqual, cmiss); __ decode_heap_oop(Rrax); - __ movq(Address(Rrsi, + __ movptr(Address(Rrsi, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()), Rrax); @@ -2602,16 +2603,16 @@ encode %{ __ decode_heap_oop(Rrax); __ jmp(miss); } else { - __ repne_scanq(); + __ repne_scan(); __ jcc(Assembler::notEqual, miss); - __ movq(Address(Rrsi, + __ movptr(Address(Rrsi, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()), Rrax); } __ bind(hit); if ($primary) { - __ xorq(Rrdi, Rrdi); + __ xorptr(Rrdi, Rrdi); } __ bind(miss); %} @@ -3527,8 +3528,9 @@ encode %{ masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr())); } if (EmitSync & 1) { - masm.movptr (Address(boxReg, 0), intptr_t(markOopDesc::unused_mark())) ; - masm.cmpq (rsp, 0) ; + // Without cast to int32_t a movptr will destroy r10 which is typically obj + masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; + masm.cmpptr(rsp, (int32_t)NULL_WORD) ; } else if (EmitSync & 2) { Label DONE_LABEL; @@ -3536,29 +3538,30 @@ encode %{ // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument. masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); } - masm.movl(tmpReg, 0x1); - masm.orq(tmpReg, Address(objReg, 0)); - masm.movq(Address(boxReg, 0), tmpReg); + // QQQ was movl... + masm.movptr(tmpReg, 0x1); + masm.orptr(tmpReg, Address(objReg, 0)); + masm.movptr(Address(boxReg, 0), tmpReg); if (os::is_MP()) { masm.lock(); } - masm.cmpxchgq(boxReg, Address(objReg, 0)); // Updates tmpReg + masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg masm.jcc(Assembler::equal, DONE_LABEL); // Recursive locking - masm.subq(tmpReg, rsp); - masm.andq(tmpReg, 7 - os::vm_page_size()); - masm.movq(Address(boxReg, 0), tmpReg); + masm.subptr(tmpReg, rsp); + masm.andptr(tmpReg, 7 - os::vm_page_size()); + masm.movptr(Address(boxReg, 0), tmpReg); masm.bind(DONE_LABEL); masm.nop(); // avoid branch to branch } else { Label DONE_LABEL, IsInflated, Egress; - masm.movq (tmpReg, Address(objReg, 0)) ; - masm.testq (tmpReg, 0x02) ; // inflated vs stack-locked|neutral|biased - masm.jcc (Assembler::notZero, IsInflated) ; - + masm.movptr(tmpReg, Address(objReg, 0)) ; + masm.testl (tmpReg, 0x02) ; // inflated vs stack-locked|neutral|biased + masm.jcc (Assembler::notZero, IsInflated) ; + // it's stack-locked, biased or neutral // TODO: optimize markword triage order to reduce the number of // conditional branches in the most common cases. @@ -3568,13 +3571,14 @@ encode %{ if (UseBiasedLocking) { masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters); - masm.movq (tmpReg, Address(objReg, 0)) ; // [FETCH] + masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH] } - masm.orq (tmpReg, 1) ; - masm.movq (Address(boxReg, 0), tmpReg) ; - if (os::is_MP()) { masm.lock(); } - masm.cmpxchgq(boxReg, Address(objReg, 0)); // Updates tmpReg + // was q will it destroy high? + masm.orl (tmpReg, 1) ; + masm.movptr(Address(boxReg, 0), tmpReg) ; + if (os::is_MP()) { masm.lock(); } + masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg if (_counters != NULL) { masm.cond_inc32(Assembler::equal, ExternalAddress((address) _counters->fast_path_entry_count_addr())); @@ -3582,9 +3586,9 @@ encode %{ masm.jcc (Assembler::equal, DONE_LABEL); // Recursive locking - masm.subq (tmpReg, rsp); - masm.andq (tmpReg, 7 - os::vm_page_size()); - masm.movq (Address(boxReg, 0), tmpReg); + masm.subptr(tmpReg, rsp); + masm.andptr(tmpReg, 7 - os::vm_page_size()); + masm.movptr(Address(boxReg, 0), tmpReg); if (_counters != NULL) { masm.cond_inc32(Assembler::equal, ExternalAddress((address) _counters->fast_path_entry_count_addr())); @@ -3599,16 +3603,17 @@ encode %{ // We should also think about trying a CAS without having // fetched _owner. If the CAS is successful we may // avoid an RTO->RTS upgrade on the $line. - masm.movptr(Address(boxReg, 0), intptr_t(markOopDesc::unused_mark())) ; + // Without cast to int32_t a movptr will destroy r10 which is typically obj + masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; - masm.movq (boxReg, tmpReg) ; - masm.movq (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; - masm.testq (tmpReg, tmpReg) ; - masm.jcc (Assembler::notZero, DONE_LABEL) ; + masm.mov (boxReg, tmpReg) ; + masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; + masm.testptr(tmpReg, tmpReg) ; + masm.jcc (Assembler::notZero, DONE_LABEL) ; // It's inflated and appears unlocked - if (os::is_MP()) { masm.lock(); } - masm.cmpxchgq(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; + if (os::is_MP()) { masm.lock(); } + masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; // Intentional fall-through into DONE_LABEL ... masm.bind (DONE_LABEL) ; @@ -3627,8 +3632,8 @@ encode %{ Register tmpReg = as_Register($tmp$$reg); MacroAssembler masm(&cbuf); - if (EmitSync & 4) { - masm.cmpq (rsp, 0) ; + if (EmitSync & 4) { + masm.cmpptr(rsp, 0) ; } else if (EmitSync & 8) { Label DONE_LABEL; @@ -3638,15 +3643,15 @@ encode %{ // Check whether the displaced header is 0 //(=> recursive unlock) - masm.movq(tmpReg, Address(boxReg, 0)); - masm.testq(tmpReg, tmpReg); + masm.movptr(tmpReg, Address(boxReg, 0)); + masm.testptr(tmpReg, tmpReg); masm.jcc(Assembler::zero, DONE_LABEL); // If not recursive lock, reset the header to displaced header if (os::is_MP()) { masm.lock(); } - masm.cmpxchgq(tmpReg, Address(objReg, 0)); // Uses RAX which is box + masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box masm.bind(DONE_LABEL); masm.nop(); // avoid branch to branch } else { @@ -3655,44 +3660,44 @@ encode %{ if (UseBiasedLocking) { masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); } - - masm.movq (tmpReg, Address(objReg, 0)) ; - masm.cmpq (Address(boxReg, 0), (int)NULL_WORD) ; - masm.jcc (Assembler::zero, DONE_LABEL) ; - masm.testq (tmpReg, 0x02) ; - masm.jcc (Assembler::zero, Stacked) ; - + + masm.movptr(tmpReg, Address(objReg, 0)) ; + masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ; + masm.jcc (Assembler::zero, DONE_LABEL) ; + masm.testl (tmpReg, 0x02) ; + masm.jcc (Assembler::zero, Stacked) ; + // It's inflated - masm.movq (boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; - masm.xorq (boxReg, r15_thread) ; - masm.orq (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; - masm.jcc (Assembler::notZero, DONE_LABEL) ; - masm.movq (boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; - masm.orq (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; - masm.jcc (Assembler::notZero, CheckSucc) ; - masm.mov64 (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int)NULL_WORD) ; - masm.jmp (DONE_LABEL) ; - - if ((EmitSync & 65536) == 0) { + masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; + masm.xorptr(boxReg, r15_thread) ; + masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; + masm.jcc (Assembler::notZero, DONE_LABEL) ; + masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; + masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; + masm.jcc (Assembler::notZero, CheckSucc) ; + masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; + masm.jmp (DONE_LABEL) ; + + if ((EmitSync & 65536) == 0) { Label LSuccess, LGoSlowPath ; masm.bind (CheckSucc) ; - masm.cmpq (Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int)NULL_WORD) ; + masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; masm.jcc (Assembler::zero, LGoSlowPath) ; // I'd much rather use lock:andl m->_owner, 0 as it's faster than the // the explicit ST;MEMBAR combination, but masm doesn't currently support // "ANDQ M,IMM". Don't use MFENCE here. lock:add to TOS, xchg, etc // are all faster when the write buffer is populated. - masm.movptr (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int)NULL_WORD) ; + masm.movptr (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; if (os::is_MP()) { - masm.lock () ; masm.addq (Address(rsp, 0), 0) ; + masm.lock () ; masm.addl (Address(rsp, 0), 0) ; } - masm.cmpq (Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int)NULL_WORD) ; + masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; masm.jcc (Assembler::notZero, LSuccess) ; - masm.movptr (boxReg, (int)NULL_WORD) ; // box is really EAX + masm.movptr (boxReg, (int32_t)NULL_WORD) ; // box is really EAX if (os::is_MP()) { masm.lock(); } - masm.cmpxchgq (r15_thread, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); + masm.cmpxchgptr(r15_thread, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); masm.jcc (Assembler::notEqual, LSuccess) ; // Intentional fall-through into slow-path @@ -3705,10 +3710,10 @@ encode %{ masm.jmp (DONE_LABEL) ; } - masm.bind (Stacked) ; - masm.movq (tmpReg, Address (boxReg, 0)) ; // re-fetch - if (os::is_MP()) { masm.lock(); } - masm.cmpxchgq(tmpReg, Address(objReg, 0)); // Uses RAX which is box + masm.bind (Stacked) ; + masm.movptr(tmpReg, Address (boxReg, 0)) ; // re-fetch + if (os::is_MP()) { masm.lock(); } + masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box if (EmitSync & 65536) { masm.bind (CheckSucc) ; @@ -3736,10 +3741,10 @@ encode %{ masm.load_heap_oop(rax, Address(rsi, value_offset)); masm.movl(rcx, Address(rsi, offset_offset)); - masm.leaq(rax, Address(rax, rcx, Address::times_2, base_offset)); + masm.lea(rax, Address(rax, rcx, Address::times_2, base_offset)); masm.load_heap_oop(rbx, Address(rdi, value_offset)); masm.movl(rcx, Address(rdi, offset_offset)); - masm.leaq(rbx, Address(rbx, rcx, Address::times_2, base_offset)); + masm.lea(rbx, Address(rbx, rcx, Address::times_2, base_offset)); // Compute the minimum of the string lengths(rsi) and the // difference of the string lengths (stack) @@ -3748,8 +3753,8 @@ encode %{ masm.movl(rsi, Address(rsi, count_offset)); masm.movl(rcx, rdi); masm.subl(rdi, rsi); - masm.pushq(rdi); - masm.cmovl(Assembler::lessEqual, rsi, rcx); + masm.push(rdi); + masm.cmov(Assembler::lessEqual, rsi, rcx); // Is the minimum length zero? masm.bind(RCX_GOOD_LABEL); @@ -3770,7 +3775,7 @@ encode %{ // Check after comparing first character to see if strings are equivalent Label LSkip2; // Check if the strings start at same location - masm.cmpq(rbx, rax); + masm.cmpptr(rbx, rax); masm.jcc(Assembler::notEqual, LSkip2); // Check if the length difference is zero (from stack) @@ -3782,9 +3787,9 @@ encode %{ } // Shift RAX and RBX to the end of the arrays, negate min - masm.leaq(rax, Address(rax, rsi, Address::times_2, 2)); - masm.leaq(rbx, Address(rbx, rsi, Address::times_2, 2)); - masm.negq(rsi); + masm.lea(rax, Address(rax, rsi, Address::times_2, 2)); + masm.lea(rbx, Address(rbx, rsi, Address::times_2, 2)); + masm.negptr(rsi); // Compare the rest of the characters masm.bind(WHILE_HEAD_LABEL); @@ -3792,18 +3797,18 @@ encode %{ masm.load_unsigned_word(rdi, Address(rax, rsi, Address::times_2, 0)); masm.subl(rcx, rdi); masm.jcc(Assembler::notZero, POP_LABEL); - masm.incrementq(rsi); + masm.increment(rsi); masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL); // Strings are equal up to min length. Return the length difference. masm.bind(LENGTH_DIFF_LABEL); - masm.popq(rcx); + masm.pop(rcx); masm.jmp(DONE_LABEL); // Discard the stored length difference masm.bind(POP_LABEL); - masm.addq(rsp, 8); - + masm.addptr(rsp, 8); + // That's it masm.bind(DONE_LABEL); %} @@ -3893,7 +3898,7 @@ encode %{ enc_class absF_encoding(regF dst) %{ int dstenc = $dst$$reg; - address signmask_address = (address) StubRoutines::amd64::float_sign_mask(); + address signmask_address = (address) StubRoutines::x86::float_sign_mask(); cbuf.set_inst_mark(); if (dstenc >= 8) { @@ -3910,7 +3915,7 @@ encode %{ enc_class absD_encoding(regD dst) %{ int dstenc = $dst$$reg; - address signmask_address = (address) StubRoutines::amd64::double_sign_mask(); + address signmask_address = (address) StubRoutines::x86::double_sign_mask(); cbuf.set_inst_mark(); emit_opcode(cbuf, 0x66); @@ -3928,7 +3933,7 @@ encode %{ enc_class negF_encoding(regF dst) %{ int dstenc = $dst$$reg; - address signflip_address = (address) StubRoutines::amd64::float_sign_flip(); + address signflip_address = (address) StubRoutines::x86::float_sign_flip(); cbuf.set_inst_mark(); if (dstenc >= 8) { @@ -3945,7 +3950,7 @@ encode %{ enc_class negD_encoding(regD dst) %{ int dstenc = $dst$$reg; - address signflip_address = (address) StubRoutines::amd64::double_sign_flip(); + address signflip_address = (address) StubRoutines::x86::double_sign_flip(); cbuf.set_inst_mark(); emit_opcode(cbuf, 0x66); @@ -4003,7 +4008,7 @@ encode %{ emit_opcode(cbuf, 0xE8); emit_d32_reloc(cbuf, (int) - (StubRoutines::amd64::f2i_fixup() - cbuf.code_end() - 4), + (StubRoutines::x86::f2i_fixup() - cbuf.code_end() - 4), runtime_call_Relocation::spec(), RELOC_DISP32); @@ -4020,7 +4025,7 @@ encode %{ %{ int dstenc = $dst$$reg; int srcenc = $src$$reg; - address const_address = (address) StubRoutines::amd64::double_sign_flip(); + address const_address = (address) StubRoutines::x86::double_sign_flip(); // cmpq $dst, [0x8000000000000000] cbuf.set_inst_mark(); @@ -4061,7 +4066,7 @@ encode %{ emit_opcode(cbuf, 0xE8); emit_d32_reloc(cbuf, (int) - (StubRoutines::amd64::f2l_fixup() - cbuf.code_end() - 4), + (StubRoutines::x86::f2l_fixup() - cbuf.code_end() - 4), runtime_call_Relocation::spec(), RELOC_DISP32); @@ -4117,7 +4122,7 @@ encode %{ emit_opcode(cbuf, 0xE8); emit_d32_reloc(cbuf, (int) - (StubRoutines::amd64::d2i_fixup() - cbuf.code_end() - 4), + (StubRoutines::x86::d2i_fixup() - cbuf.code_end() - 4), runtime_call_Relocation::spec(), RELOC_DISP32); @@ -4134,7 +4139,7 @@ encode %{ %{ int dstenc = $dst$$reg; int srcenc = $src$$reg; - address const_address = (address) StubRoutines::amd64::double_sign_flip(); + address const_address = (address) StubRoutines::x86::double_sign_flip(); // cmpq $dst, [0x8000000000000000] cbuf.set_inst_mark(); @@ -4175,7 +4180,7 @@ encode %{ emit_opcode(cbuf, 0xE8); emit_d32_reloc(cbuf, (int) - (StubRoutines::amd64::d2l_fixup() - cbuf.code_end() - 4), + (StubRoutines::x86::d2l_fixup() - cbuf.code_end() - 4), runtime_call_Relocation::spec(), RELOC_DISP32); diff --git a/hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86_32.cpp b/hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86.cpp similarity index 63% rename from hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86_32.cpp rename to hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86.cpp index 1854b007516..4211d36118b 100644 --- a/hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86_32.cpp +++ b/hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86.cpp @@ -23,8 +23,9 @@ */ #include "incls/_precompiled.incl" -#include "incls/_assembler_linux_x86_32.cpp.incl" +#include "incls/_assembler_linux_x86.cpp.incl" +#ifndef _LP64 void MacroAssembler::int3() { call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint))); } @@ -39,3 +40,45 @@ void MacroAssembler::get_thread(Register thread) { movptr(thread, tls); } +#else +void MacroAssembler::int3() { + call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint))); +} + +void MacroAssembler::get_thread(Register thread) { + // call pthread_getspecific + // void * pthread_getspecific(pthread_key_t key); + if (thread != rax) { + push(rax); + } + push(rdi); + push(rsi); + push(rdx); + push(rcx); + push(r8); + push(r9); + push(r10); + // XXX + mov(r10, rsp); + andq(rsp, -16); + push(r10); + push(r11); + + movl(rdi, ThreadLocalStorage::thread_index()); + call(RuntimeAddress(CAST_FROM_FN_PTR(address, pthread_getspecific))); + + pop(r11); + pop(rsp); + pop(r10); + pop(r9); + pop(r8); + pop(rcx); + pop(rdx); + pop(rsi); + pop(rdi); + if (thread != rax) { + mov(thread, rax); + pop(rax); + } +} +#endif diff --git a/hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86_64.cpp b/hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86_64.cpp deleted file mode 100644 index 24a4dce09e4..00000000000 --- a/hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86_64.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2003-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. - * - */ - -#include "incls/_precompiled.incl" -#include "incls/_assembler_linux_x86_64.cpp.incl" - -void MacroAssembler::int3() { - call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint))); -} - -void MacroAssembler::get_thread(Register thread) { - // call pthread_getspecific - // void * pthread_getspecific(pthread_key_t key); - if (thread != rax) { - pushq(rax); - } - pushq(rdi); - pushq(rsi); - pushq(rdx); - pushq(rcx); - pushq(r8); - pushq(r9); - pushq(r10); - // XXX - movq(r10, rsp); - andq(rsp, -16); - pushq(r10); - pushq(r11); - - movl(rdi, ThreadLocalStorage::thread_index()); - call(RuntimeAddress(CAST_FROM_FN_PTR(address, pthread_getspecific))); - - popq(r11); - popq(rsp); - popq(r10); - popq(r9); - popq(r8); - popq(rcx); - popq(rdx); - popq(rsi); - popq(rdi); - if (thread != rax) { - movq(thread, rax); - popq(rax); - } -} diff --git a/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86_32.cpp b/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86.cpp similarity index 50% rename from hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86_32.cpp rename to hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86.cpp index bce611c1125..9fd017b41a6 100644 --- a/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86_32.cpp +++ b/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86.cpp @@ -23,59 +23,111 @@ */ #include "incls/_precompiled.incl" -#include "incls/_assembler_solaris_x86_32.cpp.incl" +#include "incls/_assembler_solaris_x86.cpp.incl" void MacroAssembler::int3() { - pushl(rax); - pushl(rdx); - pushl(rcx); + push(rax); + push(rdx); + push(rcx); call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint))); - popl(rcx); - popl(rdx); - popl(rax); + pop(rcx); + pop(rdx); + pop(rax); } -void MacroAssembler::get_thread(Register thread) { - - // Try to emit a Solaris-specific fast TSD/TLS accessor. - ThreadLocalStorage::pd_tlsAccessMode tlsMode = ThreadLocalStorage::pd_getTlsAccessMode () ; - if (tlsMode == ThreadLocalStorage::pd_tlsAccessIndirect) { // T1 - // Use thread as a temporary: mov r, gs:[0]; mov r, [r+tlsOffset] - emit_byte (Assembler::GS_segment) ; - // ExternalAddress doesn't work because it can't take NULL - AddressLiteral null(0, relocInfo::none); - movptr (thread, null); - movl (thread, Address(thread, ThreadLocalStorage::pd_getTlsOffset())) ; - return ; - } else - if (tlsMode == ThreadLocalStorage::pd_tlsAccessDirect) { // T2 - // mov r, gs:[tlsOffset] - emit_byte (Assembler::GS_segment) ; - AddressLiteral tls((address)ThreadLocalStorage::pd_getTlsOffset(), relocInfo::none); - movptr (thread, tls); - return ; - } +#define __ _masm-> +#ifndef _LP64 +static void slow_call_thr_specific(MacroAssembler* _masm, Register thread) { // slow call to of thr_getspecific // int thr_getspecific(thread_key_t key, void **value); // Consider using pthread_getspecific instead. - pushl(0); // allocate space for return value - if (thread != rax) pushl(rax); // save rax, if caller still wants it - pushl(rcx); // save caller save - pushl(rdx); // save caller save +__ push(0); // allocate space for return value + if (thread != rax) __ push(rax); // save rax, if caller still wants it +__ push(rcx); // save caller save +__ push(rdx); // save caller save if (thread != rax) { - leal(thread, Address(rsp, 3 * sizeof(int))); // address of return value +__ lea(thread, Address(rsp, 3 * sizeof(int))); // address of return value } else { - leal(thread, Address(rsp, 2 * sizeof(int))); // address of return value +__ lea(thread, Address(rsp, 2 * sizeof(int))); // address of return value } - pushl(thread); // and pass the address - pushl(ThreadLocalStorage::thread_index()); // the key - call(RuntimeAddress(CAST_FROM_FN_PTR(address, thr_getspecific))); - increment(rsp, 2 * wordSize); - popl(rdx); - popl(rcx); - if (thread != rax) popl(rax); - popl(thread); +__ push(thread); // and pass the address +__ push(ThreadLocalStorage::thread_index()); // the key +__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, thr_getspecific))); +__ increment(rsp, 2 * wordSize); +__ pop(rdx); +__ pop(rcx); + if (thread != rax) __ pop(rax); +__ pop(thread); + +} +#else +static void slow_call_thr_specific(MacroAssembler* _masm, Register thread) { + // slow call to of thr_getspecific + // int thr_getspecific(thread_key_t key, void **value); + // Consider using pthread_getspecific instead. + + if (thread != rax) { +__ push(rax); + } +__ push(0); // space for return value +__ push(rdi); +__ push(rsi); +__ lea(rsi, Address(rsp, 16)); // pass return value address +__ push(rdx); +__ push(rcx); +__ push(r8); +__ push(r9); +__ push(r10); + // XXX +__ mov(r10, rsp); +__ andptr(rsp, -16); +__ push(r10); +__ push(r11); + +__ movl(rdi, ThreadLocalStorage::thread_index()); +__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, thr_getspecific))); + +__ pop(r11); +__ pop(rsp); +__ pop(r10); +__ pop(r9); +__ pop(r8); +__ pop(rcx); +__ pop(rdx); +__ pop(rsi); +__ pop(rdi); +__ pop(thread); // load return value + if (thread != rax) { +__ pop(rax); + } +} +#endif //LP64 + +void MacroAssembler::get_thread(Register thread) { + + int segment = NOT_LP64(Assembler::GS_segment) LP64_ONLY(Assembler::FS_segment); + // Try to emit a Solaris-specific fast TSD/TLS accessor. + ThreadLocalStorage::pd_tlsAccessMode tlsMode = ThreadLocalStorage::pd_getTlsAccessMode (); + if (tlsMode == ThreadLocalStorage::pd_tlsAccessIndirect) { // T1 + // Use thread as a temporary: mov r, gs:[0]; mov r, [r+tlsOffset] + emit_byte (segment); + // ExternalAddress doesn't work because it can't take NULL + AddressLiteral null(0, relocInfo::none); + movptr (thread, null); + movptr(thread, Address(thread, ThreadLocalStorage::pd_getTlsOffset())) ; + return ; + } else + if (tlsMode == ThreadLocalStorage::pd_tlsAccessDirect) { // T2 + // mov r, gs:[tlsOffset] + emit_byte (segment); + AddressLiteral tls_off((address)ThreadLocalStorage::pd_getTlsOffset(), relocInfo::none); + movptr (thread, tls_off); + return ; + } + + slow_call_thr_specific(this, thread); + } diff --git a/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86_64.cpp b/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86_64.cpp deleted file mode 100644 index 2ccae8a683d..00000000000 --- a/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86_64.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2004-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. - * - */ - -#include "incls/_precompiled.incl" -#include "incls/_assembler_solaris_x86_64.cpp.incl" - -void MacroAssembler::int3() { - call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint))); -} - -void MacroAssembler::get_thread(Register thread) { - // Try to emit a Solaris-specific fast TSD/TLS accessor. - ThreadLocalStorage::pd_tlsAccessMode tlsMode = ThreadLocalStorage::pd_getTlsAccessMode(); - if (tlsMode == ThreadLocalStorage::pd_tlsAccessIndirect) { // T1 - // Use thread as a temporary: mov r, fs:[0]; mov r, [r+tlsOffset] - emit_byte(Assembler::FS_segment); - movq(thread, Address(NULL, relocInfo::none)); - movq(thread, Address(thread, ThreadLocalStorage::pd_getTlsOffset())); - return; - } else if (tlsMode == ThreadLocalStorage::pd_tlsAccessDirect) { // T2 - // mov r, fs:[tlsOffset] - emit_byte(Assembler::FS_segment); - ExternalAddress tls_off((address) ThreadLocalStorage::pd_getTlsOffset()); - movptr(thread, tls_off); - return; - } - - // slow call to of thr_getspecific - // int thr_getspecific(thread_key_t key, void **value); - // Consider using pthread_getspecific instead. - - if (thread != rax) { - pushq(rax); - } - pushq(0); // space for return value - pushq(rdi); - pushq(rsi); - leaq(rsi, Address(rsp, 16)); // pass return value address - pushq(rdx); - pushq(rcx); - pushq(r8); - pushq(r9); - pushq(r10); - // XXX - movq(r10, rsp); - andq(rsp, -16); - pushq(r10); - pushq(r11); - - movl(rdi, ThreadLocalStorage::thread_index()); - call(RuntimeAddress(CAST_FROM_FN_PTR(address, thr_getspecific))); - - popq(r11); - popq(rsp); - popq(r10); - popq(r9); - popq(r8); - popq(rcx); - popq(rdx); - popq(rsi); - popq(rdi); - popq(thread); // load return value - if (thread != rax) { - popq(rax); - } -} diff --git a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.ad b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.ad index 0409fb55d8b..549f7b04859 100644 --- a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.ad +++ b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.ad @@ -62,13 +62,13 @@ encode %{ enc_class solaris_breakpoint %{ MacroAssembler* masm = new MacroAssembler(&cbuf); // Really need to fix this - masm->pushl(rax); - masm->pushl(rcx); - masm->pushl(rdx); + masm->push(rax); + masm->push(rcx); + masm->push(rdx); masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint))); - masm->popl(rdx); - masm->popl(rcx); - masm->popl(rax); + masm->pop(rdx); + masm->pop(rcx); + masm->pop(rax); %} enc_class call_epilog %{ diff --git a/hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86_32.cpp b/hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86.cpp similarity index 78% rename from hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86_32.cpp rename to hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86.cpp index 5e91ce654f8..4d4642143e8 100644 --- a/hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86_32.cpp +++ b/hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86.cpp @@ -23,13 +23,14 @@ */ #include "incls/_precompiled.incl" -#include "incls/_assembler_windows_x86_32.cpp.incl" +#include "incls/_assembler_windows_x86.cpp.incl" void MacroAssembler::int3() { emit_byte(0xCC); } +#ifndef _LP64 // The current scheme to accelerate access to the thread // pointer is to store the current thread in the os_exception_wrapper // and reference the current thread from stubs and compiled code @@ -58,3 +59,40 @@ void MacroAssembler::get_thread(Register thread) { "Thread Pointer Offset has not been initialized"); movl(thread, Address(thread, ThreadLocalStorage::get_thread_ptr_offset())); } +#else +// call (Thread*)TlsGetValue(thread_index()); +void MacroAssembler::get_thread(Register thread) { + if (thread != rax) { + push(rax); + } + push(rdi); + push(rsi); + push(rdx); + push(rcx); + push(r8); + push(r9); + push(r10); + // XXX + mov(r10, rsp); + andq(rsp, -16); + push(r10); + push(r11); + + movl(c_rarg0, ThreadLocalStorage::thread_index()); + call(RuntimeAddress((address)TlsGetValue)); + + pop(r11); + pop(rsp); + pop(r10); + pop(r9); + pop(r8); + pop(rcx); + pop(rdx); + pop(rsi); + pop(rdi); + if (thread != rax) { + mov(thread, rax); + pop(rax); + } +} +#endif diff --git a/hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86_64.cpp b/hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86_64.cpp deleted file mode 100644 index 7ff190fb21b..00000000000 --- a/hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86_64.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2003-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. - * - */ - -#include "incls/_precompiled.incl" -#include "incls/_assembler_windows_x86_64.cpp.incl" - - -void MacroAssembler::int3() { - emit_byte(0xCC); -} - -// call (Thread*)TlsGetValue(thread_index()); -void MacroAssembler::get_thread(Register thread) { - if (thread != rax) { - pushq(rax); - } - pushq(rdi); - pushq(rsi); - pushq(rdx); - pushq(rcx); - pushq(r8); - pushq(r9); - pushq(r10); - // XXX - movq(r10, rsp); - andq(rsp, -16); - pushq(r10); - pushq(r11); - - movl(c_rarg0, ThreadLocalStorage::thread_index()); - call(RuntimeAddress((address)TlsGetValue)); - - popq(r11); - popq(rsp); - popq(r10); - popq(r9); - popq(r8); - popq(rcx); - popq(rdx); - popq(rsi); - popq(rdi); - if (thread != rax) { - movq(thread, rax); - popq(rax); - } -} diff --git a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp index a2504045915..ff8cdd6ff8f 100644 --- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp +++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp @@ -369,7 +369,7 @@ frame os::current_frame() { // apparently _asm not supported on windows amd64 typedef intptr_t* get_fp_func (); get_fp_func* func = CAST_TO_FN_PTR(get_fp_func*, - StubRoutines::amd64::get_previous_fp_entry()); + StubRoutines::x86::get_previous_fp_entry()); if (func == NULL) return frame(NULL, NULL, NULL); intptr_t* fp = (*func)(); #else diff --git a/hotspot/src/share/vm/c1/c1_FrameMap.cpp b/hotspot/src/share/vm/c1/c1_FrameMap.cpp index 31e29bed07f..465b6d133c4 100644 --- a/hotspot/src/share/vm/c1/c1_FrameMap.cpp +++ b/hotspot/src/share/vm/c1/c1_FrameMap.cpp @@ -278,7 +278,7 @@ ByteSize FrameMap::sp_offset_for_spill(const int index) const { ByteSize FrameMap::sp_offset_for_monitor_base(const int index) const { int end_of_spills = round_to(first_available_sp_in_frame + _reserved_argument_area_size, sizeof(double)) + _num_spills * spill_slot_size_in_bytes; - int offset = round_to(end_of_spills, HeapWordSize) + index * sizeof(BasicObjectLock); + int offset = (int) round_to(end_of_spills, HeapWordSize) + index * sizeof(BasicObjectLock); return in_ByteSize(offset); } diff --git a/hotspot/src/share/vm/c1/c1_LIR.cpp b/hotspot/src/share/vm/c1/c1_LIR.cpp index 7335abb0731..0c0f1eda623 100644 --- a/hotspot/src/share/vm/c1/c1_LIR.cpp +++ b/hotspot/src/share/vm/c1/c1_LIR.cpp @@ -37,7 +37,7 @@ Register LIR_OprDesc::as_register_hi() const { return FrameMap::cpu_rnr2reg(cpu_regnrHi()); } -#ifdef IA32 +#if defined(X86) XMMRegister LIR_OprDesc::as_xmm_float_reg() const { return FrameMap::nr2xmmreg(xmm_regnr()); @@ -48,7 +48,7 @@ XMMRegister LIR_OprDesc::as_xmm_double_reg() const { return FrameMap::nr2xmmreg(xmm_regnrLo()); } -#endif +#endif // X86 #ifdef SPARC @@ -81,7 +81,7 @@ LIR_Opr LIR_OprFact::value_type(ValueType* type) { case floatTag : return LIR_OprFact::floatConst(type->as_FloatConstant()->value()); case longTag : return LIR_OprFact::longConst(type->as_LongConstant()->value()); case doubleTag : return LIR_OprFact::doubleConst(type->as_DoubleConstant()->value()); - default: ShouldNotReachHere(); + default: ShouldNotReachHere(); return LIR_OprFact::intConst(-1); } } @@ -94,7 +94,7 @@ LIR_Opr LIR_OprFact::dummy_value_type(ValueType* type) { case floatTag: return LIR_OprFact::floatConst(0.0); case longTag: return LIR_OprFact::longConst(0); case doubleTag: return LIR_OprFact::doubleConst(0.0); - default: ShouldNotReachHere(); + default: ShouldNotReachHere(); return LIR_OprFact::intConst(-1); } return illegalOpr; } @@ -162,6 +162,7 @@ char LIR_OprDesc::type_char(BasicType t) { default: ShouldNotReachHere(); + return '?'; } } @@ -1374,7 +1375,7 @@ void LIR_OprDesc::print(outputStream* out) const { } else if (is_double_cpu()) { out->print(as_register_hi()->name()); out->print(as_register_lo()->name()); -#ifdef IA32 +#if defined(X86) } else if (is_single_xmm()) { out->print(as_xmm_float_reg()->name()); } else if (is_double_xmm()) { diff --git a/hotspot/src/share/vm/c1/c1_LIR.hpp b/hotspot/src/share/vm/c1/c1_LIR.hpp index 6612604ca66..15a095d443e 100644 --- a/hotspot/src/share/vm/c1/c1_LIR.hpp +++ b/hotspot/src/share/vm/c1/c1_LIR.hpp @@ -135,6 +135,13 @@ class LIR_Const: public LIR_OprPtr { return as_jint_hi(); } } + jlong as_jlong_bits() const { + if (type() == T_DOUBLE) { + return jlong_cast(_value.get_jdouble()); + } else { + return as_jlong(); + } + } virtual void print_value_on(outputStream* out) const PRODUCT_RETURN; @@ -302,6 +309,7 @@ class LIR_OprDesc: public CompilationResourceObj { default: ShouldNotReachHere(); + return single_size; } } @@ -417,12 +425,12 @@ class LIR_OprDesc: public CompilationResourceObj { return as_register(); } -#ifdef IA32 +#ifdef X86 XMMRegister as_xmm_float_reg() const; XMMRegister as_xmm_double_reg() const; // for compatibility with RInfo int fpu () const { return lo_reg_half(); } -#endif +#endif // X86 #ifdef SPARC FloatRegister as_float_reg () const; @@ -503,14 +511,14 @@ class LIR_Address: public LIR_OprPtr { , _type(type) , _disp(disp) { verify(); } -#ifdef IA32 +#ifdef X86 LIR_Address(LIR_Opr base, LIR_Opr index, Scale scale, int disp, BasicType type): _base(base) , _index(index) , _scale(scale) , _type(type) , _disp(disp) { verify(); } -#endif +#endif // X86 LIR_Opr base() const { return _base; } LIR_Opr index() const { return _index; } @@ -535,31 +543,93 @@ class LIR_OprFact: public AllStatic { static LIR_Opr illegalOpr; - static LIR_Opr single_cpu(int reg) { return (LIR_Opr)((reg << LIR_OprDesc::reg1_shift) | LIR_OprDesc::int_type | LIR_OprDesc::cpu_register | LIR_OprDesc::single_size); } - static LIR_Opr single_cpu_oop(int reg) { return (LIR_Opr)((reg << LIR_OprDesc::reg1_shift) | LIR_OprDesc::object_type | LIR_OprDesc::cpu_register | LIR_OprDesc::single_size); } - static LIR_Opr double_cpu(int reg1, int reg2) { return (LIR_Opr)((reg1 << LIR_OprDesc::reg1_shift) | (reg2 << LIR_OprDesc::reg2_shift) | LIR_OprDesc::long_type | LIR_OprDesc::cpu_register | LIR_OprDesc::double_size); } + static LIR_Opr single_cpu(int reg) { return (LIR_Opr)(intptr_t)((reg << LIR_OprDesc::reg1_shift) | LIR_OprDesc::int_type | LIR_OprDesc::cpu_register | LIR_OprDesc::single_size); } + static LIR_Opr single_cpu_oop(int reg) { return (LIR_Opr)(intptr_t)((reg << LIR_OprDesc::reg1_shift) | LIR_OprDesc::object_type | LIR_OprDesc::cpu_register | LIR_OprDesc::single_size); } + static LIR_Opr double_cpu(int reg1, int reg2) { + LP64_ONLY(assert(reg1 == reg2, "must be identical")); + return (LIR_Opr)(intptr_t)((reg1 << LIR_OprDesc::reg1_shift) | + (reg2 << LIR_OprDesc::reg2_shift) | + LIR_OprDesc::long_type | + LIR_OprDesc::cpu_register | + LIR_OprDesc::double_size); + } - static LIR_Opr single_fpu(int reg) { return (LIR_Opr)((reg << LIR_OprDesc::reg1_shift) | LIR_OprDesc::float_type | LIR_OprDesc::fpu_register | LIR_OprDesc::single_size); } + static LIR_Opr single_fpu(int reg) { return (LIR_Opr)(intptr_t)((reg << LIR_OprDesc::reg1_shift) | + LIR_OprDesc::float_type | + LIR_OprDesc::fpu_register | + LIR_OprDesc::single_size); } #ifdef SPARC - static LIR_Opr double_fpu(int reg1, int reg2) { return (LIR_Opr)((reg1 << LIR_OprDesc::reg1_shift) | (reg2 << LIR_OprDesc::reg2_shift) | LIR_OprDesc::double_type | LIR_OprDesc::fpu_register | LIR_OprDesc::double_size); } -#endif -#ifdef IA32 - static LIR_Opr double_fpu(int reg) { return (LIR_Opr)((reg << LIR_OprDesc::reg1_shift) | (reg << LIR_OprDesc::reg2_shift) | LIR_OprDesc::double_type | LIR_OprDesc::fpu_register | LIR_OprDesc::double_size); } - static LIR_Opr single_xmm(int reg) { return (LIR_Opr)((reg << LIR_OprDesc::reg1_shift) | LIR_OprDesc::float_type | LIR_OprDesc::fpu_register | LIR_OprDesc::single_size | LIR_OprDesc::is_xmm_mask); } - static LIR_Opr double_xmm(int reg) { return (LIR_Opr)((reg << LIR_OprDesc::reg1_shift) | (reg << LIR_OprDesc::reg2_shift) | LIR_OprDesc::double_type | LIR_OprDesc::fpu_register | LIR_OprDesc::double_size | LIR_OprDesc::is_xmm_mask); } + static LIR_Opr double_fpu(int reg1, int reg2) { return (LIR_Opr)(intptr_t)((reg1 << LIR_OprDesc::reg1_shift) | + (reg2 << LIR_OprDesc::reg2_shift) | + LIR_OprDesc::double_type | + LIR_OprDesc::fpu_register | + LIR_OprDesc::double_size); } #endif +#ifdef X86 + static LIR_Opr double_fpu(int reg) { return (LIR_Opr)(intptr_t)((reg << LIR_OprDesc::reg1_shift) | + (reg << LIR_OprDesc::reg2_shift) | + LIR_OprDesc::double_type | + LIR_OprDesc::fpu_register | + LIR_OprDesc::double_size); } + + static LIR_Opr single_xmm(int reg) { return (LIR_Opr)(intptr_t)((reg << LIR_OprDesc::reg1_shift) | + LIR_OprDesc::float_type | + LIR_OprDesc::fpu_register | + LIR_OprDesc::single_size | + LIR_OprDesc::is_xmm_mask); } + static LIR_Opr double_xmm(int reg) { return (LIR_Opr)(intptr_t)((reg << LIR_OprDesc::reg1_shift) | + (reg << LIR_OprDesc::reg2_shift) | + LIR_OprDesc::double_type | + LIR_OprDesc::fpu_register | + LIR_OprDesc::double_size | + LIR_OprDesc::is_xmm_mask); } +#endif // X86 static LIR_Opr virtual_register(int index, BasicType type) { LIR_Opr res; switch (type) { case T_OBJECT: // fall through - case T_ARRAY: res = (LIR_Opr)((index << LIR_OprDesc::data_shift) | LIR_OprDesc::object_type | LIR_OprDesc::cpu_register | LIR_OprDesc::single_size | LIR_OprDesc::virtual_mask); break; - case T_INT: res = (LIR_Opr)((index << LIR_OprDesc::data_shift) | LIR_OprDesc::int_type | LIR_OprDesc::cpu_register | LIR_OprDesc::single_size | LIR_OprDesc::virtual_mask); break; - case T_LONG: res = (LIR_Opr)((index << LIR_OprDesc::data_shift) | LIR_OprDesc::long_type | LIR_OprDesc::cpu_register | LIR_OprDesc::double_size | LIR_OprDesc::virtual_mask); break; - case T_FLOAT: res = (LIR_Opr)((index << LIR_OprDesc::data_shift) | LIR_OprDesc::float_type | LIR_OprDesc::fpu_register | LIR_OprDesc::single_size | LIR_OprDesc::virtual_mask); break; - case T_DOUBLE: res = (LIR_Opr)((index << LIR_OprDesc::data_shift) | LIR_OprDesc::double_type | LIR_OprDesc::fpu_register | LIR_OprDesc::double_size | LIR_OprDesc::virtual_mask); break; + case T_ARRAY: + res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + LIR_OprDesc::object_type | + LIR_OprDesc::cpu_register | + LIR_OprDesc::single_size | + LIR_OprDesc::virtual_mask); + break; + + case T_INT: + res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + LIR_OprDesc::int_type | + LIR_OprDesc::cpu_register | + LIR_OprDesc::single_size | + LIR_OprDesc::virtual_mask); + break; + + case T_LONG: + res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + LIR_OprDesc::long_type | + LIR_OprDesc::cpu_register | + LIR_OprDesc::double_size | + LIR_OprDesc::virtual_mask); + break; + + case T_FLOAT: + res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + LIR_OprDesc::float_type | + LIR_OprDesc::fpu_register | + LIR_OprDesc::single_size | + LIR_OprDesc::virtual_mask); + break; + + case + T_DOUBLE: res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + LIR_OprDesc::double_type | + LIR_OprDesc::fpu_register | + LIR_OprDesc::double_size | + LIR_OprDesc::virtual_mask); + break; default: ShouldNotReachHere(); res = illegalOpr; } @@ -572,8 +642,8 @@ class LIR_OprFact: public AllStatic { // old-style calculation; check if old and new method are equal LIR_OprDesc::OprType t = as_OprType(type); - LIR_Opr old_res = (LIR_Opr)((index << LIR_OprDesc::data_shift) | t | - ((type == T_FLOAT || type == T_DOUBLE) ? LIR_OprDesc::fpu_register : LIR_OprDesc::cpu_register) | + LIR_Opr old_res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | t | + ((type == T_FLOAT || type == T_DOUBLE) ? LIR_OprDesc::fpu_register : LIR_OprDesc::cpu_register) | LIR_OprDesc::size_for(type) | LIR_OprDesc::virtual_mask); assert(res == old_res, "old and new method not equal"); #endif @@ -588,11 +658,39 @@ class LIR_OprFact: public AllStatic { LIR_Opr res; switch (type) { case T_OBJECT: // fall through - case T_ARRAY: res = (LIR_Opr)((index << LIR_OprDesc::data_shift) | LIR_OprDesc::object_type | LIR_OprDesc::stack_value | LIR_OprDesc::single_size); break; - case T_INT: res = (LIR_Opr)((index << LIR_OprDesc::data_shift) | LIR_OprDesc::int_type | LIR_OprDesc::stack_value | LIR_OprDesc::single_size); break; - case T_LONG: res = (LIR_Opr)((index << LIR_OprDesc::data_shift) | LIR_OprDesc::long_type | LIR_OprDesc::stack_value | LIR_OprDesc::double_size); break; - case T_FLOAT: res = (LIR_Opr)((index << LIR_OprDesc::data_shift) | LIR_OprDesc::float_type | LIR_OprDesc::stack_value | LIR_OprDesc::single_size); break; - case T_DOUBLE: res = (LIR_Opr)((index << LIR_OprDesc::data_shift) | LIR_OprDesc::double_type | LIR_OprDesc::stack_value | LIR_OprDesc::double_size); break; + case T_ARRAY: + res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + LIR_OprDesc::object_type | + LIR_OprDesc::stack_value | + LIR_OprDesc::single_size); + break; + + case T_INT: + res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + LIR_OprDesc::int_type | + LIR_OprDesc::stack_value | + LIR_OprDesc::single_size); + break; + + case T_LONG: + res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + LIR_OprDesc::long_type | + LIR_OprDesc::stack_value | + LIR_OprDesc::double_size); + break; + + case T_FLOAT: + res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + LIR_OprDesc::float_type | + LIR_OprDesc::stack_value | + LIR_OprDesc::single_size); + break; + case T_DOUBLE: + res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + LIR_OprDesc::double_type | + LIR_OprDesc::stack_value | + LIR_OprDesc::double_size); + break; default: ShouldNotReachHere(); res = illegalOpr; } @@ -601,7 +699,10 @@ class LIR_OprFact: public AllStatic { assert(index >= 0, "index must be positive"); assert(index <= (max_jint >> LIR_OprDesc::data_shift), "index is too big"); - LIR_Opr old_res = (LIR_Opr)((index << LIR_OprDesc::data_shift) | LIR_OprDesc::stack_value | as_OprType(type) | LIR_OprDesc::size_for(type)); + LIR_Opr old_res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + LIR_OprDesc::stack_value | + as_OprType(type) | + LIR_OprDesc::size_for(type)); assert(res == old_res, "old and new method not equal"); #endif diff --git a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp index a8ed3da18a7..1a0dac769f8 100644 --- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp +++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp @@ -215,7 +215,7 @@ void LIR_Assembler::emit_block(BlockBegin* block) { #endif /* PRODUCT */ assert(block->lir() != NULL, "must have LIR"); - IA32_ONLY(assert(_masm->rsp_offset() == 0, "frame size should be fixed")); + X86_ONLY(assert(_masm->rsp_offset() == 0, "frame size should be fixed")); #ifndef PRODUCT if (CommentedAssembly) { @@ -227,7 +227,7 @@ void LIR_Assembler::emit_block(BlockBegin* block) { emit_lir_list(block->lir()); - IA32_ONLY(assert(_masm->rsp_offset() == 0, "frame size should be fixed")); + X86_ONLY(assert(_masm->rsp_offset() == 0, "frame size should be fixed")); } @@ -434,7 +434,7 @@ void LIR_Assembler::emit_call(LIR_OpJavaCall* op) { break; default: ShouldNotReachHere(); } -#if defined(IA32) && defined(TIERED) +#if defined(X86) && defined(TIERED) // C2 leave fpu stack dirty clean it if (UseSSE < 2) { int i; @@ -445,7 +445,7 @@ void LIR_Assembler::emit_call(LIR_OpJavaCall* op) { ffree(0); } } -#endif // IA32 && TIERED +#endif // X86 && TIERED } diff --git a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp index 3a64fe678fa..12adf1bac97 100644 --- a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp +++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp @@ -75,9 +75,9 @@ class LIR_Assembler: public CompilationResourceObj { void emit_stubs(CodeStubList* stub_list); // addresses - static Address as_Address(LIR_Address* addr); - static Address as_Address_lo(LIR_Address* addr); - static Address as_Address_hi(LIR_Address* addr); + Address as_Address(LIR_Address* addr); + Address as_Address_lo(LIR_Address* addr); + Address as_Address_hi(LIR_Address* addr); // debug information void add_call_info(int pc_offset, CodeEmitInfo* cinfo); diff --git a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp index eb90b3fd2bc..6fe213ed163 100644 --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp @@ -1717,7 +1717,7 @@ void LIRGenerator::do_UnsafeGetRaw(UnsafeGetRaw* x) { assert(log2_scale == 0, "must not have a scale"); addr = new LIR_Address(base_op, index_op->as_jint(), dst_type); } else { -#ifdef IA32 +#ifdef X86 addr = new LIR_Address(base_op, index_op, LIR_Address::Scale(log2_scale), 0, dst_type); #else if (index_op->is_illegal() || log2_scale == 0) { diff --git a/hotspot/src/share/vm/c1/c1_LinearScan.cpp b/hotspot/src/share/vm/c1/c1_LinearScan.cpp index 0d733b7e660..22246148dec 100644 --- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp +++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp @@ -80,7 +80,7 @@ LinearScan::LinearScan(IR* ir, LIRGenerator* gen, FrameMap* frame_map) , _scope_value_cache(0) // initialized later with correct length , _interval_in_loop(0, 0) // initialized later with correct length , _cached_blocks(*ir->linear_scan_order()) -#ifdef IA32 +#ifdef X86 , _fpu_stack_allocator(NULL) #endif { @@ -116,7 +116,7 @@ int LinearScan::reg_num(LIR_Opr opr) { return opr->cpu_regnr(); } else if (opr->is_double_cpu()) { return opr->cpu_regnrLo(); -#ifdef IA32 +#ifdef X86 } else if (opr->is_single_xmm()) { return opr->fpu_regnr() + pd_first_xmm_reg; } else if (opr->is_double_xmm()) { @@ -128,6 +128,7 @@ int LinearScan::reg_num(LIR_Opr opr) { return opr->fpu_regnrLo() + pd_first_fpu_reg; } else { ShouldNotReachHere(); + return -1; } } @@ -140,7 +141,7 @@ int LinearScan::reg_numHi(LIR_Opr opr) { return -1; } else if (opr->is_double_cpu()) { return opr->cpu_regnrHi(); -#ifdef IA32 +#ifdef X86 } else if (opr->is_single_xmm()) { return -1; } else if (opr->is_double_xmm()) { @@ -152,6 +153,7 @@ int LinearScan::reg_numHi(LIR_Opr opr) { return opr->fpu_regnrHi() + pd_first_fpu_reg; } else { ShouldNotReachHere(); + return -1; } } @@ -1063,7 +1065,7 @@ IntervalUseKind LinearScan::use_kind_of_input_operand(LIR_Op* op, LIR_Opr opr) { } -#ifdef IA32 +#ifdef X86 if (op->code() == lir_cmove) { // conditional moves can handle stack operands assert(op->result_opr()->is_register(), "result must always be in a register"); @@ -1128,7 +1130,7 @@ IntervalUseKind LinearScan::use_kind_of_input_operand(LIR_Op* op, LIR_Opr opr) { } } } -#endif // IA32 +#endif // X86 // all other operands require a register return mustHaveRegister; @@ -1261,7 +1263,7 @@ void LinearScan::build_intervals() { // virtual fpu operands. Otherwise no allocation for fpu registers is // perfomed and so the temp ranges would be useless if (has_fpu_registers()) { -#ifdef IA32 +#ifdef X86 if (UseSSE < 2) { #endif for (i = 0; i < FrameMap::nof_caller_save_fpu_regs; i++) { @@ -1270,7 +1272,7 @@ void LinearScan::build_intervals() { assert(reg_numHi(opr) == -1, "missing addition of range for hi-register"); caller_save_registers[num_caller_save_registers++] = reg_num(opr); } -#ifdef IA32 +#ifdef X86 } if (UseSSE > 0) { for (i = 0; i < FrameMap::nof_caller_save_xmm_regs; i++) { @@ -1299,8 +1301,8 @@ void LinearScan::build_intervals() { // Update intervals for registers live at the end of this block; BitMap live = block->live_out(); - int size = live.size(); - for (int number = live.get_next_one_offset(0, size); number < size; number = live.get_next_one_offset(number + 1, size)) { + int size = (int)live.size(); + for (int number = (int)live.get_next_one_offset(0, size); number < size; number = (int)live.get_next_one_offset(number + 1, size)) { assert(live.at(number), "should not stop here otherwise"); assert(number >= LIR_OprDesc::vreg_base, "fixed intervals must not be live on block bounds"); TRACE_LINEAR_SCAN(2, tty->print_cr("live in %d to %d", number, block_to + 2)); @@ -1654,7 +1656,7 @@ void LinearScan::resolve_collect_mappings(BlockBegin* from_block, BlockBegin* to const BitMap live_at_edge = to_block->live_in(); // visit all registers where the live_at_edge bit is set - for (int r = live_at_edge.get_next_one_offset(0, size); r < size; r = live_at_edge.get_next_one_offset(r + 1, size)) { + for (int r = (int)live_at_edge.get_next_one_offset(0, size); r < size; r = (int)live_at_edge.get_next_one_offset(r + 1, size)) { assert(r < num_regs, "live information set for not exisiting interval"); assert(from_block->live_out().at(r) && to_block->live_in().at(r), "interval not live at this edge"); @@ -1824,7 +1826,7 @@ void LinearScan::resolve_exception_entry(BlockBegin* block, MoveResolver &move_r // visit all registers where the live_in bit is set int size = live_set_size(); - for (int r = block->live_in().get_next_one_offset(0, size); r < size; r = block->live_in().get_next_one_offset(r + 1, size)) { + for (int r = (int)block->live_in().get_next_one_offset(0, size); r < size; r = (int)block->live_in().get_next_one_offset(r + 1, size)) { resolve_exception_entry(block, r, move_resolver); } @@ -1898,7 +1900,7 @@ void LinearScan::resolve_exception_edge(XHandler* handler, int throwing_op_id, M // visit all registers where the live_in bit is set BlockBegin* block = handler->entry_block(); int size = live_set_size(); - for (int r = block->live_in().get_next_one_offset(0, size); r < size; r = block->live_in().get_next_one_offset(r + 1, size)) { + for (int r = (int)block->live_in().get_next_one_offset(0, size); r < size; r = (int)block->live_in().get_next_one_offset(r + 1, size)) { resolve_exception_edge(handler, throwing_op_id, r, NULL, move_resolver); } @@ -2032,19 +2034,19 @@ LIR_Opr LinearScan::calc_operand_for_interval(const Interval* interval) { assert(assigned_reg % 2 == 0 && assigned_reg + 1 == assigned_regHi, "must be sequential and even"); } -#ifdef SPARC #ifdef _LP64 return LIR_OprFact::double_cpu(assigned_reg, assigned_reg); #else +#ifdef SPARC return LIR_OprFact::double_cpu(assigned_regHi, assigned_reg); -#endif #else return LIR_OprFact::double_cpu(assigned_reg, assigned_regHi); -#endif +#endif // SPARC +#endif // LP64 } case T_FLOAT: { -#ifdef IA32 +#ifdef X86 if (UseSSE >= 1) { assert(assigned_reg >= pd_first_xmm_reg && assigned_reg <= pd_last_xmm_reg, "no xmm register"); assert(interval->assigned_regHi() == any_reg, "must not have hi register"); @@ -2058,7 +2060,7 @@ LIR_Opr LinearScan::calc_operand_for_interval(const Interval* interval) { } case T_DOUBLE: { -#ifdef IA32 +#ifdef X86 if (UseSSE >= 2) { assert(assigned_reg >= pd_first_xmm_reg && assigned_reg <= pd_last_xmm_reg, "no xmm register"); assert(interval->assigned_regHi() == any_reg, "must not have hi register (double xmm values are stored in one register)"); @@ -2122,7 +2124,7 @@ LIR_Opr LinearScan::color_lir_opr(LIR_Opr opr, int op_id, LIR_OpVisitState::OprM LIR_Opr res = operand_for_interval(interval); -#ifdef IA32 +#ifdef X86 // new semantic for is_last_use: not only set on definite end of interval, // but also before hole // This may still miss some cases (e.g. for dead values), but it is not necessary that the @@ -2475,6 +2477,7 @@ int LinearScan::append_scope_value_for_constant(LIR_Opr opr, GrowableArrayappend(sv); return 1; -#ifdef IA32 +#ifdef X86 } else if (opr->is_single_xmm()) { VMReg rname = opr->as_xmm_float_reg()->as_VMReg(); LocationValue* sv = new LocationValue(Location::new_reg_loc(Location::normal, rname)); @@ -2525,7 +2528,7 @@ int LinearScan::append_scope_value_for_operand(LIR_Opr opr, GrowableArrayis_single_fpu()) { -#ifdef IA32 +#ifdef X86 // the exact location of fpu stack values is only known // during fpu stack allocation, so the stack allocator object // must be present @@ -2548,12 +2551,23 @@ int LinearScan::append_scope_value_for_operand(LIR_Opr opr, GrowableArrayis_double_stack()) { +#ifdef _LP64 + Location loc1; + Location::Type loc_type = opr->type() == T_LONG ? Location::lng : Location::dbl; + if (!frame_map()->locations_for_slot(opr->double_stack_ix(), loc_type, &loc1, NULL)) { + bailout("too large frame"); + } + // Does this reverse on x86 vs. sparc? + first = new LocationValue(loc1); + second = &_int_0_scope_value; +#else Location loc1, loc2; if (!frame_map()->locations_for_slot(opr->double_stack_ix(), Location::normal, &loc1, &loc2)) { bailout("too large frame"); } first = new LocationValue(loc1); second = new LocationValue(loc2); +#endif // _LP64 } else if (opr->is_double_cpu()) { #ifdef _LP64 @@ -2573,9 +2587,10 @@ int LinearScan::append_scope_value_for_operand(LIR_Opr opr, GrowableArrayis_double_xmm()) { assert(opr->fpu_regnrLo() == opr->fpu_regnrHi(), "assumed in calculation"); VMReg rname_first = opr->as_xmm_double_reg()->as_VMReg(); @@ -2589,13 +2604,13 @@ int LinearScan::append_scope_value_for_operand(LIR_Opr opr, GrowableArrayis_double_fpu()) { // On SPARC, fpu_regnrLo/fpu_regnrHi represents the two halves of - // the double as float registers in the native ordering. On IA32, + // the double as float registers in the native ordering. On X86, // fpu_regnrLo is a FPU stack slot whose VMReg represents // the low-order word of the double and fpu_regnrLo + 1 is the // name for the other half. *first and *second must represent the // least and most significant words, respectively. -#ifdef IA32 +#ifdef X86 // the exact location of fpu stack values is only known // during fpu stack allocation, so the stack allocator object // must be present @@ -2865,7 +2880,6 @@ void LinearScan::assign_reg_num(LIR_OpList* instructions, IntervalWalker* iw) { op->verify(); #endif -#ifndef _LP64 // remove useless moves if (op->code() == lir_move) { assert(op->as_Op1() != NULL, "move must be LIR_Op1"); @@ -2879,7 +2893,6 @@ void LinearScan::assign_reg_num(LIR_OpList* instructions, IntervalWalker* iw) { has_dead = true; } } -#endif } if (has_dead) { @@ -3192,7 +3205,7 @@ void LinearScan::verify_constants() { BitMap live_at_edge = block->live_in(); // visit all registers where the live_at_edge bit is set - for (int r = live_at_edge.get_next_one_offset(0, size); r < size; r = live_at_edge.get_next_one_offset(r + 1, size)) { + for (int r = (int)live_at_edge.get_next_one_offset(0, size); r < size; r = (int)live_at_edge.get_next_one_offset(r + 1, size)) { TRACE_LINEAR_SCAN(4, tty->print("checking interval %d of block B%d", r, block->block_id())); Value value = gen()->instruction_for_vreg(r); @@ -3438,7 +3451,7 @@ void RegisterVerifier::process_operations(LIR_List* ops, IntervalList* input_sta state_put(input_state, reg_num(FrameMap::caller_save_fpu_reg_at(j)), NULL); } -#ifdef IA32 +#ifdef X86 for (j = 0; j < FrameMap::nof_caller_save_xmm_regs; j++) { state_put(input_state, reg_num(FrameMap::caller_save_xmm_reg_at(j)), NULL); } @@ -4357,7 +4370,7 @@ void Interval::print(outputStream* out) const { opr = LIR_OprFact::single_cpu(assigned_reg()); } else if (assigned_reg() >= pd_first_fpu_reg && assigned_reg() <= pd_last_fpu_reg) { opr = LIR_OprFact::single_fpu(assigned_reg() - pd_first_fpu_reg); -#ifdef IA32 +#ifdef X86 } else if (assigned_reg() >= pd_first_xmm_reg && assigned_reg() <= pd_last_xmm_reg) { opr = LIR_OprFact::single_xmm(assigned_reg() - pd_first_xmm_reg); #endif @@ -5435,7 +5448,7 @@ void LinearScanWalker::alloc_locked_reg(Interval* cur) { } bool LinearScanWalker::no_allocation_possible(Interval* cur) { -#ifdef IA32 +#ifdef X86 // fast calculation of intervals that can never get a register because the // the next instruction is a call that blocks all registers // Note: this does not work if callee-saved registers are available (e.g. on Sparc) diff --git a/hotspot/src/share/vm/c1/c1_LinearScan.hpp b/hotspot/src/share/vm/c1/c1_LinearScan.hpp index bc187fa75d1..10487b07483 100644 --- a/hotspot/src/share/vm/c1/c1_LinearScan.hpp +++ b/hotspot/src/share/vm/c1/c1_LinearScan.hpp @@ -177,7 +177,7 @@ class LinearScan : public CompilationResourceObj { bool is_interval_in_loop(int interval, int loop) const { return _interval_in_loop.at(interval, loop); } // handling of fpu stack allocation (platform dependent, needed for debug information generation) -#ifdef IA32 +#ifdef X86 FpuStackAllocator* _fpu_stack_allocator; bool use_fpu_stack_allocation() const { return UseSSE < 2 && has_fpu_registers(); } #else diff --git a/hotspot/src/share/vm/c1/c1_Runtime1.cpp b/hotspot/src/share/vm/c1/c1_Runtime1.cpp index e7321ccc351..4a4765099e5 100644 --- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp +++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp @@ -336,21 +336,6 @@ JRT_ENTRY(void, Runtime1::new_multi_array(JavaThread* thread, klassOopDesc* klas assert(oop(klass)->is_klass(), "not a class"); assert(rank >= 1, "rank must be nonzero"); -#ifdef _LP64 -// In 64 bit mode, the sizes are stored in the top 32 bits -// of each 64 bit stack entry. -// dims is actually an intptr_t * because the arguments -// are pushed onto a 64 bit stack. -// We must create an array of jints to pass to multi_allocate. -// We reuse the current stack because it will be popped -// after this bytecode is completed. - if ( rank > 1 ) { - int index; - for ( index = 1; index < rank; index++ ) { // First size is ok - dims[index] = dims[index*2]; - } - } -#endif oop obj = arrayKlass::cast(klass)->multi_allocate(rank, dims, CHECK); thread->set_vm_result(obj); JRT_END diff --git a/hotspot/src/share/vm/code/relocInfo.hpp b/hotspot/src/share/vm/code/relocInfo.hpp index 8a2867dc00e..36006e82496 100644 --- a/hotspot/src/share/vm/code/relocInfo.hpp +++ b/hotspot/src/share/vm/code/relocInfo.hpp @@ -1200,11 +1200,13 @@ class section_word_Relocation : public internal_word_Relocation { class poll_Relocation : public Relocation { bool is_data() { return true; } relocInfo::relocType type() { return relocInfo::poll_type; } + void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest); }; class poll_return_Relocation : public Relocation { bool is_data() { return true; } relocInfo::relocType type() { return relocInfo::poll_return_type; } + void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest); }; diff --git a/hotspot/src/share/vm/includeDB_compiler1 b/hotspot/src/share/vm/includeDB_compiler1 index 3509507f10b..d3006b094a0 100644 --- a/hotspot/src/share/vm/includeDB_compiler1 +++ b/hotspot/src/share/vm/includeDB_compiler1 @@ -258,6 +258,7 @@ c1_LIRGenerator_.cpp ciArray.hpp c1_LIRGenerator_.cpp ciObjArrayKlass.hpp c1_LIRGenerator_.cpp ciTypeArrayKlass.hpp c1_LIRGenerator_.cpp sharedRuntime.hpp +c1_LIRGenerator_.cpp vmreg_.inline.hpp c1_LinearScan.cpp c1_CFGPrinter.hpp c1_LinearScan.cpp c1_Compilation.hpp @@ -281,7 +282,7 @@ c1_LinearScan_.cpp c1_LinearScan.hpp c1_LinearScan_.hpp generate_platform_dependent_include c1_MacroAssembler.hpp assembler.hpp -c1_MacroAssembler.hpp assembler_.inline.hpp +c1_MacroAssembler.hpp assembler_.inline.hpp c1_MacroAssembler_.cpp arrayOop.hpp c1_MacroAssembler_.cpp biasedLocking.hpp diff --git a/hotspot/src/share/vm/includeDB_compiler2 b/hotspot/src/share/vm/includeDB_compiler2 index 1d2cb6d8b15..07ae8a87096 100644 --- a/hotspot/src/share/vm/includeDB_compiler2 +++ b/hotspot/src/share/vm/includeDB_compiler2 @@ -26,7 +26,7 @@ ad_.cpp adGlobals_.hpp ad_.cpp ad_.hpp ad_.cpp allocation.inline.hpp ad_.cpp assembler.hpp -ad_.cpp assembler_.inline.hpp +ad_.cpp assembler_.inline.hpp ad_.cpp biasedLocking.hpp ad_.cpp cfgnode.hpp ad_.cpp collectedHeap.inline.hpp @@ -957,7 +957,7 @@ runtime.hpp vframe.hpp runtime_.cpp adGlobals_.hpp runtime_.cpp ad_.hpp runtime_.cpp assembler.hpp -runtime_.cpp assembler_.inline.hpp +runtime_.cpp assembler_.inline.hpp runtime_.cpp globalDefinitions.hpp runtime_.cpp interfaceSupport.hpp runtime_.cpp interpreter.hpp diff --git a/hotspot/src/share/vm/includeDB_core b/hotspot/src/share/vm/includeDB_core index b9b46dcaf2d..5b2045617d2 100644 --- a/hotspot/src/share/vm/includeDB_core +++ b/hotspot/src/share/vm/includeDB_core @@ -228,7 +228,7 @@ arrayOop.hpp universe.inline.hpp assembler.cpp assembler.hpp assembler.cpp assembler.inline.hpp -assembler.cpp assembler_.inline.hpp +assembler.cpp assembler_.inline.hpp assembler.cpp codeBuffer.hpp assembler.cpp icache.hpp assembler.cpp os.hpp @@ -248,29 +248,29 @@ assembler.inline.hpp codeBuffer.hpp assembler.inline.hpp disassembler.hpp assembler.inline.hpp threadLocalStorage.hpp -assembler_.cpp assembler_.inline.hpp -assembler_.cpp biasedLocking.hpp -assembler_.cpp cardTableModRefBS.hpp -assembler_.cpp collectedHeap.inline.hpp -assembler_.cpp interfaceSupport.hpp -assembler_.cpp interpreter.hpp -assembler_.cpp objectMonitor.hpp -assembler_.cpp os.hpp -assembler_.cpp resourceArea.hpp -assembler_.cpp sharedRuntime.hpp -assembler_.cpp stubRoutines.hpp +assembler_.cpp assembler_.inline.hpp +assembler_.cpp biasedLocking.hpp +assembler_.cpp cardTableModRefBS.hpp +assembler_.cpp collectedHeap.inline.hpp +assembler_.cpp interfaceSupport.hpp +assembler_.cpp interpreter.hpp +assembler_.cpp objectMonitor.hpp +assembler_.cpp os.hpp +assembler_.cpp resourceArea.hpp +assembler_.cpp sharedRuntime.hpp +assembler_.cpp stubRoutines.hpp -assembler_.hpp generate_platform_dependent_include +assembler_.hpp generate_platform_dependent_include -assembler_.inline.hpp assembler.inline.hpp -assembler_.inline.hpp codeBuffer.hpp -assembler_.inline.hpp codeCache.hpp -assembler_.inline.hpp handles.inline.hpp +assembler_.inline.hpp assembler.inline.hpp +assembler_.inline.hpp codeBuffer.hpp +assembler_.inline.hpp codeCache.hpp +assembler_.inline.hpp handles.inline.hpp -assembler_.cpp assembler.hpp -assembler_.cpp assembler_.inline.hpp -assembler_.cpp os.hpp -assembler_.cpp threadLocalStorage.hpp +assembler_.cpp assembler.hpp +assembler_.cpp assembler_.inline.hpp +assembler_.cpp os.hpp +assembler_.cpp threadLocalStorage.hpp atomic.cpp atomic.hpp atomic.cpp atomic_.inline.hpp @@ -1926,7 +1926,7 @@ hpi_.cpp os.hpp hpi_imported.h jni.h -icBuffer.cpp assembler_.inline.hpp +icBuffer.cpp assembler_.inline.hpp icBuffer.cpp collectedHeap.inline.hpp icBuffer.cpp compiledIC.hpp icBuffer.cpp icBuffer.hpp @@ -1947,7 +1947,7 @@ icBuffer.hpp bytecodes.hpp icBuffer.hpp stubs.hpp icBuffer_.cpp assembler.hpp -icBuffer_.cpp assembler_.inline.hpp +icBuffer_.cpp assembler_.inline.hpp icBuffer_.cpp bytecodes.hpp icBuffer_.cpp collectedHeap.inline.hpp icBuffer_.cpp icBuffer.hpp @@ -1962,7 +1962,7 @@ icache.cpp resourceArea.hpp icache.hpp allocation.hpp icache.hpp stubCodeGenerator.hpp -icache_.cpp assembler_.inline.hpp +icache_.cpp assembler_.inline.hpp icache_.cpp icache.hpp icache_.hpp generate_platform_dependent_include @@ -2095,7 +2095,7 @@ interp_masm_.cpp sharedRuntime.hpp interp_masm_.cpp synchronizer.hpp interp_masm_.cpp thread_.inline.hpp -interp_masm_.hpp assembler_.inline.hpp +interp_masm_.hpp assembler_.inline.hpp interp_masm_.hpp invocationCounter.hpp interpreter.cpp allocation.inline.hpp @@ -2402,7 +2402,7 @@ jniFastGetField.cpp jniFastGetField.hpp jniFastGetField.hpp allocation.hpp jniFastGetField.hpp jvm_misc.hpp -jniFastGetField_.cpp assembler_.inline.hpp +jniFastGetField_.cpp assembler_.inline.hpp jniFastGetField_.cpp jniFastGetField.hpp jniFastGetField_.cpp jvm_misc.hpp jniFastGetField_.cpp resourceArea.hpp @@ -2905,7 +2905,7 @@ mutex_.inline.hpp interfaceSupport.hpp mutex_.inline.hpp os_.inline.hpp mutex_.inline.hpp thread_.inline.hpp -nativeInst_.cpp assembler_.inline.hpp +nativeInst_.cpp assembler_.inline.hpp nativeInst_.cpp handles.hpp nativeInst_.cpp nativeInst_.hpp nativeInst_.cpp oop.hpp @@ -3174,7 +3174,7 @@ os.hpp top.hpp os_.cpp allocation.inline.hpp os_.cpp arguments.hpp -os_.cpp assembler_.inline.hpp +os_.cpp assembler_.inline.hpp os_.cpp classLoader.hpp os_.cpp events.hpp os_.cpp extendedPC.hpp @@ -3208,7 +3208,7 @@ os_.hpp generate_platform_dependent_include os_.cpp allocation.inline.hpp os_.cpp arguments.hpp -os_.cpp assembler_.inline.hpp +os_.cpp assembler_.inline.hpp os_.cpp attachListener.hpp os_.cpp classLoader.hpp os_.cpp compileBroker.hpp @@ -3267,7 +3267,7 @@ osThread.hpp javaFrameAnchor.hpp osThread.hpp objectMonitor.hpp osThread.hpp top.hpp -osThread_.cpp assembler_.inline.hpp +osThread_.cpp assembler_.inline.hpp osThread_.cpp atomic.hpp osThread_.cpp handles.inline.hpp osThread_.cpp mutexLocker.hpp @@ -3480,7 +3480,7 @@ register_definitions_.cpp interp_masm_.hpp register_definitions_.cpp register.hpp register_definitions_.cpp register_.hpp -relocInfo.cpp assembler_.inline.hpp +relocInfo.cpp assembler_.inline.hpp relocInfo.cpp compiledIC.hpp relocInfo.cpp copy.hpp relocInfo.cpp nativeInst_.hpp @@ -3493,7 +3493,7 @@ relocInfo.hpp allocation.hpp relocInfo.hpp top.hpp relocInfo_.cpp assembler.inline.hpp -relocInfo_.cpp assembler_.inline.hpp +relocInfo_.cpp assembler_.inline.hpp relocInfo_.cpp nativeInst_.hpp relocInfo_.cpp oop.inline.hpp relocInfo_.cpp relocInfo.hpp @@ -3676,7 +3676,7 @@ sharedRuntime.hpp resourceArea.hpp sharedRuntime.hpp threadLocalStorage.hpp sharedRuntime_.cpp assembler.hpp -sharedRuntime_.cpp assembler_.inline.hpp +sharedRuntime_.cpp assembler_.inline.hpp sharedRuntime_.cpp compiledICHolderOop.hpp sharedRuntime_.cpp debugInfoRec.hpp sharedRuntime_.cpp icBuffer.hpp @@ -3819,7 +3819,7 @@ statSampler.cpp vm_version_.hpp statSampler.hpp perfData.hpp statSampler.hpp task.hpp -stubCodeGenerator.cpp assembler_.inline.hpp +stubCodeGenerator.cpp assembler_.inline.hpp stubCodeGenerator.cpp disassembler.hpp stubCodeGenerator.cpp forte.hpp stubCodeGenerator.cpp oop.inline.hpp @@ -3830,7 +3830,7 @@ stubCodeGenerator.hpp allocation.hpp stubCodeGenerator.hpp assembler.hpp stubGenerator_.cpp assembler.hpp -stubGenerator_.cpp assembler_.inline.hpp +stubGenerator_.cpp assembler_.inline.hpp stubGenerator_.cpp frame.inline.hpp stubGenerator_.cpp handles.inline.hpp stubGenerator_.cpp instanceOop.hpp @@ -4562,7 +4562,7 @@ vm_version.cpp vm_version_.hpp vm_version.hpp allocation.hpp vm_version.hpp ostream.hpp -vm_version_.cpp assembler_.inline.hpp +vm_version_.cpp assembler_.inline.hpp vm_version_.cpp java.hpp vm_version_.cpp os_.inline.hpp vm_version_.cpp resourceArea.hpp @@ -4603,7 +4603,7 @@ vtableStubs.cpp vtune.hpp vtableStubs.hpp allocation.hpp vtableStubs_.cpp assembler.hpp -vtableStubs_.cpp assembler_.inline.hpp +vtableStubs_.cpp assembler_.inline.hpp vtableStubs_.cpp instanceKlass.hpp vtableStubs_.cpp interp_masm_.hpp vtableStubs_.cpp klassVtable.hpp diff --git a/hotspot/src/share/vm/includeDB_features b/hotspot/src/share/vm/includeDB_features index 88f4c293643..6effcca57ae 100644 --- a/hotspot/src/share/vm/includeDB_features +++ b/hotspot/src/share/vm/includeDB_features @@ -57,7 +57,7 @@ dump.cpp systemDictionary.hpp dump.cpp vmThread.hpp dump.cpp vm_operations.hpp -dump_.cpp assembler_.inline.hpp +dump_.cpp assembler_.inline.hpp dump_.cpp compactingPermGenGen.hpp forte.cpp collectedHeap.inline.hpp diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index cb38e15d017..0c0dee1308d 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -583,7 +583,7 @@ static inline uint64_t cast_uint64_t(size_t x) /***********************************/ \ \ static_field(StubRoutines, _call_stub_return_address, address) \ - IA32_ONLY(static_field(StubRoutines::i486,_call_stub_compiled_return, address)) \ + IA32_ONLY(static_field(StubRoutines::x86,_call_stub_compiled_return, address)) \ \ /***************************************/ \ /* PcDesc and other compiled code info */ \ @@ -1107,7 +1107,7 @@ static inline uint64_t cast_uint64_t(size_t x) \ declare_toplevel_type(StubQueue) \ declare_toplevel_type(StubRoutines) \ - IA32_ONLY(declare_toplevel_type(StubRoutines::i486)) \ + IA32_ONLY(declare_toplevel_type(StubRoutines::x86)) \ declare_toplevel_type(Stub) \ declare_type(InterpreterCodelet, Stub) \ \ diff --git a/hotspot/src/share/vm/utilities/macros.hpp b/hotspot/src/share/vm/utilities/macros.hpp index 2f495efac67..7d7bc654a3b 100644 --- a/hotspot/src/share/vm/utilities/macros.hpp +++ b/hotspot/src/share/vm/utilities/macros.hpp @@ -144,6 +144,14 @@ #define NOT_WINDOWS(code) code #endif +#if defined(IA32) || defined(AMD64) +#define X86 +#define X86_ONLY(code) code +#else +#undef X86 +#define X86_ONLY(code) +#endif + #ifdef IA32 #define IA32_ONLY(code) code #define NOT_IA32(code) From 37306315b207383ad39b9ee374ecb216b9ecb50e Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Wed, 27 Aug 2008 09:15:46 -0700 Subject: [PATCH 61/95] 6736417: Fastdebug C2 crashes in StoreBNode::Ideal The result of step_through_mergemem() and remove_dead_region() is not checked in some cases. Reviewed-by: never --- hotspot/src/share/vm/opto/callnode.cpp | 4 +--- hotspot/src/share/vm/opto/connode.cpp | 2 ++ hotspot/src/share/vm/opto/divnode.cpp | 16 ++++++++++++++-- hotspot/src/share/vm/opto/memnode.cpp | 8 ++++++-- hotspot/src/share/vm/opto/node.cpp | 11 +++++------ hotspot/src/share/vm/opto/phaseX.cpp | 4 ++++ 6 files changed, 32 insertions(+), 13 deletions(-) diff --git a/hotspot/src/share/vm/opto/callnode.cpp b/hotspot/src/share/vm/opto/callnode.cpp index 389db14fed5..29b5f9990f6 100644 --- a/hotspot/src/share/vm/opto/callnode.cpp +++ b/hotspot/src/share/vm/opto/callnode.cpp @@ -829,9 +829,7 @@ SafePointNode* SafePointNode::next_exception() const { //------------------------------Ideal------------------------------------------ // Skip over any collapsed Regions Node *SafePointNode::Ideal(PhaseGVN *phase, bool can_reshape) { - if (remove_dead_region(phase, can_reshape)) return this; - - return NULL; + return remove_dead_region(phase, can_reshape) ? this : NULL; } //------------------------------Identity--------------------------------------- diff --git a/hotspot/src/share/vm/opto/connode.cpp b/hotspot/src/share/vm/opto/connode.cpp index 8b441c99439..ceebd76a6bb 100644 --- a/hotspot/src/share/vm/opto/connode.cpp +++ b/hotspot/src/share/vm/opto/connode.cpp @@ -101,6 +101,8 @@ matter ever). // Move constants to the right. Node *CMoveNode::Ideal(PhaseGVN *phase, bool can_reshape) { if( in(0) && remove_dead_region(phase, can_reshape) ) return this; + // Don't bother trying to transform a dead node + if( in(0) && in(0)->is_top() ) return NULL; assert( !phase->eqv(in(Condition), this) && !phase->eqv(in(IfFalse), this) && !phase->eqv(in(IfTrue), this), "dead loop in CMoveNode::Ideal" ); diff --git a/hotspot/src/share/vm/opto/divnode.cpp b/hotspot/src/share/vm/opto/divnode.cpp index 591456f788a..c1c2b5df442 100644 --- a/hotspot/src/share/vm/opto/divnode.cpp +++ b/hotspot/src/share/vm/opto/divnode.cpp @@ -402,6 +402,8 @@ Node *DivINode::Identity( PhaseTransform *phase ) { // Divides can be changed to multiplies and/or shifts Node *DivINode::Ideal(PhaseGVN *phase, bool can_reshape) { if (in(0) && remove_dead_region(phase, can_reshape)) return this; + // Don't bother trying to transform a dead node + if( in(0) && in(0)->is_top() ) return NULL; const Type *t = phase->type( in(2) ); if( t == TypeInt::ONE ) // Identity? @@ -499,6 +501,8 @@ Node *DivLNode::Identity( PhaseTransform *phase ) { // Dividing by a power of 2 is a shift. Node *DivLNode::Ideal( PhaseGVN *phase, bool can_reshape) { if (in(0) && remove_dead_region(phase, can_reshape)) return this; + // Don't bother trying to transform a dead node + if( in(0) && in(0)->is_top() ) return NULL; const Type *t = phase->type( in(2) ); if( t == TypeLong::ONE ) // Identity? @@ -640,6 +644,8 @@ Node *DivFNode::Identity( PhaseTransform *phase ) { //------------------------------Idealize--------------------------------------- Node *DivFNode::Ideal(PhaseGVN *phase, bool can_reshape) { if (in(0) && remove_dead_region(phase, can_reshape)) return this; + // Don't bother trying to transform a dead node + if( in(0) && in(0)->is_top() ) return NULL; const Type *t2 = phase->type( in(2) ); if( t2 == TypeF::ONE ) // Identity? @@ -725,6 +731,8 @@ Node *DivDNode::Identity( PhaseTransform *phase ) { //------------------------------Idealize--------------------------------------- Node *DivDNode::Ideal(PhaseGVN *phase, bool can_reshape) { if (in(0) && remove_dead_region(phase, can_reshape)) return this; + // Don't bother trying to transform a dead node + if( in(0) && in(0)->is_top() ) return NULL; const Type *t2 = phase->type( in(2) ); if( t2 == TypeD::ONE ) // Identity? @@ -760,7 +768,9 @@ Node *DivDNode::Ideal(PhaseGVN *phase, bool can_reshape) { //------------------------------Idealize--------------------------------------- Node *ModINode::Ideal(PhaseGVN *phase, bool can_reshape) { // Check for dead control input - if( remove_dead_region(phase, can_reshape) ) return this; + if( in(0) && remove_dead_region(phase, can_reshape) ) return this; + // Don't bother trying to transform a dead node + if( in(0) && in(0)->is_top() ) return NULL; // Get the modulus const Type *t = phase->type( in(2) ); @@ -929,7 +939,9 @@ const Type *ModINode::Value( PhaseTransform *phase ) const { //------------------------------Idealize--------------------------------------- Node *ModLNode::Ideal(PhaseGVN *phase, bool can_reshape) { // Check for dead control input - if( remove_dead_region(phase, can_reshape) ) return this; + if( in(0) && remove_dead_region(phase, can_reshape) ) return this; + // Don't bother trying to transform a dead node + if( in(0) && in(0)->is_top() ) return NULL; // Get the modulus const Type *t = phase->type( in(2) ); diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp index dd9530885e9..56f7ef736c9 100644 --- a/hotspot/src/share/vm/opto/memnode.cpp +++ b/hotspot/src/share/vm/opto/memnode.cpp @@ -214,6 +214,9 @@ Node *MemNode::Ideal_common(PhaseGVN *phase, bool can_reshape) { Node *ctl = in(MemNode::Control); if (ctl && remove_dead_region(phase, can_reshape)) return this; + ctl = in(MemNode::Control); + // Don't bother trying to transform a dead node + if( ctl && ctl->is_top() ) return NodeSentinel; // Ignore if memory is dead, or self-loop Node *mem = in(MemNode::Memory); @@ -244,6 +247,7 @@ Node *MemNode::Ideal_common(PhaseGVN *phase, bool can_reshape) { if (mem != old_mem) { set_req(MemNode::Memory, mem); + if (phase->type( mem ) == Type::TOP) return NodeSentinel; return this; } @@ -1316,6 +1320,7 @@ Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) { Node* opt_mem = MemNode::optimize_memory_chain(mem, addr_t, phase); if (opt_mem != mem) { set_req(MemNode::Memory, opt_mem); + if (phase->type( opt_mem ) == Type::TOP) return NULL; return this; } const TypeOopPtr *t_oop = addr_t->isa_oopptr(); @@ -2447,8 +2452,7 @@ MemBarNode* MemBarNode::make(Compile* C, int opcode, int atp, Node* pn) { // Return a node which is more "ideal" than the current node. Strip out // control copies Node *MemBarNode::Ideal(PhaseGVN *phase, bool can_reshape) { - if (remove_dead_region(phase, can_reshape)) return this; - return NULL; + return remove_dead_region(phase, can_reshape) ? this : NULL; } //------------------------------Value------------------------------------------ diff --git a/hotspot/src/share/vm/opto/node.cpp b/hotspot/src/share/vm/opto/node.cpp index df3e56c2dc7..9130403ed9d 100644 --- a/hotspot/src/share/vm/opto/node.cpp +++ b/hotspot/src/share/vm/opto/node.cpp @@ -1166,16 +1166,15 @@ bool Node::dominates(Node* sub, Node_List &nlist) { // using it dead as well. This will happen normally via the usual IterGVN // worklist but this call is more efficient. Do not update use-def info // inside the dead region, just at the borders. -static bool kill_dead_code( Node *dead, PhaseIterGVN *igvn ) { +static void kill_dead_code( Node *dead, PhaseIterGVN *igvn ) { // Con's are a popular node to re-hit in the hash table again. - if( dead->is_Con() ) return false; + if( dead->is_Con() ) return; // Can't put ResourceMark here since igvn->_worklist uses the same arena // for verify pass with +VerifyOpto and we add/remove elements in it here. Node_List nstack(Thread::current()->resource_area()); Node *top = igvn->C->top(); - bool progress = false; nstack.push(dead); while (nstack.size() > 0) { @@ -1214,7 +1213,6 @@ static bool kill_dead_code( Node *dead, PhaseIterGVN *igvn ) { for (uint i=0; i < dead->req(); i++) { Node *n = dead->in(i); // Get input to dead guy if (n != NULL && !n->is_top()) { // Input is valid? - progress = true; dead->set_req(i, top); // Smash input away if (n->outcnt() == 0) { // Input also goes dead? if (!n->is_Con()) @@ -1233,7 +1231,7 @@ static bool kill_dead_code( Node *dead, PhaseIterGVN *igvn ) { } } // (dead->outcnt() == 0) } // while (nstack.size() > 0) for outputs - return progress; + return; } //------------------------------remove_dead_region----------------------------- @@ -1243,7 +1241,8 @@ bool Node::remove_dead_region(PhaseGVN *phase, bool can_reshape) { // Lost control into this guy? I.e., it became unreachable? // Aggressively kill all unreachable code. if (can_reshape && n->is_top()) { - return kill_dead_code(this, phase->is_IterGVN()); + kill_dead_code(this, phase->is_IterGVN()); + return false; // Node is dead. } if( n->is_Region() && n->as_Region()->is_copy() ) { diff --git a/hotspot/src/share/vm/opto/phaseX.cpp b/hotspot/src/share/vm/opto/phaseX.cpp index 45690469d92..484629a90ce 100644 --- a/hotspot/src/share/vm/opto/phaseX.cpp +++ b/hotspot/src/share/vm/opto/phaseX.cpp @@ -986,7 +986,9 @@ Node *PhaseIterGVN::transform_old( Node *n ) { // Apply the Ideal call in a loop until it no longer applies Node *k = n; DEBUG_ONLY(dead_loop_check(k);) + DEBUG_ONLY(bool is_new = (k->outcnt() == 0);) Node *i = k->Ideal(this, /*can_reshape=*/true); + assert(i != k || is_new || i->outcnt() > 0, "don't return dead nodes"); #ifndef PRODUCT if( VerifyIterativeGVN ) verify_step(k); @@ -1024,7 +1026,9 @@ Node *PhaseIterGVN::transform_old( Node *n ) { } DEBUG_ONLY(dead_loop_check(k);) // Try idealizing again + DEBUG_ONLY(is_new = (k->outcnt() == 0);) i = k->Ideal(this, /*can_reshape=*/true); + assert(i != k || is_new || i->outcnt() > 0, "don't return dead nodes"); #ifndef PRODUCT if( VerifyIterativeGVN ) verify_step(k); From 3c4879eb9af8b4b9db3b52c08c1de8fcd48839c3 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Wed, 27 Aug 2008 14:47:32 -0700 Subject: [PATCH 62/95] 6741738: TypePtr::add_offset() set incorrect offset when the add overflows Set offset to OffsetBot when the add overflows in TypePtr::add_offset() Reviewed-by: jrose, never --- hotspot/src/share/vm/opto/addnode.cpp | 6 +-- hotspot/src/share/vm/opto/escape.cpp | 2 +- hotspot/src/share/vm/opto/macro.cpp | 4 +- hotspot/src/share/vm/opto/type.cpp | 48 +++++++++++----------- hotspot/src/share/vm/opto/type.hpp | 14 +++---- hotspot/test/compiler/6741738/Tester.java | 50 +++++++++++++++++++++++ 6 files changed, 84 insertions(+), 40 deletions(-) create mode 100644 hotspot/test/compiler/6741738/Tester.java diff --git a/hotspot/src/share/vm/opto/addnode.cpp b/hotspot/src/share/vm/opto/addnode.cpp index f581f92493f..066ec6d7152 100644 --- a/hotspot/src/share/vm/opto/addnode.cpp +++ b/hotspot/src/share/vm/opto/addnode.cpp @@ -573,8 +573,6 @@ const Type *AddPNode::bottom_type() const { intptr_t txoffset = Type::OffsetBot; if (tx->is_con()) { // Left input is an add of a constant? txoffset = tx->get_con(); - if (txoffset != (int)txoffset) - txoffset = Type::OffsetBot; // oops: add_offset will choke on it } return tp->add_offset(txoffset); } @@ -595,8 +593,6 @@ const Type *AddPNode::Value( PhaseTransform *phase ) const { intptr_t p2offset = Type::OffsetBot; if (p2->is_con()) { // Left input is an add of a constant? p2offset = p2->get_con(); - if (p2offset != (int)p2offset) - p2offset = Type::OffsetBot; // oops: add_offset will choke on it } return p1->add_offset(p2offset); } @@ -675,7 +671,7 @@ const Type *AddPNode::mach_bottom_type( const MachNode* n) { // Check for any interesting operand info. // In particular, check for both memory and non-memory operands. // %%%%% Clean this up: use xadd_offset - int con = opnd->constant(); + intptr_t con = opnd->constant(); if ( con == TypePtr::OffsetBot ) goto bottom_out; offset += con; con = opnd->constant_disp(); diff --git a/hotspot/src/share/vm/opto/escape.cpp b/hotspot/src/share/vm/opto/escape.cpp index ef146637806..956306eb1ec 100644 --- a/hotspot/src/share/vm/opto/escape.cpp +++ b/hotspot/src/share/vm/opto/escape.cpp @@ -501,7 +501,7 @@ bool ConnectionGraph::split_AddP(Node *addp, Node *base, PhaseGVN *igvn) { // compute an appropriate address type (cases #3 and #5). assert(igvn->type(addp) == TypeRawPtr::NOTNULL, "must be raw pointer"); assert(addp->in(AddPNode::Address)->is_Proj(), "base of raw address must be result projection from allocation"); - int offs = (int)igvn->find_intptr_t_con(addp->in(AddPNode::Offset), Type::OffsetBot); + intptr_t offs = (int)igvn->find_intptr_t_con(addp->in(AddPNode::Offset), Type::OffsetBot); assert(offs != Type::OffsetBot, "offset must be a constant"); t = base_t->add_offset(offs)->is_oopptr(); } diff --git a/hotspot/src/share/vm/opto/macro.cpp b/hotspot/src/share/vm/opto/macro.cpp index c496c8fd98a..f8aea8e36aa 100644 --- a/hotspot/src/share/vm/opto/macro.cpp +++ b/hotspot/src/share/vm/opto/macro.cpp @@ -594,7 +594,7 @@ bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray nonstatic_field_at(j); @@ -602,7 +602,7 @@ bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray type(); basic_elem_type = field->layout_type(); } else { - offset = array_base + j * element_size; + offset = array_base + j * (intptr_t)element_size; } const Type *field_type; diff --git a/hotspot/src/share/vm/opto/type.cpp b/hotspot/src/share/vm/opto/type.cpp index e850d018e8d..243b44c4263 100644 --- a/hotspot/src/share/vm/opto/type.cpp +++ b/hotspot/src/share/vm/opto/type.cpp @@ -1956,14 +1956,25 @@ const Type *TypePtr::xdual() const { return new TypePtr( AnyPtr, dual_ptr(), dual_offset() ); } +//------------------------------xadd_offset------------------------------------ +int TypePtr::xadd_offset( intptr_t offset ) const { + // Adding to 'TOP' offset? Return 'TOP'! + if( _offset == OffsetTop || offset == OffsetTop ) return OffsetTop; + // Adding to 'BOTTOM' offset? Return 'BOTTOM'! + if( _offset == OffsetBot || offset == OffsetBot ) return OffsetBot; + // Addition overflows or "accidentally" equals to OffsetTop? Return 'BOTTOM'! + offset += (intptr_t)_offset; + if (offset != (int)offset || offset == OffsetTop) return OffsetBot; + + // assert( _offset >= 0 && _offset+offset >= 0, "" ); + // It is possible to construct a negative offset during PhaseCCP + + return (int)offset; // Sum valid offsets +} + //------------------------------add_offset------------------------------------- -const TypePtr *TypePtr::add_offset( int offset ) const { - if( offset == 0 ) return this; // No change - if( _offset == OffsetBot ) return this; - if( offset == OffsetBot ) offset = OffsetBot; - else if( _offset == OffsetTop || offset == OffsetTop ) offset = OffsetTop; - else offset += _offset; - return make( AnyPtr, _ptr, offset ); +const TypePtr *TypePtr::add_offset( intptr_t offset ) const { + return make( AnyPtr, _ptr, xadd_offset(offset) ); } //------------------------------eq--------------------------------------------- @@ -2096,7 +2107,7 @@ const Type *TypeRawPtr::xdual() const { } //------------------------------add_offset------------------------------------- -const TypePtr *TypeRawPtr::add_offset( int offset ) const { +const TypePtr *TypeRawPtr::add_offset( intptr_t offset ) const { if( offset == OffsetTop ) return BOTTOM; // Undefined offset-> undefined pointer if( offset == OffsetBot ) return BOTTOM; // Unknown offset-> unknown pointer if( offset == 0 ) return this; // No change @@ -2545,21 +2556,8 @@ bool TypeOopPtr::singleton(void) const { return (_offset == 0) && !below_centerline(_ptr); } -//------------------------------xadd_offset------------------------------------ -int TypeOopPtr::xadd_offset( int offset ) const { - // Adding to 'TOP' offset? Return 'TOP'! - if( _offset == OffsetTop || offset == OffsetTop ) return OffsetTop; - // Adding to 'BOTTOM' offset? Return 'BOTTOM'! - if( _offset == OffsetBot || offset == OffsetBot ) return OffsetBot; - - // assert( _offset >= 0 && _offset+offset >= 0, "" ); - // It is possible to construct a negative offset during PhaseCCP - - return _offset+offset; // Sum valid offsets -} - //------------------------------add_offset------------------------------------- -const TypePtr *TypeOopPtr::add_offset( int offset ) const { +const TypePtr *TypeOopPtr::add_offset( intptr_t offset ) const { return make( _ptr, xadd_offset(offset) ); } @@ -3076,7 +3074,7 @@ void TypeInstPtr::dump2( Dict &d, uint depth, outputStream *st ) const { #endif //------------------------------add_offset------------------------------------- -const TypePtr *TypeInstPtr::add_offset( int offset ) const { +const TypePtr *TypeInstPtr::add_offset( intptr_t offset ) const { return make( _ptr, klass(), klass_is_exact(), const_oop(), xadd_offset(offset), _instance_id ); } @@ -3427,7 +3425,7 @@ bool TypeAryPtr::empty(void) const { } //------------------------------add_offset------------------------------------- -const TypePtr *TypeAryPtr::add_offset( int offset ) const { +const TypePtr *TypeAryPtr::add_offset( intptr_t offset ) const { return make( _ptr, _const_oop, _ary, _klass, _klass_is_exact, xadd_offset(offset), _instance_id ); } @@ -3654,7 +3652,7 @@ ciKlass* TypeAryPtr::klass() const { //------------------------------add_offset------------------------------------- // Access internals of klass object -const TypePtr *TypeKlassPtr::add_offset( int offset ) const { +const TypePtr *TypeKlassPtr::add_offset( intptr_t offset ) const { return make( _ptr, klass(), xadd_offset(offset) ); } diff --git a/hotspot/src/share/vm/opto/type.hpp b/hotspot/src/share/vm/opto/type.hpp index 7dbcf096277..68366edca9b 100644 --- a/hotspot/src/share/vm/opto/type.hpp +++ b/hotspot/src/share/vm/opto/type.hpp @@ -581,7 +581,8 @@ public: virtual intptr_t get_con() const; - virtual const TypePtr *add_offset( int offset ) const; + int xadd_offset( intptr_t offset ) const; + virtual const TypePtr *add_offset( intptr_t offset ) const; virtual bool singleton(void) const; // TRUE if type is a singleton virtual bool empty(void) const; // TRUE if type is vacuous @@ -632,7 +633,7 @@ public: virtual intptr_t get_con() const; - virtual const TypePtr *add_offset( int offset ) const; + virtual const TypePtr *add_offset( intptr_t offset ) const; virtual const Type *xmeet( const Type *t ) const; virtual const Type *xdual() const; // Compute dual right now. @@ -659,7 +660,6 @@ public: }; protected: - int xadd_offset( int offset ) const; // Oop is NULL, unless this is a constant oop. ciObject* _const_oop; // Constant oop // If _klass is NULL, then so is _sig. This is an unloaded klass. @@ -724,7 +724,7 @@ public: // corresponding pointer to klass, for a given instance const TypeKlassPtr* as_klass_type() const; - virtual const TypePtr *add_offset( int offset ) const; + virtual const TypePtr *add_offset( intptr_t offset ) const; virtual const Type *xmeet( const Type *t ) const; virtual const Type *xdual() const; // Compute dual right now. @@ -793,7 +793,7 @@ class TypeInstPtr : public TypeOopPtr { virtual const TypeOopPtr *cast_to_instance_id(int instance_id) const; - virtual const TypePtr *add_offset( int offset ) const; + virtual const TypePtr *add_offset( intptr_t offset ) const; virtual const Type *xmeet( const Type *t ) const; virtual const TypeInstPtr *xmeet_unloaded( const TypeInstPtr *t ) const; @@ -842,7 +842,7 @@ public: virtual const TypeAryPtr* cast_to_size(const TypeInt* size) const; virtual bool empty(void) const; // TRUE if type is vacuous - virtual const TypePtr *add_offset( int offset ) const; + virtual const TypePtr *add_offset( intptr_t offset ) const; virtual const Type *xmeet( const Type *t ) const; virtual const Type *xdual() const; // Compute dual right now. @@ -896,7 +896,7 @@ public: // corresponding pointer to instance, for a given class const TypeOopPtr* as_instance_type() const; - virtual const TypePtr *add_offset( int offset ) const; + virtual const TypePtr *add_offset( intptr_t offset ) const; virtual const Type *xmeet( const Type *t ) const; virtual const Type *xdual() const; // Compute dual right now. diff --git a/hotspot/test/compiler/6741738/Tester.java b/hotspot/test/compiler/6741738/Tester.java new file mode 100644 index 00000000000..922f5e2f4e4 --- /dev/null +++ b/hotspot/test/compiler/6741738/Tester.java @@ -0,0 +1,50 @@ +/* + * 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 6741738 + * @summary TypePtr::add_offset() set incorrect offset when the add overflows + * @run main/othervm -Xcomp -XX:CompileOnly=Tester.foo Tester + */ + +public class Tester { + private String[] values; + private int count; + + String foo() { + int i = Integer.MAX_VALUE-1; + String s; + try { + s = values[i]; + } catch (Throwable e) { + s = ""; + } + return s; + } + + public static void main(String[] args) { + Tester t = new Tester(); + String s = t.foo(); + } +} From 99ff6e5eb220dcd496f2b9b74cededd5993508c7 Mon Sep 17 00:00:00 2001 From: John Coomes Date: Wed, 27 Aug 2008 15:41:58 -0700 Subject: [PATCH 63/95] 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 8ab0a4d7a94d83726a73347cbc4e3c6e7fb0d692 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Wed, 27 Aug 2008 16:33:34 -0700 Subject: [PATCH 64/95] 6732732: CTW with EA: assert(n != 0L,"Bad immediate dominator info.") Missing edge to a call's return value in EA Connection Graph. Reviewed-by: never --- hotspot/src/share/vm/opto/escape.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/opto/escape.cpp b/hotspot/src/share/vm/opto/escape.cpp index 956306eb1ec..1c1d5d8223f 100644 --- a/hotspot/src/share/vm/opto/escape.cpp +++ b/hotspot/src/share/vm/opto/escape.cpp @@ -1810,6 +1810,7 @@ void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *pha } else if (call_analyzer->is_return_local()) { // determine whether any arguments are returned set_escape_state(call_idx, PointsToNode::NoEscape); + bool ret_arg = false; for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { const Type* at = d->field_at(i); @@ -1817,6 +1818,7 @@ void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *pha Node *arg = call->in(i)->uncast(); if (call_analyzer->is_arg_returned(i - TypeFunc::Parms)) { + ret_arg = true; PointsToNode *arg_esp = ptnode_adr(arg->_idx); if (arg_esp->node_type() == PointsToNode::UnknownType) done = false; @@ -1828,6 +1830,11 @@ void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *pha } } } + if (done && !ret_arg) { + // Returns unknown object. + set_escape_state(call_idx, PointsToNode::GlobalEscape); + add_pointsto_edge(resproj_idx, _phantom_object); + } copy_dependencies = true; } else { set_escape_state(call_idx, PointsToNode::GlobalEscape); @@ -2234,7 +2241,9 @@ 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 (ptnode_adr(in->_idx)->node_type() == PointsToNode::JavaObject) { + PointsToNode::NodeType nt = ptnode_adr(ti)->node_type(); + assert(nt != PointsToNode::UnknownType, "all nodes should be known"); + if (nt == PointsToNode::JavaObject) { add_pointsto_edge(n_idx, ti); } else { add_deferred_edge(n_idx, ti); From b640b025c83f381da06113c9c8ccd2ee3ebd891c Mon Sep 17 00:00:00 2001 From: Poonam Bajaj Date: Wed, 27 Aug 2008 22:45:38 -0700 Subject: [PATCH 65/95] 6731958: Include all the SA classes into sa-jdi.jar Sa-jdi.jar bundled with JDK should include all the SA classes. Reviewed-by: swamyv --- hotspot/agent/make/build-pkglist | 2 +- hotspot/make/linux/makefiles/sa.make | 18 ++++++-- hotspot/make/sa.files | 59 ++++++++++++-------------- hotspot/make/solaris/makefiles/sa.make | 17 ++++++-- hotspot/make/windows/makefiles/sa.make | 11 ++++- 5 files changed, 64 insertions(+), 43 deletions(-) diff --git a/hotspot/agent/make/build-pkglist b/hotspot/agent/make/build-pkglist index 64d9a96cabb..c7cac3dfc05 100644 --- a/hotspot/agent/make/build-pkglist +++ b/hotspot/agent/make/build-pkglist @@ -8,4 +8,4 @@ FIND=$MKS_HOME/find SED=$MKS_HOME/sed SORT=$MKS_HOME/sort -$CD ../src/share/classes; $FIND sun/jvm/hotspot \( -name SCCS -prune \) -o -type d -print | $SED -e 's/\//./g' | $SORT > ../../../make/pkglist.txt +$CD ../src/share/classes; $FIND sun/jvm/hotspot com/sun/java/swing -type d -print | $SED -e 's/\//./g' | $SORT > ../../../make/pkglist.txt diff --git a/hotspot/make/linux/makefiles/sa.make b/hotspot/make/linux/makefiles/sa.make index 94463d6a049..eca293bb8c0 100644 --- a/hotspot/make/linux/makefiles/sa.make +++ b/hotspot/make/linux/makefiles/sa.make @@ -41,8 +41,9 @@ GENERATED = $(TOPDIR)/../generated SA_CLASSPATH = $(BOOT_JAVA_HOME)/lib/tools.jar # gnumake 3.78.1 does not accept the *s that -# are in AGENT_ALLFILES, so use the shell to expand them -AGENT_ALLFILES := $(shell /usr/bin/test -d $(AGENT_DIR) && /bin/ls $(AGENT_ALLFILES)) +# are in AGENT_FILES1 and AGENT_FILES2, so use the shell to expand them +AGENT_FILES1 := $(shell /usr/bin/test -d $(AGENT_DIR) && /bin/ls $(AGENT_FILES1)) +AGENT_FILES2 := $(shell /usr/bin/test -d $(AGENT_DIR) && /bin/ls $(AGENT_FILES2)) SA_CLASSDIR = $(GENERATED)/saclasses @@ -58,7 +59,7 @@ all: $(MAKE) -f sa.make $(GENERATED)/sa-jdi.jar; \ fi -$(GENERATED)/sa-jdi.jar: $(AGENT_ALLFILES) +$(GENERATED)/sa-jdi.jar: $(AGENT_FILES1) $(AGENT_FILES2) $(QUIETLY) echo "Making $@" $(QUIETLY) if [ "$(BOOT_JAVA_HOME)" = "" ]; then \ echo "ALT_BOOTDIR, BOOTDIR or JAVA_HOME needs to be defined to build SA"; \ @@ -72,9 +73,18 @@ $(GENERATED)/sa-jdi.jar: $(AGENT_ALLFILES) $(QUIETLY) if [ ! -d $(SA_CLASSDIR) ] ; then \ mkdir -p $(SA_CLASSDIR); \ fi - $(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -g -d $(SA_CLASSDIR) $(AGENT_ALLFILES) + + $(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES1) + $(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES2) + $(QUIETLY) $(REMOTE) $(COMPILE.RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer $(QUIETLY) echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES) + $(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql/sa.js + $(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql + $(QUIETLY) mkdir -p $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources + $(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources/* + $(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources/ + $(QUIETLY) cp -r $(AGENT_SRC_DIR)/images/* $(SA_CLASSDIR)/ $(QUIETLY) $(REMOTE) $(RUN.JAR) cf $@ -C $(SA_CLASSDIR)/ . $(QUIETLY) $(REMOTE) $(RUN.JAR) uf $@ -C $(AGENT_SRC_DIR) META-INF/services/com.sun.jdi.connect.Connector $(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.x86.X86ThreadContext diff --git a/hotspot/make/sa.files b/hotspot/make/sa.files index 6f76f9d8faa..7040cf517e7 100644 --- a/hotspot/make/sa.files +++ b/hotspot/make/sa.files @@ -33,40 +33,23 @@ AGENT_SRC_DIR = $(AGENT_DIR)/src/share/classes -AGENT_ALLFILES = \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/DebugServer.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/HelloWorld.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/HotSpotAgent.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/HotSpotSolarisVtblAccess.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/HotSpotTypeDataBase.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/LinuxVtblAccess.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/ObjectHistogram.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/RMIHelper.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/StackTrace.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/TestDebugger.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/Win32VtblAccess.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/Immediate.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/ImmediateOrRegister.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/Operand.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/Register.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/amd64/AMD64Register.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/amd64/AMD64Registers.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/ia64/IA64Register.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/ia64/IA64Registers.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/sparc/SPARCArgument.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/sparc/SPARCRegister.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/sparc/SPARCRegisterType.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/sparc/SPARCRegisters.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/x86/X86Register.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/x86/X86RegisterPart.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/x86/X86Registers.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/x86/X86SegmentRegister.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/x86/X86SegmentRegisters.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/bugspot/BugSpotAgent.java \ +# Splitted the set of files into two sets because on linux plaform +# listing or compiling all the files results in 'Argument list too long' error. + +AGENT_FILES1 = \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/amd64/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/ia64/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/sparc/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/x86/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/bugspot/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/bugspot/tree/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/c1/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/code/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/compiler/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/amd64/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/cdbg/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/cdbg/basic/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/cdbg/basic/x86/*.java \ @@ -75,7 +58,6 @@ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/dbx/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/dbx/sparc/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/dbx/x86/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/dummy/*.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/amd64/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/ia64/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/amd64/*.java \ @@ -107,7 +89,10 @@ $(AGENT_SRC_DIR)/sun/jvm/hotspot/interpreter/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/jdi/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/livejvm/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/memory/*.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/oops/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/oops/*.java + + +AGENT_FILES2 = \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/amd64/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/ia64/*.java \ @@ -127,7 +112,17 @@ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/win32_x86/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/x86/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/tools/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/tools/jcore/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/tools/soql/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/types/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/types/basic/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/utilities/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/utilities/memo/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/utilities/soql/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/action/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/classbrowser/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/table/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/tree/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/treetable/*.java \ +$(AGENT_SRC_DIR)/com/sun/java/swing/action/*.java \ +$(AGENT_SRC_DIR)/com/sun/java/swing/ui/*.java diff --git a/hotspot/make/solaris/makefiles/sa.make b/hotspot/make/solaris/makefiles/sa.make index 6d700b23437..f8c1bf416c0 100644 --- a/hotspot/make/solaris/makefiles/sa.make +++ b/hotspot/make/solaris/makefiles/sa.make @@ -37,8 +37,9 @@ GENERATED = ../generated SA_CLASSPATH = $(BOOT_JAVA_HOME)/lib/tools.jar # gnumake 3.78.1 does not accept the *s that -# are in AGENT_ALLFILES, so use the shell to expand them -AGENT_ALLFILES := $(shell /usr/bin/test -d $(AGENT_DIR) && /bin/ls $(AGENT_ALLFILES)) +# are in AGENT_FILES1 and AGENT_FILES2, so use the shell to expand them +AGENT_FILES1 := $(shell /usr/bin/test -d $(AGENT_DIR) && /bin/ls $(AGENT_FILES1)) +AGENT_FILES2 := $(shell /usr/bin/test -d $(AGENT_DIR) && /bin/ls $(AGENT_FILES2)) SA_CLASSDIR = $(GENERATED)/saclasses @@ -52,7 +53,7 @@ all: $(MAKE) -f sa.make $(GENERATED)/sa-jdi.jar; \ fi -$(GENERATED)/sa-jdi.jar: $(AGENT_ALLFILES) +$(GENERATED)/sa-jdi.jar: $(AGENT_FILES1) $(AGENT_FILES2) $(QUIETLY) echo "Making $@"; $(QUIETLY) if [ "$(BOOT_JAVA_HOME)" = "" ]; then \ echo "ALT_BOOTDIR, BOOTDIR or JAVA_HOME needs to be defined to build SA"; \ @@ -66,9 +67,17 @@ $(GENERATED)/sa-jdi.jar: $(AGENT_ALLFILES) $(QUIETLY) if [ ! -d $(SA_CLASSDIR) ] ; then \ mkdir -p $(SA_CLASSDIR); \ fi - $(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -g -d $(SA_CLASSDIR) $(AGENT_ALLFILES) + $(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES1) + $(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES2) + $(QUIETLY) $(COMPILE.RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer $(QUIETLY) echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES) + $(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql/sa.js + $(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql + $(QUIETLY) mkdir -p $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources + $(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources/* + $(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources/ + $(QUIETLY) cp -r $(AGENT_SRC_DIR)/images/* $(SA_CLASSDIR)/ $(QUIETLY) $(RUN.JAR) cf $@ -C $(SA_CLASSDIR)/ . $(QUIETLY) $(RUN.JAR) uf $@ -C $(AGENT_SRC_DIR) META-INF/services/com.sun.jdi.connect.Connector $(QUIETLY) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.proc.ProcDebuggerLocal diff --git a/hotspot/make/windows/makefiles/sa.make b/hotspot/make/windows/makefiles/sa.make index 481b5149d03..57fd493f823 100644 --- a/hotspot/make/windows/makefiles/sa.make +++ b/hotspot/make/windows/makefiles/sa.make @@ -49,15 +49,22 @@ SA_PROPERTIES = $(SA_CLASSDIR)\sa.properties default:: $(GENERATED)\sa-jdi.jar -$(GENERATED)\sa-jdi.jar: $(AGENT_ALLFILES:/=\) +$(GENERATED)\sa-jdi.jar: $(AGENT_FILES1:/=\) $(AGENT_FILES2:/=\) @if not exist $(SA_CLASSDIR) mkdir $(SA_CLASSDIR) @echo ...Building sa-jdi.jar @echo ...$(COMPILE_JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -g -d $(SA_CLASSDIR) .... - @$(COMPILE_JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -g -d $(SA_CLASSDIR) $(AGENT_ALLFILES:/=\) + @$(COMPILE_JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES1:/=\) + @$(COMPILE_JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES2:/=\) $(COMPILE_RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer $(QUIETLY) echo $(SA_BUILD_VERSION_PROP) > $(SA_PROPERTIES) $(RUN_JAR) cf $@ -C saclasses . $(RUN_JAR) uf $@ -C $(AGENT_SRC_DIR:/=\) META-INF\services\com.sun.jdi.connect.Connector + $(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql/sa.js + $(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql + $(QUIETLY) mkdir -p $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources + $(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources/* + $(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources/ + $(QUIETLY) cp -r $(AGENT_SRC_DIR)/images/* $(SA_CLASSDIR)/ $(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal $(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.x86.X86ThreadContext $(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.ia64.IA64ThreadContext From bdd62705f2f152f319dfa3f5139b8e1c3f29dd76 Mon Sep 17 00:00:00 2001 From: Chuck Rasbold Date: Thu, 28 Aug 2008 10:22:12 -0700 Subject: [PATCH 66/95] 6611837: block frequency is zero Insert_goto_at should set frequency for newly created blocks Reviewed-by: never --- hotspot/src/share/vm/opto/block.cpp | 6 ++++++ hotspot/src/share/vm/opto/gcm.cpp | 25 ++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/opto/block.cpp b/hotspot/src/share/vm/opto/block.cpp index c6b94a45af2..be861b643a2 100644 --- a/hotspot/src/share/vm/opto/block.cpp +++ b/hotspot/src/share/vm/opto/block.cpp @@ -467,6 +467,10 @@ void PhaseCFG::insert_goto_at(uint block_no, uint succ_no) { // get successor block succ_no assert(succ_no < in->_num_succs, "illegal successor number"); Block* out = in->_succs[succ_no]; + // Compute frequency of the new block. Do this before inserting + // new block in case succ_prob() needs to infer the probability from + // surrounding blocks. + float freq = in->_freq * in->succ_prob(succ_no); // get ProjNode corresponding to the succ_no'th successor of the in block ProjNode* proj = in->_nodes[in->_nodes.size() - in->_num_succs + succ_no]->as_Proj(); // create region for basic block @@ -491,6 +495,8 @@ void PhaseCFG::insert_goto_at(uint block_no, uint succ_no) { } // remap predecessor's successor to new block in->_succs.map(succ_no, block); + // Set the frequency of the new block + block->_freq = freq; // add new basic block to basic block list _blocks.insert(block_no + 1, block); _num_blocks++; diff --git a/hotspot/src/share/vm/opto/gcm.cpp b/hotspot/src/share/vm/opto/gcm.cpp index 0627e50505b..b65101197cb 100644 --- a/hotspot/src/share/vm/opto/gcm.cpp +++ b/hotspot/src/share/vm/opto/gcm.cpp @@ -1609,7 +1609,30 @@ void CFGLoop::compute_freq() { float Block::succ_prob(uint i) { int eidx = end_idx(); Node *n = _nodes[eidx]; // Get ending Node - int op = n->is_Mach() ? n->as_Mach()->ideal_Opcode() : n->Opcode(); + + int op = n->Opcode(); + if (n->is_Mach()) { + if (n->is_MachNullCheck()) { + // Can only reach here if called after lcm. The original Op_If is gone, + // so we attempt to infer the probability from one or both of the + // successor blocks. + assert(_num_succs == 2, "expecting 2 successors of a null check"); + // If either successor has only one predecessor, then the + // probabiltity estimate can be derived using the + // relative frequency of the successor and this block. + if (_succs[i]->num_preds() == 2) { + return _succs[i]->_freq / _freq; + } else if (_succs[1-i]->num_preds() == 2) { + return 1 - (_succs[1-i]->_freq / _freq); + } else { + // Estimate using both successor frequencies + float freq = _succs[i]->_freq; + return freq / (freq + _succs[1-i]->_freq); + } + } + op = n->as_Mach()->ideal_Opcode(); + } + // Switch on branch type switch( op ) { From 3cc7c78362352dba58ca2c680150e4dcd7aa1187 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 28 Aug 2008 11:05:13 -0700 Subject: [PATCH 67/95] Added tag jdk7-b34 for changeset 5d6b06900843 --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index f3da47b8cc1..8366e3060e0 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -8,3 +8,4 @@ cbc8ad9dd0e085a607427ea35411990982f19a36 jdk7-b25 3300a35a0bd56d695b92fe0b34f03ebbfc939064 jdk7-b31 64da805be725721bf2004e7409a0d7a16fc8ddbc jdk7-b32 bb1ef4ee3d2c8cbf43a37d372325a7952be590b9 jdk7-b33 +46a989ab932992b2084b946eeb322fa99b9fee6c jdk7-b34 From b0c44a6c6eb94ed4469ff154f5aed427f5206032 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 28 Aug 2008 11:05:14 -0700 Subject: [PATCH 68/95] Added tag jdk7-b34 for changeset 1faafeba249c --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index 88de55dd33b..d11eee86062 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -8,3 +8,4 @@ c0252adbb2abbfdd6c35595429ac6fbdd98e20ac jdk7-b30 ef6af34d75a7b44e77083f1d4ee47631fa09d3b4 jdk7-b31 80a0f46a6203e727012bd579fe38a609b83decce jdk7-b32 6a5b9d2f8b20de54e3bfe33cd12bd0793caedc4e jdk7-b33 +0a812b9824e5d17b073765d1505594b49ff88a10 jdk7-b34 From 9da2b45a82de48bbcf4b0c6010cbaefbebcc91c2 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 28 Aug 2008 11:05:17 -0700 Subject: [PATCH 69/95] Added tag jdk7-b34 for changeset fff241969646 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index fbe09df39c2..0a20ba0d8e5 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -8,3 +8,4 @@ d1605aabd0a15ecf93787c47de63073c33fba52d jdk7-b30 9c2ecc2ffb125f14fab3857fe7689598956348a0 jdk7-b31 b727c32788a906c04839516ae7443a085185a300 jdk7-b32 585535ec8a14adafa6bfea65d6975e29094c8cec jdk7-b33 +5251a9cd8eb8743eee647365bee1c8afdc131556 jdk7-b34 From 14ecb7850fb80aa37f8325d5a7c3b99d26f4478d Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 28 Aug 2008 11:05:21 -0700 Subject: [PATCH 70/95] Added tag jdk7-b34 for changeset e33522ffd9bb --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index 3773ca1e2d4..1a5477b5629 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -8,3 +8,4 @@ b996318955c0ad8e9fa0ffb56c74f626786e863f jdk7-b28 255d64ee287e926e8629dd80bc67690e65eeba30 jdk7-b31 400a5ee432cc2db9031e06852ddde9264a192b48 jdk7-b32 95375835527f0bf06124ce984266e2ad5de8a6dc jdk7-b33 +01facdf8cabdeaaf68cca037aef56cc5f074897f jdk7-b34 From 83dafe98b2fa619b1ccf5f26a28d9fa175f89eaa Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 28 Aug 2008 11:05:22 -0700 Subject: [PATCH 71/95] Added tag jdk7-b34 for changeset 115202335eb1 --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index db69f05ef33..e367d4469ba 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -8,3 +8,4 @@ eefcd5204500a11d6aa802dca9f961cf10ab64c2 jdk7-b28 f978623825364a2ad9c6f51d02fc9424a8b0bc86 jdk7-b31 e6daca2eced9d84b01255cabcfcc49164c26405e jdk7-b32 6dcbcfb9551aaa2a80906c28ab48c9a8564e0e64 jdk7-b33 +7a9f629cd957e3169a1a769f763fe060d078785c jdk7-b34 From 3735e1a4b2ddb2a3a0ce128c1954313781eacb39 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 28 Aug 2008 11:05:27 -0700 Subject: [PATCH 72/95] Added tag jdk7-b34 for changeset 8810ae8edcd1 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index 75a9825e99c..88db46731dd 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -8,3 +8,4 @@ b6d6877c1155621a175dccd12dc14c54f938fb8b jdk7-b30 b7474b739d13bacd9972f88ac91f6350b7b0be12 jdk7-b31 c51121419e30eac5f0fbbce45ff1711c4ce0de28 jdk7-b32 fa4c0a6cdd25d97d4e6f5d7aa180bcbb0e0d56af jdk7-b33 +434055a0716ee44bca712ebca02fc04b20e6e288 jdk7-b34 From 969313d8cc04599fc67e1be48ab978d22dd00eee Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 28 Aug 2008 11:05:35 -0700 Subject: [PATCH 73/95] Added tag jdk7-b34 for changeset 1f47a876c043 --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index 7f30f314bd3..3a8b6e62c14 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -8,3 +8,4 @@ eaf608c64fecf70f955dc9f29f94c055b183aeec jdk7-b30 07c916ecfc71f6bf432e4ff09bfbfb6290b5703c jdk7-b31 13aee98cc0d8e24a084b62ad1d48d2a49792416c jdk7-b32 0a5f04fb72825302a80a67c636a7ddc410ead266 jdk7-b33 +4026dece07e86ae75154c05b98ba342d00828ed7 jdk7-b34 From aba715ae04ad24ed174f555f5243d9845f4a604f Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Thu, 28 Aug 2008 23:03:55 -0700 Subject: [PATCH 74/95] 6732698: crash with dead code from compressed oops in gcm Reviewed-by: rasbold --- hotspot/src/share/vm/opto/matcher.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hotspot/src/share/vm/opto/matcher.cpp b/hotspot/src/share/vm/opto/matcher.cpp index 1640b28e3cc..f8ff59632ae 100644 --- a/hotspot/src/share/vm/opto/matcher.cpp +++ b/hotspot/src/share/vm/opto/matcher.cpp @@ -1450,6 +1450,8 @@ MachNode *Matcher::ReduceInst( State *s, int rule, Node *&mem ) { Node *leaf = s->_leaf; // Check for instruction or instruction chain rule if( rule >= _END_INST_CHAIN_RULE || rule < _BEGIN_INST_CHAIN_RULE ) { + assert(C->node_arena()->contains(s->_leaf) || !has_new_node(s->_leaf), + "duplicating node that's already been matched"); // Instruction mach->add_req( leaf->in(0) ); // Set initial control // Reduce interior of complex instruction @@ -1872,6 +1874,12 @@ void Matcher::find_shared( Node *n ) { // Clone addressing expressions as they are "free" in most instructions if( mem_op && i == MemNode::Address && mop == Op_AddP ) { + if (m->in(AddPNode::Base)->Opcode() == Op_DecodeN) { + // Bases used in addresses must be shared but since + // they are shared through a DecodeN they may appear + // to have a single use so force sharing here. + set_shared(m->in(AddPNode::Base)->in(1)); + } Node *off = m->in(AddPNode::Offset); if( off->is_Con() ) { set_visited(m); // Flag as visited now From 29440e8636b1f5b65713eaee6f6ea5a7faca9fce Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Wed, 3 Sep 2008 14:57:00 -0700 Subject: [PATCH 75/95] 6744422: incorrect handling of -1 in set_jump_destination Reviewed-by: rasbold --- hotspot/src/cpu/x86/vm/nativeInst_x86.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp b/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp index c3951c5af29..bd15cbb7b7b 100644 --- a/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp +++ b/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp @@ -391,6 +391,9 @@ class NativeJump: public NativeInstruction { void set_jump_destination(address dest) { intptr_t val = dest - next_instruction_address(); + if (dest == (address) -1) { + val = -5; // jump to self + } #ifdef AMD64 assert((labs(val) & 0xFFFFFFFF00000000) == 0 || dest == (address)-1, "must be 32bit offset or -1"); #endif // AMD64 From f76aa542707dcb0c945b3bcf7e266fa2c0b0de29 Mon Sep 17 00:00:00 2001 From: Erik Trimble Date: Thu, 4 Sep 2008 18:40:08 -0700 Subject: [PATCH 76/95] 6745064: Update Hotspot build number for HS14 Bump build number for hs14-b04 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 4ec4a92ff7a..bc6ca1e4f83 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=03 +HS_BUILD_NUMBER=04 JDK_MAJOR_VER=1 JDK_MINOR_VER=7 From 51a345480abfbbb4c76ea377c7b0701f91001074 Mon Sep 17 00:00:00 2001 From: Dave Bristor Date: Mon, 8 Sep 2008 13:44:32 -0700 Subject: [PATCH 77/95] 6661861: Decrease memory use of Inflaters by ZipFile Fix allows release of native resources earlier than without fix Reviewed-by: alanb --- jdk/src/share/classes/java/util/zip/Inflater.java | 7 +++++-- jdk/src/share/classes/java/util/zip/ZipFile.java | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/java/util/zip/Inflater.java b/jdk/src/share/classes/java/util/zip/Inflater.java index bc0bdf55f3e..68c8d623397 100644 --- a/jdk/src/share/classes/java/util/zip/Inflater.java +++ b/jdk/src/share/classes/java/util/zip/Inflater.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-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 @@ -73,11 +73,13 @@ package java.util.zip; public class Inflater { private long strm; - private byte[] buf = new byte[0]; + private byte[] buf = defaultBuf; private int off, len; private boolean finished; private boolean needDict; + private static final byte[] defaultBuf = new byte[0]; + static { /* Zip library is loaded from System.initializeSystemClass */ initIDs(); @@ -318,6 +320,7 @@ class Inflater { public synchronized void reset() { ensureOpen(); reset(strm); + buf = defaultBuf; finished = false; needDict = false; off = len = 0; diff --git a/jdk/src/share/classes/java/util/zip/ZipFile.java b/jdk/src/share/classes/java/util/zip/ZipFile.java index 8ad177fdc92..37e92ddecb7 100644 --- a/jdk/src/share/classes/java/util/zip/ZipFile.java +++ b/jdk/src/share/classes/java/util/zip/ZipFile.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-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 @@ -278,7 +278,6 @@ class ZipFile implements ZipConstants { int size = inflaters.size(); if (size > 0) { Inflater inf = (Inflater)inflaters.remove(size - 1); - inf.reset(); return inf; } else { return new Inflater(true); @@ -291,6 +290,7 @@ class ZipFile implements ZipConstants { */ private void releaseInflater(Inflater inf) { synchronized (inflaters) { + inf.reset(); inflaters.add(inf); } } From 367e60a438410ae34729307a81488371c1ce0b92 Mon Sep 17 00:00:00 2001 From: Dave Bristor Date: Mon, 8 Sep 2008 14:11:13 -0700 Subject: [PATCH 78/95] 6356642: extcheck.exe -verbose throws ArrayIndexOutOfBoundsException exception Fix causes printing of user-level error messages instead of throwing exceptions Reviewed-by: sherman --- .../com/sun/tools/extcheck/ExtCheck.java | 67 +++++++------- .../classes/com/sun/tools/extcheck/Main.java | 36 ++++++-- .../sun/tools/extcheck/TestExtcheckArgs.java | 92 +++++++++++++++++++ .../sun/tools/extcheck/TestExtcheckArgs.sh | 47 ++++++++++ 4 files changed, 198 insertions(+), 44 deletions(-) create mode 100644 jdk/test/com/sun/tools/extcheck/TestExtcheckArgs.java create mode 100644 jdk/test/com/sun/tools/extcheck/TestExtcheckArgs.sh diff --git a/jdk/src/share/classes/com/sun/tools/extcheck/ExtCheck.java b/jdk/src/share/classes/com/sun/tools/extcheck/ExtCheck.java index b83381a6514..b69cf00cd8b 100644 --- a/jdk/src/share/classes/com/sun/tools/extcheck/ExtCheck.java +++ b/jdk/src/share/classes/com/sun/tools/extcheck/ExtCheck.java @@ -1,5 +1,5 @@ /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-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 @@ -256,13 +256,13 @@ public class ExtCheck { private boolean isNotOlderThan(String already,String target) throws NumberFormatException { - if (already == null || already.length() < 1) { + if (already == null || already.length() < 1) { throw new NumberFormatException("Empty version string"); } - // Until it matches scan and compare numbers - StringTokenizer dtok = new StringTokenizer(target, ".", true); - StringTokenizer stok = new StringTokenizer(already, ".", true); + // Until it matches scan and compare numbers + StringTokenizer dtok = new StringTokenizer(target, ".", true); + StringTokenizer stok = new StringTokenizer(already, ".", true); while (dtok.hasMoreTokens() || stok.hasMoreTokens()) { int dver; int sver; @@ -276,19 +276,19 @@ public class ExtCheck { } else sver = 0; - if (sver < dver) - return false; // Known to be incompatible - if (sver > dver) - return true; // Known to be compatible + if (sver < dver) + return false; // Known to be incompatible + if (sver > dver) + return true; // Known to be compatible - // Check for and absorb separators - if (dtok.hasMoreTokens()) - dtok.nextToken(); - if (stok.hasMoreTokens()) - stok.nextToken(); - // Compare next component - } - // All components numerically equal + // Check for and absorb separators + if (dtok.hasMoreTokens()) + dtok.nextToken(); + if (stok.hasMoreTokens()) + stok.nextToken(); + // Compare next component + } + // All components numerically equal return true; } @@ -307,11 +307,10 @@ public class ExtCheck { } /** - * Print out the error message and exit from the program + * Throws a RuntimeException with a message describing the error. */ - static void error(String message){ - System.err.println(message); - System.exit(-1); + static void error(String message) throws RuntimeException { + throw new RuntimeException(message); } @@ -356,19 +355,19 @@ public class ExtCheck { } private JarFile findJarFile(URL url) throws IOException { - // Optimize case where url refers to a local jar file - if ("file".equals(url.getProtocol())) { - String path = url.getFile().replace('/', File.separatorChar); - File file = new File(path); - if (!file.exists()) { - throw new FileNotFoundException(path); - } - return new JarFile(path); - } - URLConnection uc = getBaseURL().openConnection(); - //uc.setRequestProperty(USER_AGENT_JAVA_VERSION, JAVA_VERSION); - return ((JarURLConnection)uc).getJarFile(); - } + // Optimize case where url refers to a local jar file + if ("file".equals(url.getProtocol())) { + String path = url.getFile().replace('/', File.separatorChar); + File file = new File(path); + if (!file.exists()) { + throw new FileNotFoundException(path); + } + return new JarFile(path); + } + URLConnection uc = getBaseURL().openConnection(); + //uc.setRequestProperty(USER_AGENT_JAVA_VERSION, JAVA_VERSION); + return ((JarURLConnection)uc).getJarFile(); + } /* diff --git a/jdk/src/share/classes/com/sun/tools/extcheck/Main.java b/jdk/src/share/classes/com/sun/tools/extcheck/Main.java index 893af063f46..022346efc13 100644 --- a/jdk/src/share/classes/com/sun/tools/extcheck/Main.java +++ b/jdk/src/share/classes/com/sun/tools/extcheck/Main.java @@ -1,5 +1,5 @@ /* - * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-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 @@ -32,7 +32,10 @@ import java.io.*; */ public final class Main { - + public static final String INSUFFICIENT = "Insufficient number of arguments"; + public static final String MISSING = "Missing argument"; + public static final String DOES_NOT_EXIST = "Jarfile does not exist: "; + public static final String EXTRA = "Extra command line argument: "; /** * Terminates with one of the following codes @@ -40,26 +43,36 @@ public final class Main { * 0 No newer jar file was found * -1 An internal error occurred */ - public static void main(String args[]){ - - if (args.length < 1){ - System.err.println("Usage: extcheck [-verbose] "); + public static void main(String args[]) { + try { + realMain(args); + } catch (Exception ex) { + System.err.println(ex.getMessage()); System.exit(-1); } + } + + public static void realMain(String[] args) throws Exception { + if (args.length < 1) { + usage(INSUFFICIENT); + } int argIndex = 0; boolean verboseFlag = false; - if (args[argIndex].equals("-verbose")){ + if (args[argIndex].equals("-verbose")) { verboseFlag = true; argIndex++; + if (argIndex >= args.length) { + usage(MISSING); + } } String jarName = args[argIndex]; argIndex++; File jarFile = new File(jarName); if (!jarFile.exists()){ - ExtCheck.error("Jarfile " + jarName + " does not exist"); + usage(DOES_NOT_EXIST + jarName); } if (argIndex < args.length) { - ExtCheck.error("Extra command line argument :"+args[argIndex]); + usage(EXTRA + args[argIndex]); } ExtCheck jt = ExtCheck.create(jarFile,verboseFlag); boolean result = jt.checkInstalledAgainstTarget(); @@ -68,7 +81,10 @@ public final class Main { } else { System.exit(1); } - } + private static void usage(String msg) throws Exception { + throw new Exception(msg + "\nUsage: extcheck [-verbose] "); + } } + diff --git a/jdk/test/com/sun/tools/extcheck/TestExtcheckArgs.java b/jdk/test/com/sun/tools/extcheck/TestExtcheckArgs.java new file mode 100644 index 00000000000..0e5514b875a --- /dev/null +++ b/jdk/test/com/sun/tools/extcheck/TestExtcheckArgs.java @@ -0,0 +1,92 @@ +/* + * 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 6356642 + * @summary Verify that extcheck exits appropriately when invalid args are given. + * @run shell TestExtcheckArgs.sh + * @author Dave Bristor + */ + +import java.io.File; +import com.sun.tools.extcheck.Main; + +/* + * Test extcheck by using Runtime.exec instead of invoking + * com.sun.tools.extcheck.Main.main, since the latter does its own + * System.exit under the conditions checked here. + */ +public class TestExtcheckArgs { + public static void realMain(String[] args) throws Throwable { + String testJar = System.getenv("TESTJAVA") + File.separator + + "lib" + File.separator + "jconsole.jar"; + + verify(new String[] { + }, Main.INSUFFICIENT); + verify(new String[] { + "-verbose" + }, Main.MISSING); + verify(new String[] { + "-verbose", + "foo" + }, Main.DOES_NOT_EXIST); + verify(new String[] { + testJar, + "bar" + }, Main.EXTRA); + verify(new String[] { + "-verbose", + testJar, + "bar" + }, Main.EXTRA); + } + + static void verify(String[] args, String expected) throws Throwable { + try { + Main.realMain(args); + fail(); + } catch (Exception ex) { + if (ex.getMessage().startsWith(expected)) { + pass(); + } else { + fail("Unexpected message: " + ex.getMessage()); + } + } + } + + //--------------------- Infrastructure --------------------------- + static volatile int passed = 0, failed = 0; + static boolean pass() {passed++; return true;} + static boolean fail() {failed++; Thread.dumpStack(); return false;} + static boolean fail(String msg) {System.out.println(msg); return fail();} + static void unexpected(Throwable t) {failed++; t.printStackTrace();} + static boolean check(boolean cond) {if (cond) pass(); else fail(); return cond;} + static boolean equal(Object x, Object y) { + if (x == null ? y == null : x.equals(y)) return pass(); + else return fail(x + " not equal to " + y);} + public static void main(String[] args) throws Throwable { + try {realMain(args);} catch (Throwable t) {unexpected(t);} + System.out.println("\nPassed = " + passed + " failed = " + failed); + if (failed > 0) throw new AssertionError("Some tests failed");} +} diff --git a/jdk/test/com/sun/tools/extcheck/TestExtcheckArgs.sh b/jdk/test/com/sun/tools/extcheck/TestExtcheckArgs.sh new file mode 100644 index 00000000000..3c478c1e13d --- /dev/null +++ b/jdk/test/com/sun/tools/extcheck/TestExtcheckArgs.sh @@ -0,0 +1,47 @@ +#! /bin/sh + +# +# 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. +# + +if [ "x$TESTJAVA" = x ]; then + TESTJAVA=$1; shift + TESTCLASSES=. + TESTSRC=. +fi +export TESTJAVA + +case "`uname`" in Windows*|CYGWIN* ) PS=';';; *) PS=':';; esac + +${TESTJAVA}/bin/javac -d ${TESTCLASSES} -classpath ${TESTJAVA}/lib/tools.jar${PS}${TESTCLASSES} ${TESTSRC}/TestExtcheckArgs.java +rc=$? +if [ $rc != 0 ]; then + echo Compilation failure with exit status $rc + exit $rc +fi + +${TESTJAVA}/bin/java -classpath ${TESTJAVA}/lib/tools.jar${PS}${TESTCLASSES} TestExtcheckArgs +rc=$? +if [ $rc != 0 ]; then + echo Execution failure with exit status $rc + exit $rc +fi From ebdad848b87e7fa89c73a28c452a6848840acdca Mon Sep 17 00:00:00 2001 From: Shanliang Jiang Date: Tue, 9 Sep 2008 14:17:29 +0200 Subject: [PATCH 79/95] 6736611: [Evt Srv] EventSubscriber.unsubscribe removes other listeners Reviewed-by: emcmanus --- .../management/event/EventSubscriber.java | 82 ++++++------ .../management/eventService/SubUnsubTest.java | 125 ++++++++++++++++++ 2 files changed, 164 insertions(+), 43 deletions(-) create mode 100644 jdk/test/javax/management/eventService/SubUnsubTest.java diff --git a/jdk/src/share/classes/javax/management/event/EventSubscriber.java b/jdk/src/share/classes/javax/management/event/EventSubscriber.java index 2426345550f..9948810bfeb 100644 --- a/jdk/src/share/classes/javax/management/event/EventSubscriber.java +++ b/jdk/src/share/classes/javax/management/event/EventSubscriber.java @@ -149,10 +149,10 @@ public class EventSubscriber implements EventConsumer { if (listener == null) throw new IllegalArgumentException("Null listener"); - final ListenerInfo li = new ListenerInfo(listener, filter, handback); - List list; + final MyListenerInfo li = new MyListenerInfo(listener, filter, handback); + List list; - Map> map; + Map> map; Set names; if (name.isPattern()) { map = patternSubscriptionMap; @@ -165,7 +165,7 @@ public class EventSubscriber implements EventConsumer { synchronized (map) { list = map.get(name); if (list == null) { - list = new ArrayList(); + list = new ArrayList(); map.put(name, list); } list.add(li); @@ -186,7 +186,6 @@ public class EventSubscriber implements EventConsumer { public void unsubscribe(ObjectName name, NotificationListener listener) throws ListenerNotFoundException, IOException { - if (logger.traceOn()) logger.trace("unsubscribe", "" + name); @@ -196,7 +195,7 @@ public class EventSubscriber implements EventConsumer { if (listener == null) throw new ListenerNotFoundException(); - Map> map; + Map> map; Set names; if (name.isPattern()) { @@ -207,22 +206,39 @@ public class EventSubscriber implements EventConsumer { names = Collections.singleton(name); } - final ListenerInfo li = new ListenerInfo(listener, null, null); - List list; + List toRemove = new ArrayList(); synchronized (map) { - list = map.get(name); - if (list == null || !list.remove(li)) + List list = map.get(name); + if (list == null) { throw new ListenerNotFoundException(); + } + + for (MyListenerInfo info : list) { + if (info.listener == listener) { + toRemove.add(info); + } + } + + if (toRemove.isEmpty()) { + throw new ListenerNotFoundException(); + } + + for (MyListenerInfo info : toRemove) { + list.remove(info); + } if (list.isEmpty()) map.remove(name); } for (ObjectName mbeanName : names) { - try { - mbeanServer.removeNotificationListener(mbeanName, li.listener); - } catch (Exception e) { - logger.fine("unsubscribe", "removeNotificationListener", e); + for (MyListenerInfo i : toRemove) { + try { + mbeanServer.removeNotificationListener(mbeanName, + i.listener, i.filter, i.handback); + } catch (Exception e) { + logger.fine("unsubscribe", "removeNotificationListener", e); + } } } } @@ -256,12 +272,12 @@ public class EventSubscriber implements EventConsumer { return; } - final List listeners = new ArrayList(); + final List listeners = new ArrayList(); // If there are subscribers for the exact name that has just arrived // then add their listeners to the list. synchronized (exactSubscriptionMap) { - List exactListeners = exactSubscriptionMap.get(name); + List exactListeners = exactSubscriptionMap.get(name); if (exactListeners != null) listeners.addAll(exactListeners); } @@ -277,7 +293,7 @@ public class EventSubscriber implements EventConsumer { } // Add all the listeners just found to the new MBean. - for (ListenerInfo li : listeners) { + for (MyListenerInfo li : listeners) { try { mbeanServer.addNotificationListener( name, @@ -292,12 +308,12 @@ public class EventSubscriber implements EventConsumer { } }; - private static class ListenerInfo { + private static class MyListenerInfo { public final NotificationListener listener; public final NotificationFilter filter; public final Object handback; - public ListenerInfo(NotificationListener listener, + public MyListenerInfo(NotificationListener listener, NotificationFilter filter, Object handback) { @@ -308,26 +324,6 @@ public class EventSubscriber implements EventConsumer { this.filter = filter; this.handback = handback; } - - /* Two ListenerInfo instances are equal if they have the same - * NotificationListener. This means that we can use List.remove - * to implement the two-argument removeNotificationListener. - */ - @Override - public boolean equals(Object o) { - if (o == this) - return true; - - if (!(o instanceof ListenerInfo)) - return false; - - return listener.equals(((ListenerInfo)o).listener); - } - - @Override - public int hashCode() { - return listener.hashCode(); - } } // --------------------------------- @@ -338,10 +334,10 @@ public class EventSubscriber implements EventConsumer { // --------------------------------- private final MBeanServer mbeanServer; - private final Map> exactSubscriptionMap = - new HashMap>(); - private final Map> patternSubscriptionMap = - new HashMap>(); + private final Map> exactSubscriptionMap = + new HashMap>(); + private final Map> patternSubscriptionMap = + new HashMap>(); diff --git a/jdk/test/javax/management/eventService/SubUnsubTest.java b/jdk/test/javax/management/eventService/SubUnsubTest.java new file mode 100644 index 00000000000..f8889882317 --- /dev/null +++ b/jdk/test/javax/management/eventService/SubUnsubTest.java @@ -0,0 +1,125 @@ +/* + * 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 SubUnsubTest + * @bug 6736611 + * @summary Test not to remove other listeners when calling unsubscribe + * @author Shanliang JIANG + * @run clean SubUnsubTest + * @run build SubUnsubTest + * @run main SubUnsubTest + */ + +import java.lang.management.ManagementFactory; +import javax.management.MBeanServer; +import javax.management.Notification; +import javax.management.NotificationFilter; +import javax.management.NotificationBroadcasterSupport; +import javax.management.NotificationListener; +import javax.management.ObjectName; +import javax.management.event.EventSubscriber; +import javax.management.event.EventClient; +public class SubUnsubTest { + private static class CountListener implements NotificationListener { + volatile int count; + + public void handleNotification(Notification n, Object h) { + count++; + } + } + + public static interface SenderMBean {} + + public static class Sender extends NotificationBroadcasterSupport + implements SenderMBean { + void send() { + Notification n = new Notification("type", this, 1L); + sendNotification(n); + } + } + + public static void main(String[] args) throws Exception { + System.out.println("Testing EventSubscriber-unsubscribe method."); + + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + ObjectName name1 = new ObjectName("d:type=Sender,id=1"); + ObjectName name2 = new ObjectName("d:type=Sender,id=2"); + ObjectName pattern = new ObjectName("d:type=Sender,*"); + Sender sender1 = new Sender(); + Sender sender2 = new Sender(); + mbs.registerMBean(sender1, name1); + mbs.registerMBean(sender2, name2); + + EventSubscriber sub = EventSubscriber.getEventSubscriber(mbs); + + System.out.println("Single subscribe covering both MBeans"); + CountListener listener = new CountListener(); + + System.out.println("Subscribing and adding listeners ..."); + sub.subscribe(pattern, listener, null, null); + sub.subscribe(name2, listener, null, null); + mbs.addNotificationListener(name2, listener, null, null); + + sender1.send(); + sender2.send(); + if (listener.count != 4) { + throw new RuntimeException("Do not receive all notifications: "+ + "Expect 4, got "+listener.count); + } + + System.out.println("Unsubscribe the listener with the pattern."); + sub.unsubscribe(pattern, listener); + listener.count = 0; + sender1.send(); + sender2.send(); + if (listener.count != 2) { + throw new RuntimeException("The method unsubscribe removes wrong listeners."); + } + + System.out.println("Unsubscribe the listener with the ObjectName."); + sub.unsubscribe(name2, listener); + listener.count = 0; + sender1.send(); + sender2.send(); + if (listener.count != 1) { + throw new RuntimeException("The method unsubscribe removes wrong listeners."); + } + + System.out.println("Subscribe twice to same MBean with same listener " + + "but different handback."); + sub.subscribe(name1, listener, null, new Object()); + sub.subscribe(name1, listener, null, new Object()); + listener.count = 0; + + sub.unsubscribe(name1, listener); + sender1.send(); + if (listener.count > 0) { + throw new RuntimeException("EventSubscriber: the method unsubscribe" + + " does not remove a listener which was subscribed 2 times."); + } + + System.out.println("Bye bye!"); + return; + } +} \ No newline at end of file From e0a15fc51d23c8fb17eea2ad54ba3ac0867e8a9b Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Tue, 9 Sep 2008 14:57:30 +0200 Subject: [PATCH 80/95] 6746196: Some JMX classes do not compile with Eclipse compiler Reviewed-by: dfuchs --- .../jmx/mbeanserver/DefaultMXBeanMappingFactory.java | 10 +++++----- .../com/sun/jmx/mbeanserver/MBeanIntrospector.java | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java index 3509c40f3c2..b86b2e00128 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java @@ -1172,10 +1172,10 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory { final Class propertyNamesClass = ConstructorProperties.class; Class targetClass = getTargetClass(); - Constructor[] constrs = targetClass.getConstructors(); + Constructor[] constrs = targetClass.getConstructors(); // Applicable if and only if there are any annotated constructors - List annotatedConstrList = newList(); + List> annotatedConstrList = newList(); for (Constructor constr : constrs) { if (Modifier.isPublic(constr.getModifiers()) && constr.getAnnotation(propertyNamesClass) != null) @@ -1206,7 +1206,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory { // Also remember the set of properties in that constructor // so we can test unambiguity. Set getterIndexSets = newSet(); - for (Constructor constr : annotatedConstrList) { + for (Constructor constr : annotatedConstrList) { String[] propertyNames = constr.getAnnotation(propertyNamesClass).value(); @@ -1363,10 +1363,10 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory { } private static class Constr { - final Constructor constructor; + final Constructor constructor; final int[] paramIndexes; final BitSet presentParams; - Constr(Constructor constructor, int[] paramIndexes, + Constr(Constructor constructor, int[] paramIndexes, BitSet presentParams) { this.constructor = constructor; this.paramIndexes = paramIndexes; diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java index 725292bca36..99aaa85466d 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java @@ -623,7 +623,7 @@ abstract class MBeanIntrospector { } private static MBeanConstructorInfo[] findConstructors(Class c) { - Constructor[] cons = c.getConstructors(); + Constructor[] cons = c.getConstructors(); MBeanConstructorInfo[] mbc = new MBeanConstructorInfo[cons.length]; for (int i = 0; i < cons.length; i++) { String descr = "Public constructor of the MBean"; From 4e22cb6970b5fdb4ef67993cae4f5665bbcec98e Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Tue, 9 Sep 2008 17:01:45 +0200 Subject: [PATCH 81/95] 6745832: jmx namespaces: Some refactoring/commenting would improve code readability Reviewed-by: emcmanus --- .../DefaultMBeanServerInterceptor.java | 4 +- .../jmx/interceptor/DispatchInterceptor.java | 94 ++++---- .../DomainDispatchInterceptor.java | 82 +++++-- .../NamespaceDispatchInterceptor.java | 40 ++-- .../classes/com/sun/jmx/mbeanserver/Util.java | 15 +- .../sun/jmx/namespace/DomainInterceptor.java | 83 +++---- .../sun/jmx/namespace/HandlerInterceptor.java | 64 ++--- .../sun/jmx/namespace/JMXNamespaceUtils.java | 21 +- .../jmx/namespace/NamespaceInterceptor.java | 4 - .../jmx/namespace/RoutingConnectionProxy.java | 55 ++--- .../RoutingMBeanServerConnection.java | 218 ++++++++++-------- .../com/sun/jmx/namespace/RoutingProxy.java | 148 ++++++++++-- .../sun/jmx/namespace/RoutingServerProxy.java | 52 ++--- .../javax/management/namespace/JMXDomain.java | 12 +- .../management/namespace/JMXNamespace.java | 38 +-- .../management/namespace/JMXNamespaces.java | 6 +- .../namespace/JMXRemoteNamespace.java | 49 ++-- .../MBeanServerConnectionWrapper.java | 1 - .../javax/management/namespace/Wombat.java | 7 +- 19 files changed, 579 insertions(+), 414 deletions(-) diff --git a/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java b/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java index 7d95a77fde2..7faeb8727fb 100644 --- a/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java +++ b/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java @@ -2021,7 +2021,7 @@ public class DefaultMBeanServerInterceptor private void addJMXNamespace(JMXNamespace namespace, final ObjectName logicalName, final Queue postQueue) { - dispatcher.addNamespace(logicalName, namespace, postQueue); + dispatcher.addInterceptorFor(logicalName, namespace, postQueue); } /** @@ -2035,7 +2035,7 @@ public class DefaultMBeanServerInterceptor private void removeJMXNamespace(JMXNamespace namespace, final ObjectName logicalName, final Queue postQueue) { - dispatcher.removeNamespace(logicalName, namespace, postQueue); + dispatcher.removeInterceptorFor(logicalName, namespace, postQueue); } /** diff --git a/jdk/src/share/classes/com/sun/jmx/interceptor/DispatchInterceptor.java b/jdk/src/share/classes/com/sun/jmx/interceptor/DispatchInterceptor.java index 9e8625d1669..4a79567fed1 100644 --- a/jdk/src/share/classes/com/sun/jmx/interceptor/DispatchInterceptor.java +++ b/jdk/src/share/classes/com/sun/jmx/interceptor/DispatchInterceptor.java @@ -194,7 +194,7 @@ public abstract class DispatchInterceptor // found in the handlerMap. Note: there doesn't need to be an interceptor // for that key in the Map. // - public abstract String getHandlerKey(ObjectName name); + abstract String getHandlerKey(ObjectName name); // Returns an interceptor for that name, or null if there's no interceptor // for that name. @@ -277,7 +277,7 @@ public abstract class DispatchInterceptor // of JMXNamespace (or a subclass of it) is registered as an MBean. // This method is usually invoked from within the repository lock, // hence the necessity of the postRegisterQueue. - public void addNamespace(ObjectName name, N jmxNamespace, + public void addInterceptorFor(ObjectName name, N jmxNamespace, Queue postRegisterQueue) { final String key = getHandlerKey(name); validateHandlerNameFor(key,name); @@ -298,7 +298,7 @@ public abstract class DispatchInterceptor // of JMXNamespace (or a subclass of it) is deregistered. // This method is usually invoked from within the repository lock, // hence the necessity of the postDeregisterQueue. - public void removeNamespace(ObjectName name, N jmxNamespace, + public void removeInterceptorFor(ObjectName name, N jmxNamespace, Queue postDeregisterQueue) { final String key = getHandlerKey(name); final T ns; @@ -330,7 +330,7 @@ public abstract class DispatchInterceptor } // From MBeanServer - public ObjectInstance createMBean(String className, ObjectName name) + public final ObjectInstance createMBean(String className, ObjectName name) throws ReflectionException, InstanceAlreadyExistsException, MBeanRegistrationException, MBeanException, NotCompliantMBeanException { @@ -338,7 +338,7 @@ public abstract class DispatchInterceptor } // From MBeanServer - public ObjectInstance createMBean(String className, ObjectName name, + public final ObjectInstance createMBean(String className, ObjectName name, ObjectName loaderName) throws ReflectionException, InstanceAlreadyExistsException, MBeanRegistrationException, MBeanException, @@ -347,7 +347,7 @@ public abstract class DispatchInterceptor } // From MBeanServer - public ObjectInstance createMBean(String className, ObjectName name, + public final ObjectInstance createMBean(String className, ObjectName name, Object params[], String signature[]) throws ReflectionException, InstanceAlreadyExistsException, MBeanRegistrationException, MBeanException, @@ -357,7 +357,7 @@ public abstract class DispatchInterceptor } // From MBeanServer - public ObjectInstance createMBean(String className, ObjectName name, + public final ObjectInstance createMBean(String className, ObjectName name, ObjectName loaderName, Object params[], String signature[]) throws ReflectionException, InstanceAlreadyExistsException, @@ -368,42 +368,43 @@ public abstract class DispatchInterceptor } // From MBeanServer - public ObjectInstance registerMBean(Object object, ObjectName name) + public final ObjectInstance registerMBean(Object object, ObjectName name) throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException { return getInterceptorForCreate(name).registerMBean(object,name); } // From MBeanServer - public void unregisterMBean(ObjectName name) + public final void unregisterMBean(ObjectName name) throws InstanceNotFoundException, MBeanRegistrationException { getInterceptorForInstance(name).unregisterMBean(name); } // From MBeanServer - public ObjectInstance getObjectInstance(ObjectName name) + public final ObjectInstance getObjectInstance(ObjectName name) throws InstanceNotFoundException { return getInterceptorForInstance(name).getObjectInstance(name); } // From MBeanServer - public Set queryMBeans(ObjectName name, QueryExp query) { - final QueryInterceptor mbs = + public final Set queryMBeans(ObjectName name, + QueryExp query) { + final QueryInterceptor queryInvoker = getInterceptorForQuery(name); - if (mbs == null) return Collections.emptySet(); - else return mbs.queryMBeans(name,query); + if (queryInvoker == null) return Collections.emptySet(); + else return queryInvoker.queryMBeans(name,query); } // From MBeanServer - public Set queryNames(ObjectName name, QueryExp query) { - final QueryInterceptor mbs = + public final Set queryNames(ObjectName name, QueryExp query) { + final QueryInterceptor queryInvoker = getInterceptorForQuery(name); - if (mbs == null) return Collections.emptySet(); - else return mbs.queryNames(name,query); + if (queryInvoker == null) return Collections.emptySet(); + else return queryInvoker.queryNames(name,query); } // From MBeanServer - public boolean isRegistered(ObjectName name) { + public final boolean isRegistered(ObjectName name) { final MBeanServer mbs = getInterceptorOrNullFor(name); if (mbs == null) return false; else return mbs.isRegistered(name); @@ -415,20 +416,21 @@ public abstract class DispatchInterceptor } // From MBeanServer - public Object getAttribute(ObjectName name, String attribute) + public final Object getAttribute(ObjectName name, String attribute) throws MBeanException, AttributeNotFoundException, InstanceNotFoundException, ReflectionException { return getInterceptorForInstance(name).getAttribute(name,attribute); } // From MBeanServer - public AttributeList getAttributes(ObjectName name, String[] attributes) + public final AttributeList getAttributes(ObjectName name, + String[] attributes) throws InstanceNotFoundException, ReflectionException { return getInterceptorForInstance(name).getAttributes(name,attributes); } // From MBeanServer - public void setAttribute(ObjectName name, Attribute attribute) + public final void setAttribute(ObjectName name, Attribute attribute) throws InstanceNotFoundException, AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException { @@ -436,14 +438,14 @@ public abstract class DispatchInterceptor } // From MBeanServer - public AttributeList setAttributes(ObjectName name, + public final AttributeList setAttributes(ObjectName name, AttributeList attributes) throws InstanceNotFoundException, ReflectionException { return getInterceptorForInstance(name).setAttributes(name,attributes); } // From MBeanServer - public Object invoke(ObjectName name, String operationName, + public final Object invoke(ObjectName name, String operationName, Object params[], String signature[]) throws InstanceNotFoundException, MBeanException, ReflectionException { @@ -463,63 +465,69 @@ public abstract class DispatchInterceptor public abstract String[] getDomains(); // From MBeanServer - public void addNotificationListener(ObjectName name, + public final void addNotificationListener(ObjectName name, NotificationListener listener, NotificationFilter filter, Object handback) throws InstanceNotFoundException { - getInterceptorForInstance(name).addNotificationListener(name,listener,filter, + getInterceptorForInstance(name). + addNotificationListener(name,listener,filter, handback); } // From MBeanServer - public void addNotificationListener(ObjectName name, + public final void addNotificationListener(ObjectName name, ObjectName listener, NotificationFilter filter, Object handback) throws InstanceNotFoundException { - getInterceptorForInstance(name).addNotificationListener(name,listener,filter, + getInterceptorForInstance(name). + addNotificationListener(name,listener,filter, handback); } // From MBeanServer - public void removeNotificationListener(ObjectName name, + public final void removeNotificationListener(ObjectName name, ObjectName listener) throws InstanceNotFoundException, ListenerNotFoundException { - getInterceptorForInstance(name).removeNotificationListener(name,listener); + getInterceptorForInstance(name). + removeNotificationListener(name,listener); } // From MBeanServer - public void removeNotificationListener(ObjectName name, + public final void removeNotificationListener(ObjectName name, ObjectName listener, NotificationFilter filter, Object handback) throws InstanceNotFoundException, ListenerNotFoundException { - getInterceptorForInstance(name).removeNotificationListener(name,listener,filter, + getInterceptorForInstance(name). + removeNotificationListener(name,listener,filter, handback); } // From MBeanServer - public void removeNotificationListener(ObjectName name, + public final void removeNotificationListener(ObjectName name, NotificationListener listener) throws InstanceNotFoundException, ListenerNotFoundException { - getInterceptorForInstance(name).removeNotificationListener(name,listener); + getInterceptorForInstance(name). + removeNotificationListener(name,listener); } // From MBeanServer - public void removeNotificationListener(ObjectName name, + public final void removeNotificationListener(ObjectName name, NotificationListener listener, NotificationFilter filter, Object handback) throws InstanceNotFoundException, ListenerNotFoundException { - getInterceptorForInstance(name).removeNotificationListener(name,listener,filter, + getInterceptorForInstance(name). + removeNotificationListener(name,listener,filter, handback); } // From MBeanServer - public MBeanInfo getMBeanInfo(ObjectName name) + public final MBeanInfo getMBeanInfo(ObjectName name) throws InstanceNotFoundException, IntrospectionException, ReflectionException { return getInterceptorForInstance(name).getMBeanInfo(name); @@ -527,21 +535,23 @@ public abstract class DispatchInterceptor // From MBeanServer - public boolean isInstanceOf(ObjectName name, String className) + public final boolean isInstanceOf(ObjectName name, String className) throws InstanceNotFoundException { return getInterceptorForInstance(name).isInstanceOf(name,className); } // From MBeanServer - public ClassLoader getClassLoaderFor(ObjectName mbeanName) + public final ClassLoader getClassLoaderFor(ObjectName mbeanName) throws InstanceNotFoundException { - return getInterceptorForInstance(mbeanName).getClassLoaderFor(mbeanName); + return getInterceptorForInstance(mbeanName). + getClassLoaderFor(mbeanName); } // From MBeanServer - public ClassLoader getClassLoader(ObjectName loaderName) + public final ClassLoader getClassLoader(ObjectName loaderName) throws InstanceNotFoundException { - return getInterceptorForInstance(loaderName).getClassLoader(loaderName); + return getInterceptorForInstance(loaderName). + getClassLoader(loaderName); } } diff --git a/jdk/src/share/classes/com/sun/jmx/interceptor/DomainDispatchInterceptor.java b/jdk/src/share/classes/com/sun/jmx/interceptor/DomainDispatchInterceptor.java index cb1489ee500..9b9b1d6b19c 100644 --- a/jdk/src/share/classes/com/sun/jmx/interceptor/DomainDispatchInterceptor.java +++ b/jdk/src/share/classes/com/sun/jmx/interceptor/DomainDispatchInterceptor.java @@ -75,7 +75,7 @@ class DomainDispatchInterceptor private final DomainDispatchInterceptor parent; AggregatingQueryInterceptor(DomainDispatchInterceptor dispatcher) { - super(dispatcher.localNamespace); + super(dispatcher.nextInterceptor); parent = dispatcher; } @@ -91,9 +91,8 @@ class DomainDispatchInterceptor // Add all matching MBeans from local namespace. final Set res = Util.cloneSet(local); - final boolean all = (pattern == null || - pattern.getDomain().equals("*")); if (pattern == null) pattern = ObjectName.WILDCARD; + final boolean all = pattern.getDomain().equals("*"); final String domain = pattern.getDomain(); @@ -142,7 +141,7 @@ class DomainDispatchInterceptor } } - private final DefaultMBeanServerInterceptor localNamespace; + private final DefaultMBeanServerInterceptor nextInterceptor; private final String mbeanServerName; private final MBeanServerDelegate delegate; @@ -165,7 +164,7 @@ class DomainDispatchInterceptor MBeanInstantiator instantiator, Repository repository, NamespaceDispatchInterceptor namespaces) { - localNamespace = new DefaultMBeanServerInterceptor(outer, + nextInterceptor = new DefaultMBeanServerInterceptor(outer, delegate, instantiator,repository,namespaces); mbeanServerName = Util.getMBeanServerSecurityName(delegate); this.delegate = delegate; @@ -182,7 +181,7 @@ class DomainDispatchInterceptor @Override void validateHandlerNameFor(String key, ObjectName name) { super.validateHandlerNameFor(key,name); - final String[] domains = localNamespace.getDomains(); + final String[] domains = nextInterceptor.getDomains(); for (int i=0;i postRegisterQueue) { if (handler instanceof JMXDomain) - localNamespace.addNamespace(name, + nextInterceptor.addInterceptorFor(name, (JMXDomain)handler,postRegisterQueue); - else super.addNamespace(name,handler,postRegisterQueue); + else super.addInterceptorFor(name,handler,postRegisterQueue); } @Override - public void removeNamespace(ObjectName name, JMXNamespace handler, + public void removeInterceptorFor(ObjectName name, JMXNamespace handler, Queue postDeregisterQueue) { if (handler instanceof JMXDomain) - localNamespace.removeNamespace(name,(JMXDomain)handler, + nextInterceptor.removeInterceptorFor(name,(JMXDomain)handler, postDeregisterQueue); - else super.removeNamespace(name,handler,postDeregisterQueue); + else super.removeInterceptorFor(name,handler,postDeregisterQueue); } diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java index fcbdd904133..93c5c97f646 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java @@ -57,7 +57,8 @@ import static javax.management.namespace.JMXNamespaces.NAMESPACE_SEPARATOR; public class Util { private final static int NAMESPACE_SEPARATOR_LENGTH = NAMESPACE_SEPARATOR.length(); - public final static String ILLEGAL_MBEANSERVER_NAME_CHARS=";:*?"; + public final static char[] ILLEGAL_MBEANSERVER_NAME_CHARS=";:*?". + toCharArray(); static Map newMap() { @@ -621,7 +622,7 @@ public class Util { * is {@code null}. * @throws IllegalArgumentException if mbeanServerName contains illegal * characters, or is empty, or is {@code "-"}. - * Illegal characters are {@value #ILLEGAL_MBEANSERVER_NAME_CHARS}. + * Illegal characters are {@link #ILLEGAL_MBEANSERVER_NAME_CHARS}. */ public static String checkServerName(String mbeanServerName) { if ("".equals(mbeanServerName)) @@ -632,7 +633,7 @@ public class Util { "\"-\" is not a valid MBean server name"); if (isMBeanServerNameUndefined(mbeanServerName)) return MBeanServerFactory.DEFAULT_MBEANSERVER_NAME; - for (char c : ILLEGAL_MBEANSERVER_NAME_CHARS.toCharArray()) { + for (char c : ILLEGAL_MBEANSERVER_NAME_CHARS) { if (mbeanServerName.indexOf(c) >= 0) throw new IllegalArgumentException( "invalid character in MBeanServer name: "+c); @@ -662,15 +663,15 @@ public class Util { } // Log the exception and its causes without logging the stack trace. - // Use with care - it is usally preferable to log the whole stack trace! + // Use with care - it is usually preferable to log the whole stack trace! // We don't want to log the whole stack trace here: logshort() is // called in those cases where the exception might not be abnormal. private static void logshort(String msg, Throwable t) { if (JmxProperties.MISC_LOGGER.isLoggable(Level.FINE)) { StringBuilder toprint = new StringBuilder(msg); - toprint.append("\nCaused By: ").append(String.valueOf(t)); - while ((t=t.getCause())!=null) - toprint.append("\nCaused By: ").append(String.valueOf(t)); + do { + toprint.append("\nCaused By: ").append(String.valueOf(t)); + } while ((t=t.getCause())!=null); JmxProperties.MISC_LOGGER.fine(toprint.toString()); } } diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/DomainInterceptor.java b/jdk/src/share/classes/com/sun/jmx/namespace/DomainInterceptor.java index d7619814d79..84644d831a5 100644 --- a/jdk/src/share/classes/com/sun/jmx/namespace/DomainInterceptor.java +++ b/jdk/src/share/classes/com/sun/jmx/namespace/DomainInterceptor.java @@ -85,7 +85,7 @@ public class DomainInterceptor extends HandlerInterceptor { final ObjectName pattern; public PatternNotificationFilter(ObjectName pattern) { - this.pattern = pattern; + this.pattern = pattern==null?ObjectName.WILDCARD:pattern; } public boolean isNotificationEnabled(Notification notification) { @@ -93,7 +93,7 @@ public class DomainInterceptor extends HandlerInterceptor { return false; final MBeanServerNotification mbsn = (MBeanServerNotification) notification; - if (pattern == null || pattern.apply(mbsn.getMBeanName())) + if (pattern.apply(mbsn.getMBeanName())) return true; return false; } @@ -110,6 +110,7 @@ public class DomainInterceptor extends HandlerInterceptor { super(handler); this.domainName = domainName; this.serverName = serverName; + ALL = Util.newObjectName(domainName+":*"); } @Override @@ -118,27 +119,27 @@ public class DomainInterceptor extends HandlerInterceptor { ", domain="+this.domainName+")"; } - public void connectDelegate(final MBeanServerDelegate delegate) + final void connectDelegate(final MBeanServerDelegate delegate) throws InstanceNotFoundException { final NotificationFilter filter = new PatternNotificationFilter(getPatternFor(null)); synchronized (this) { - if (mbsListener == null) + if (mbsListener == null) { mbsListener = new NotificationListener() { - - public void handleNotification(Notification notification, - Object handback) { - if (filter.isNotificationEnabled(notification)) - delegate.sendNotification(notification); - } - }; + public void handleNotification(Notification notification, + Object handback) { + if (filter.isNotificationEnabled(notification)) + delegate.sendNotification(notification); + } + }; + } } - getNamespace(). + getHandlerInterceptorMBean(). addMBeanServerNotificationListener(mbsListener, filter); } - public void disconnectDelegate() + final void disconnectDelegate() throws InstanceNotFoundException, ListenerNotFoundException { final NotificationListener l; synchronized (this) { @@ -146,10 +147,10 @@ public class DomainInterceptor extends HandlerInterceptor { if (l == null) return; mbsListener = null; } - getNamespace().removeMBeanServerNotificationListener(l); + getHandlerInterceptorMBean().removeMBeanServerNotificationListener(l); } - public void addPostRegisterTask(Queue queue, + public final void addPostRegisterTask(Queue queue, final MBeanServerDelegate delegate) { if (queue == null) throw new IllegalArgumentException("task queue must not be null"); @@ -158,14 +159,15 @@ public class DomainInterceptor extends HandlerInterceptor { try { connectDelegate(delegate); } catch (Exception x) { - throw new UnsupportedOperationException("notification forwarding",x); + throw new UnsupportedOperationException( + "notification forwarding",x); } } }; queue.add(task1); } - public void addPostDeregisterTask(Queue queue, + public final void addPostDeregisterTask(Queue queue, final MBeanServerDelegate delegate) { if (queue == null) throw new IllegalArgumentException("task queue must not be null"); @@ -174,17 +176,18 @@ public class DomainInterceptor extends HandlerInterceptor { try { disconnectDelegate(); } catch (Exception x) { - throw new UnsupportedOperationException("notification forwarding",x); + throw new UnsupportedOperationException( + "notification forwarding",x); } } }; queue.add(task1); } - /** - * Throws IllegalArgumentException if targetName.getDomain() is not - * in the domain handled. - **/ + // No name conversion for JMXDomains... + // Throws IllegalArgumentException if targetName.getDomain() is not + // in the domain handled. + // @Override protected ObjectName toSource(ObjectName targetName) { if (targetName == null) return null; @@ -198,6 +201,7 @@ public class DomainInterceptor extends HandlerInterceptor { return targetName; } + // No name conversion for JMXDomains... @Override protected ObjectName toTarget(ObjectName sourceName) { return sourceName; @@ -255,16 +259,16 @@ public class DomainInterceptor extends HandlerInterceptor { if (LOG.isLoggable(Level.FINE)) LOG.fine("Unexpected exception raised in queryNames: "+x); LOG.log(Level.FINEST,"Unexpected exception raised in queryNames",x); + return Collections.emptySet(); } - // We reach here only when an exception was raised. - // - final Set empty = Collections.emptySet(); - return empty; } + // Compute a new pattern which is a sub pattern of 'name' but only selects + // the MBeans in domain 'domainName' + // When we reach here, it has been verified that 'name' matches our domain + // name (done by DomainDispatchInterceptor) private ObjectName getPatternFor(final ObjectName name) { try { - if (ALL == null) ALL = ObjectName.getInstance(domainName + ":*"); if (name == null) return ALL; if (name.getDomain().equals(domainName)) return name; return name.withDomain(domainName); @@ -284,11 +288,8 @@ public class DomainInterceptor extends HandlerInterceptor { if (LOG.isLoggable(Level.FINE)) LOG.fine("Unexpected exception raised in queryNames: "+x); LOG.log(Level.FINEST,"Unexpected exception raised in queryNames",x); + return Collections.emptySet(); } - // We reach here only when an exception was raised. - // - final Set empty = Collections.emptySet(); - return empty; } @Override @@ -306,7 +307,7 @@ public class DomainInterceptor extends HandlerInterceptor { // in the domain. @Override public Integer getMBeanCount() { - return getNamespace().getMBeanCount(); + return getHandlerInterceptorMBean().getMBeanCount(); } private boolean checkOn() { @@ -320,8 +321,8 @@ public class DomainInterceptor extends HandlerInterceptor { @Override void check(ObjectName routingName, String member, String action) { if (!checkOn()) return; - final String act = (action==null)?"-":action.intern(); - if(act == "queryMBeans" || act == "queryNames") { // ES: OK + final String act = (action==null)?"-":action; + if("queryMBeans".equals(act) || "queryNames".equals(act)) { // This is tricky. check with 3 parameters is called // by queryNames/queryMBeans before performing the query. // At this point we must check with no class name. @@ -355,16 +356,8 @@ public class DomainInterceptor extends HandlerInterceptor { if (!checkOn()) return; final MBeanPermission perm; - // action is most probably already an intern string. - // string literals are intern strings. - // we create a new intern string for 'action' - just to be on - // the safe side... - // We intern it in order to be able to use == rather than equals - // below, because if we don't, and if action is not one of the - // 4 literals below, we would have to do a full string comparison. - // - final String act = (action==null)?"-":action.intern(); - if (act == "getDomains") { // ES: OK + final String act = (action==null)?"-":action; + if ("getDomains".equals(act)) { // ES: OK perm = new MBeanPermission(serverName,"-",member, routingName,act); } else { @@ -381,7 +374,7 @@ public class DomainInterceptor extends HandlerInterceptor { String getClassName(ObjectName routingName) { if (routingName == null || routingName.isPattern()) return "-"; try { - return getNamespace().getSourceServer(). + return getHandlerInterceptorMBean().getSourceServer(). getObjectInstance(routingName).getClassName(); } catch (InstanceNotFoundException ex) { LOG.finest("Can't get class name for "+routingName+ diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/HandlerInterceptor.java b/jdk/src/share/classes/com/sun/jmx/namespace/HandlerInterceptor.java index eb48ef84995..7c2f3934859 100644 --- a/jdk/src/share/classes/com/sun/jmx/namespace/HandlerInterceptor.java +++ b/jdk/src/share/classes/com/sun/jmx/namespace/HandlerInterceptor.java @@ -63,8 +63,8 @@ import javax.management.namespace.JMXNamespace; /** * This interceptor wraps a JMXNamespace, and performs * {@code ObjectName} rewriting. {@code HandlerInterceptor} are - * usually created and managed by a {@link NamespaceDispatcher} or - * {@link DomainDispatcher}. + * created and managed by a {@link NamespaceDispatchInterceptor} or a + * {@link DomainDispatchInterceptor}. *

* This API is a Sun internal API and is subject to changes without notice. *

@@ -90,6 +90,12 @@ public abstract class HandlerInterceptor this.handler = handler; } + // + // The {@code source} connection is a connection to the MBeanServer + // that contains the actual MBeans. + // In the case of cascading, that would be a connection to the sub + // agent. Practically, this is JMXNamespace.getSourceServer(); + // @Override protected MBeanServer source() { return handler.getSourceServer(); @@ -105,7 +111,9 @@ public abstract class HandlerInterceptor return source(); } - T getNamespace() { + // The namespace or domain handler - this either a JMXNamespace or a + // a JMXDomain + T getHandlerInterceptorMBean() { return handler; } @@ -122,7 +130,7 @@ public abstract class HandlerInterceptor Util.newRuntimeIOException(x)); } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public AttributeList getAttributes(ObjectName name, String[] attributes) throws InstanceNotFoundException, ReflectionException { @@ -172,7 +180,7 @@ public abstract class HandlerInterceptor } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public void removeNotificationListener(ObjectName name, ObjectName listener) throws InstanceNotFoundException, ListenerNotFoundException { @@ -183,7 +191,7 @@ public abstract class HandlerInterceptor } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public String getDefaultDomain() { try { @@ -193,7 +201,7 @@ public abstract class HandlerInterceptor } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public String[] getDomains() { try { @@ -203,7 +211,7 @@ public abstract class HandlerInterceptor } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public Integer getMBeanCount() { try { @@ -213,7 +221,7 @@ public abstract class HandlerInterceptor } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public void setAttribute(ObjectName name, Attribute attribute) throws InstanceNotFoundException, AttributeNotFoundException, @@ -226,7 +234,7 @@ public abstract class HandlerInterceptor } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public Set queryNames(ObjectName name, QueryExp query) { try { @@ -236,7 +244,7 @@ public abstract class HandlerInterceptor } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public Set queryMBeans(ObjectName name, QueryExp query) { try { @@ -246,7 +254,7 @@ public abstract class HandlerInterceptor } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public boolean isInstanceOf(ObjectName name, String className) throws InstanceNotFoundException { @@ -257,7 +265,7 @@ public abstract class HandlerInterceptor } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public ObjectInstance createMBean(String className, ObjectName name) throws ReflectionException, InstanceAlreadyExistsException, @@ -270,7 +278,7 @@ public abstract class HandlerInterceptor } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public ObjectInstance createMBean(String className, ObjectName name, ObjectName loaderName) @@ -284,7 +292,7 @@ public abstract class HandlerInterceptor } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public Object getAttribute(ObjectName name, String attribute) throws MBeanException, AttributeNotFoundException, @@ -296,7 +304,7 @@ public abstract class HandlerInterceptor } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public void removeNotificationListener(ObjectName name, ObjectName listener, NotificationFilter filter, Object handback) @@ -309,7 +317,7 @@ public abstract class HandlerInterceptor } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public void removeNotificationListener(ObjectName name, NotificationListener listener, NotificationFilter filter, @@ -323,7 +331,7 @@ public abstract class HandlerInterceptor } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public void removeNotificationListener(ObjectName name, NotificationListener listener) @@ -336,7 +344,7 @@ public abstract class HandlerInterceptor } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public void addNotificationListener(ObjectName name, NotificationListener listener, NotificationFilter filter, @@ -349,7 +357,7 @@ public abstract class HandlerInterceptor } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public void addNotificationListener(ObjectName name, ObjectName listener, NotificationFilter filter, Object handback) @@ -362,7 +370,7 @@ public abstract class HandlerInterceptor } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public boolean isRegistered(ObjectName name) { try { @@ -372,7 +380,7 @@ public abstract class HandlerInterceptor } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public void unregisterMBean(ObjectName name) throws InstanceNotFoundException, MBeanRegistrationException { @@ -383,7 +391,7 @@ public abstract class HandlerInterceptor } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public MBeanInfo getMBeanInfo(ObjectName name) throws InstanceNotFoundException, IntrospectionException, @@ -395,7 +403,7 @@ public abstract class HandlerInterceptor } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public ObjectInstance getObjectInstance(ObjectName name) throws InstanceNotFoundException { @@ -406,7 +414,7 @@ public abstract class HandlerInterceptor } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public ObjectInstance createMBean(String className, ObjectName name, Object[] params, String[] signature) @@ -421,7 +429,7 @@ public abstract class HandlerInterceptor } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public ObjectInstance createMBean(String className, ObjectName name, ObjectName loaderName, Object[] params, String[] signature) @@ -437,7 +445,7 @@ public abstract class HandlerInterceptor } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public AttributeList setAttributes(ObjectName name,AttributeList attributes) throws InstanceNotFoundException, ReflectionException { @@ -448,7 +456,7 @@ public abstract class HandlerInterceptor } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public Object invoke(ObjectName name, String operationName, Object[] params, String[] signature) diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/JMXNamespaceUtils.java b/jdk/src/share/classes/com/sun/jmx/namespace/JMXNamespaceUtils.java index 1fccfcbc76e..49f875144f2 100644 --- a/jdk/src/share/classes/com/sun/jmx/namespace/JMXNamespaceUtils.java +++ b/jdk/src/share/classes/com/sun/jmx/namespace/JMXNamespaceUtils.java @@ -29,7 +29,6 @@ import com.sun.jmx.defaults.JmxProperties; import java.io.IOException; import java.util.Collections; -import java.util.HashMap; import java.util.Map; import java.util.WeakHashMap; import java.util.logging.Level; @@ -40,6 +39,8 @@ import javax.management.MBeanServerConnection; import javax.management.NotificationFilter; import javax.management.NotificationListener; import javax.management.event.EventClient; +import javax.management.event.EventClientDelegateMBean; +import javax.management.namespace.JMXNamespace; import javax.management.namespace.JMXNamespaces; import javax.management.remote.JMXAddressable; import javax.management.remote.JMXConnector; @@ -66,26 +67,10 @@ public final class JMXNamespaceUtils { return new WeakHashMap(); } - /** Creates a new instance of JMXNamespaces */ + /** There are no instances of this class */ private JMXNamespaceUtils() { } - /** - * Returns an unmodifiable option map in which the given keys have been - * filtered out. - * @param keys keys to filter out from the map. - * @return An unmodifiable option map in which the given keys have been - * filtered out. - */ - public static Map filterMap(Map map, K... keys) { - final Map filtered; - filtered=new HashMap(map); - for (K key : keys) { - filtered.remove(key); - } - return unmodifiableMap(filtered); - } - // returns un unmodifiable view of a map. public static Map unmodifiableMap(Map aMap) { if (aMap == null || aMap.isEmpty()) diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java b/jdk/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java index da85fc6d4ae..11afeb2afc1 100644 --- a/jdk/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java +++ b/jdk/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java @@ -54,10 +54,6 @@ import javax.management.namespace.JMXNamespacePermission; */ public class NamespaceInterceptor extends HandlerInterceptor { - /** - * A logger for this class. - **/ - private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER; private static final Logger PROBE_LOG = Logger.getLogger( JmxProperties.NAMESPACE_LOGGER+".probe"); diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingConnectionProxy.java b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingConnectionProxy.java index 787343eec4c..443c80f2ae5 100644 --- a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingConnectionProxy.java +++ b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingConnectionProxy.java @@ -45,6 +45,9 @@ import javax.management.namespace.JMXNamespaces; *

* @since 1.7 */ +// See class hierarchy and detailled explanations in RoutingProxy in this +// package. +// public class RoutingConnectionProxy extends RoutingProxy { @@ -93,40 +96,28 @@ public class RoutingConnectionProxy targetNs+"\", "+forwardsContext+")"; } + static final RoutingProxyFactory + + FACTORY = new RoutingProxyFactory + () { + + public RoutingConnectionProxy newInstance(MBeanServerConnection source, + String sourcePath, String targetPath, + boolean forwardsContext) { + return new RoutingConnectionProxy(source,sourcePath, + targetPath,forwardsContext); + } + + public RoutingConnectionProxy newInstance( + MBeanServerConnection source, String sourcePath) { + return new RoutingConnectionProxy(source,sourcePath); + } + }; + public static MBeanServerConnection cd(MBeanServerConnection source, String sourcePath) { - if (source == null) throw new IllegalArgumentException("null"); - if (source.getClass().equals(RoutingConnectionProxy.class)) { - // cast is OK here, but findbugs complains unless we use class.cast - final RoutingConnectionProxy other = - RoutingConnectionProxy.class.cast(source); - final String target = other.getTargetNamespace(); - - // Avoid multiple layers of serialization. - // - // We construct a new proxy from the original source instead of - // stacking a new proxy on top of the old one. - // - that is we replace - // cd ( cd ( x, dir1), dir2); - // by - // cd (x, dir1//dir2); - // - // We can do this only when the source class is exactly - // NamespaceConnectionProxy. - // - if (target == null || target.equals("")) { - final String path = - JMXNamespaces.concat(other.getSourceNamespace(), - sourcePath); - return new RoutingConnectionProxy(other.source(),path,"", - other.forwardsContext); - } - // Note: we could do possibly something here - but it would involve - // removing part of targetDir, and possibly adding - // something to sourcePath. - // Too complex to bother! => simply default to stacking... - } - return new RoutingConnectionProxy(source,sourcePath); + return RoutingProxy.cd(RoutingConnectionProxy.class, FACTORY, + source, sourcePath); } } diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingMBeanServerConnection.java b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingMBeanServerConnection.java index 904e5848e8f..70df9b504dd 100644 --- a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingMBeanServerConnection.java +++ b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingMBeanServerConnection.java @@ -83,18 +83,32 @@ public abstract class RoutingMBeanServerConnection//}. - * @param attributes The list of attributes to check permission for. - * @param action one of "getAttribute" or "setAttribute" - * @return The list of attributes for which the callers has the - * appropriate {@link - * javax.management.namespace.JMXNamespacePermission}. - */ - String[] checkAttributes(ObjectName routingName, - String[] attributes, String action) { - check(routingName,null,action); - return attributes; - } - - /** - * This method is a hook to implement permission checking in subclasses. - * By default, this method does nothing and simply returns - * {@code attribute}. - * - * @param routingName The name of the MBean in the enclosing context. - * This is of the form {@code //}. - * @param attributes The list of attributes to check permission for. - * @param action one of "getAttribute" or "setAttribute" - * @return The list of attributes for which the callers has the - * appropriate {@link - * javax.management.namespace.JMXNamespacePermission}. - */ - AttributeList checkAttributes(ObjectName routingName, - AttributeList attributes, String action) { - check(routingName,null,action); - return attributes; - } - // from MBeanServerConnection public AttributeList getAttributes(ObjectName name, String[] attributes) throws InstanceNotFoundException, ReflectionException, IOException { @@ -195,37 +171,6 @@ public abstract class RoutingMBeanServerConnection//}. - * @param member The {@link - * javax.management.namespace.JMXNamespacePermission#getMember member} - * name. - * @param action The {@link - * javax.management.namespace.JMXNamespacePermission#getActions action} - * name. - */ - void check(ObjectName routingName, - String member, String action) { - } - - void checkPattern(ObjectName routingPattern, - String member, String action) { - // pattern is checked only at posteriori by checkQuery. - // checking it a priori usually doesn't work, because ObjectName.apply - // does not work between two patterns. - check(null,null,action); - } - - void checkCreate(ObjectName routingName, String className, - String action) { - } - // from MBeanServerConnection public Object invoke(ObjectName name, String operationName, Object[] params, String[] signature) @@ -446,24 +391,6 @@ public abstract class RoutingMBeanServerConnection//}. - * @param action one of "queryNames" or "queryMBeans" - * @return true if {@code sourceName} can be returned. - */ - boolean checkQuery(ObjectName routingName, String action) { - return true; - } // Return names in the target's context. ObjectInstance processOutputInstance(ObjectInstance source) { @@ -643,6 +570,111 @@ public abstract class RoutingMBeanServerConnection//}. + * @param attributes The list of attributes to check permission for. + * @param action one of "getAttribute" or "setAttribute" + * @return The list of attributes for which the callers has the + * appropriate {@link + * javax.management.namespace.JMXNamespacePermission}. + */ + String[] checkAttributes(ObjectName routingName, + String[] attributes, String action) { + check(routingName,null,action); + return attributes; + } + + /** + * This method is a hook to implement permission checking in subclasses. + * By default, this method does nothing and simply returns + * {@code attribute}. + * + * @param routingName The name of the MBean in the enclosing context. + * This is of the form {@code //}. + * @param attributes The list of attributes to check permission for. + * @param action one of "getAttribute" or "setAttribute" + * @return The list of attributes for which the callers has the + * appropriate {@link + * javax.management.namespace.JMXNamespacePermission}. + */ + AttributeList checkAttributes(ObjectName routingName, + AttributeList attributes, String action) { + check(routingName,null,action); + return attributes; + } + + /** + * This method is a hook to implement permission checking in subclasses. + * By default, this method does nothing. + * A subclass may override this method and throw a {@link + * SecurityException} if the permission is denied. + * + * @param routingName The name of the MBean in the enclosing context. + * This is of the form {@code //}. + * @param member The {@link + * javax.management.namespace.JMXNamespacePermission#getMember member} + * name. + * @param action The {@link + * javax.management.namespace.JMXNamespacePermission#getActions action} + * name. + */ + void check(ObjectName routingName, + String member, String action) { + } + + // called in createMBean and registerMBean + void checkCreate(ObjectName routingName, String className, + String action) { + } + + // A priori check for queryNames/queryMBeans/ + void checkPattern(ObjectName routingPattern, + String member, String action) { + // pattern is checked only at posteriori by checkQuery. + // checking it a priori usually doesn't work, because ObjectName.apply + // does not work between two patterns. + // We only check that we have the permission requested for 'action'. + check(null,null,action); + } + + + /** + * This is a hook to implement permission checking in subclasses. + * + * Checks that the caller has sufficient permission for returning + * information about {@code sourceName} in {@code action}. + * + * By default always return true. Subclass may override this method + * and return false if the caller doesn't have sufficient permissions. + * + * @param routingName The name of the MBean to include or exclude from + * the query, expressed in the enclosing context. + * This is of the form {@code //}. + * @param action one of "queryNames" or "queryMBeans" + * @return true if {@code sourceName} can be returned. + */ + boolean checkQuery(ObjectName routingName, String action) { + return true; + } + /** * This method is a hook to implement permission checking in subclasses. * Checks that the caller as the necessary permissions to view the @@ -658,14 +690,4 @@ public abstract class RoutingMBeanServerConnection{@link RoutingConnectionProxy}: to cd in an MBeanServerConnection.

- *

{@link RoutingServerProxy}: to cd in an MBeanServer.

+ *

{@link RoutingConnectionProxy}: to narrow down into an + * MBeanServerConnection.

+ *

{@link RoutingServerProxy}: to narrow down into an MBeanServer.

*

* This API is a Sun internal API and is subject to changes without notice. *

* @since 1.7 */ +// +// RoutingProxies are client side objects which are used to narrow down +// into a namespace. They are used to perform ObjectName translation, +// adding the namespace to the routing ObjectName before sending it over +// to the source connection, and removing that prefix from results of +// queries, createMBean, registerMBean, and getObjectInstance. +// This translation is the opposite to that which is performed by +// NamespaceInterceptors. +// +// There is however a special case where routing proxies are used on the +// 'server' side to remove a namespace - rather than to add it: +// This the case of ClientContext. +// When an ObjectName like "jmx.context//c1=v1,c2=v2//D:k=v" reaches the +// jmx.context namespace, a routing proxy is used to remove the prefix +// c1=v1,c2=v2// from the routing objectname. +// +// For a RoutingProxy used in a narrowDownToNamespace operation, we have: +// targetNs="" // targetNS is the namespace 'to remove' +// sourceNS= // namespace 'to add' +// +// For a RoutingProxy used in a ClientContext operation, we have: +// targetNs= // context must be removed from object name +// sourceNs="" // nothing to add... +// +// RoutingProxies can also be used on the client side to implement +// "withClientContext" operations. In that case, the boolean parameter +// 'forwards context' is set to true, targetNs is "", and sourceNS may +// also be "". When forwardsContext is true, the RoutingProxy dynamically +// creates an ObjectNameRouter for each operation - in order to dynamically add +// the context attached to the thread to the routing ObjectName. This is +// performed in the getObjectNameRouter() method. +// +// Finally, in order to avoid too many layers of wrapping, +// RoutingConnectionProxy and RoutingServerProxy can be created through a +// factory method that can concatenate namespace pathes in order to +// return a single RoutingProxy - rather than wrapping a RoutingProxy inside +// another RoutingProxy. See RoutingConnectionProxy.cd and +// RoutingServerProxy.cd +// +// The class hierarchy is as follows: +// +// RoutingMBeanServerConnection +// [abstract class for all routing interceptors, +// such as RoutingProxies and HandlerInterceptors] +// / \ +// / \ +// RoutingProxy HandlerInterceptor +// [base class for [base class for server side +// client-side objects used objects, created by +// in narrowDownTo] DispatchInterceptors] +// / \ | \ +// RoutingConnectionProxy \ | NamespaceInterceptor +// [wraps MBeanServerConnection \ | [used to remove +// objects] \ | namespace prefix and +// RoutingServerProxy | wrap JMXNamespace] +// [wraps MBeanServer | +// Objects] | +// DomainInterceptor +// [used to wrap JMXDomain] +// +// RoutingProxies also differ from HandlerInterceptors in that they transform +// calls to MBeanServerConnection operations that do not have any parameters +// into a call to the underlying JMXNamespace MBean. +// So for instance a call to: +// JMXNamespaces.narrowDownToNamespace(conn,"foo").getDomains() +// is transformed into +// conn.getAttribute("foo//type=JMXNamespace","Domains"); +// public abstract class RoutingProxy extends RoutingMBeanServerConnection { @@ -179,17 +245,11 @@ public abstract class RoutingProxy throw x; } catch (MBeanException ex) { throw new IOException("Failed to get "+attributeName+": "+ - ex.getMessage(), + ex, ex.getTargetException()); - } catch (AttributeNotFoundException ex) { + } catch (Exception ex) { throw new IOException("Failed to get "+attributeName+": "+ - ex.getMessage(),ex); - } catch (InstanceNotFoundException ex) { - throw new IOException("Failed to get "+attributeName+": "+ - ex.getMessage(),ex); - } catch (ReflectionException ex) { - throw new IOException("Failed to get "+attributeName+": "+ - ex.getMessage(),ex); + ex,ex); } } @@ -279,4 +339,62 @@ public abstract class RoutingProxy (" mounted on targetNs="+targetNs)); } + // Creates an instance of a subclass 'R' of RoutingProxy + // RoutingServerProxy and RoutingConnectionProxy have their own factory + // instance. + static interface RoutingProxyFactory> { + R newInstance(T source, + String sourcePath, String targetPath, + boolean forwardsContext); + R newInstance(T source, + String sourcePath); + } + + // Performs a narrowDownToNamespace operation. + // This method will attempt to merge two RoutingProxies in a single + // one if they are of the same class. + // + // This method is never called directly - it should be called only by + // subclasses of RoutingProxy. + // + // As for now it is called by: + // RoutingServerProxy.cd and RoutingConnectionProxy.cd. + // + static > + R cd(Class routingProxyClass, + RoutingProxyFactory factory, + T source, String sourcePath) { + if (source == null) throw new IllegalArgumentException("null"); + if (source.getClass().equals(routingProxyClass)) { + // cast is OK here, but findbugs complains unless we use class.cast + final R other = routingProxyClass.cast(source); + final String target = other.getTargetNamespace(); + + // Avoid multiple layers of serialization. + // + // We construct a new proxy from the original source instead of + // stacking a new proxy on top of the old one. + // - that is we replace + // cd ( cd ( x, dir1), dir2); + // by + // cd (x, dir1//dir2); + // + // We can do this only when the source class is exactly + // RoutingServerProxy. + // + if (target == null || target.equals("")) { + final String path = + JMXNamespaces.concat(other.getSourceNamespace(), + sourcePath); + return factory.newInstance(other.source(),path,"", + other.forwardsContext); + } + // Note: we could do possibly something here - but it would involve + // removing part of targetDir, and possibly adding + // something to sourcePath. + // Too complex to bother! => simply default to stacking... + } + return factory.newInstance(source,sourcePath); + } } diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingServerProxy.java b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingServerProxy.java index 94aa139dd7a..f58e39816d3 100644 --- a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingServerProxy.java +++ b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingServerProxy.java @@ -69,6 +69,9 @@ import javax.management.namespace.JMXNamespaces; * * @since 1.7 */ +// See class hierarchy and detailled explanations in RoutingProxy in this +// package. +// public class RoutingServerProxy extends RoutingProxy implements MBeanServer { @@ -564,39 +567,24 @@ public class RoutingServerProxy } } + static final RoutingProxyFactory + FACTORY = new RoutingProxyFactory() { + + public RoutingServerProxy newInstance(MBeanServer source, + String sourcePath, String targetPath, + boolean forwardsContext) { + return new RoutingServerProxy(source,sourcePath, + targetPath,forwardsContext); + } + + public RoutingServerProxy newInstance( + MBeanServer source, String sourcePath) { + return new RoutingServerProxy(source,sourcePath); + } + }; public static MBeanServer cd(MBeanServer source, String sourcePath) { - if (source == null) throw new IllegalArgumentException("null"); - if (source.getClass().equals(RoutingServerProxy.class)) { - // cast is OK here, but findbugs complains unless we use class.cast - final RoutingServerProxy other = - RoutingServerProxy.class.cast(source); - final String target = other.getTargetNamespace(); - - // Avoid multiple layers of serialization. - // - // We construct a new proxy from the original source instead of - // stacking a new proxy on top of the old one. - // - that is we replace - // cd ( cd ( x, dir1), dir2); - // by - // cd (x, dir1//dir2); - // - // We can do this only when the source class is exactly - // NamespaceServerProxy. - // - if (target == null || target.equals("")) { - final String path = - JMXNamespaces.concat(other.getSourceNamespace(), - sourcePath); - return new RoutingServerProxy(other.source(),path,"", - other.forwardsContext); - } - // Note: we could do possibly something here - but it would involve - // removing part of targetDir, and possibly adding - // something to sourcePath. - // Too complex to bother! => simply default to stacking... - } - return new RoutingServerProxy(source,sourcePath); + return RoutingProxy.cd(RoutingServerProxy.class, FACTORY, + source, sourcePath); } } diff --git a/jdk/src/share/classes/javax/management/namespace/JMXDomain.java b/jdk/src/share/classes/javax/management/namespace/JMXDomain.java index a54fde7f309..bff3c137062 100644 --- a/jdk/src/share/classes/javax/management/namespace/JMXDomain.java +++ b/jdk/src/share/classes/javax/management/namespace/JMXDomain.java @@ -308,17 +308,17 @@ public class JMXDomain extends JMXNamespace { * It is however only available for subclasses in this package. **/ @Override - ObjectName validateHandlerName(ObjectName supliedName) { - if (supliedName == null) + ObjectName validateHandlerName(ObjectName suppliedName) { + if (suppliedName == null) throw new IllegalArgumentException("Must supply a valid name"); final String dirName = JMXNamespaces. - normalizeNamespaceName(supliedName.getDomain()); + normalizeNamespaceName(suppliedName.getDomain()); final ObjectName handlerName = getDomainObjectName(dirName); - if (!supliedName.equals(handlerName)) + if (!suppliedName.equals(handlerName)) throw new IllegalArgumentException("invalid name space name: "+ - supliedName); + suppliedName); - return supliedName; + return suppliedName; } /** diff --git a/jdk/src/share/classes/javax/management/namespace/JMXNamespace.java b/jdk/src/share/classes/javax/management/namespace/JMXNamespace.java index 39cb11b02ba..23f3004ebe5 100644 --- a/jdk/src/share/classes/javax/management/namespace/JMXNamespace.java +++ b/jdk/src/share/classes/javax/management/namespace/JMXNamespace.java @@ -482,8 +482,8 @@ public class JMXNamespace /** * This method is part of the {@link MBeanRegistration} interface. * The {@link JMXNamespace} class uses the {@link MBeanRegistration} - * interface in order to get a handle to the MBean server in which it is - * registered. It also check the validity of its own ObjectName. + * interface in order to get a reference to the MBean server in which it is + * registered. It also checks the validity of its own ObjectName. *

* This method is called by the MBean server. * Application classes should never call this method directly. @@ -502,11 +502,14 @@ public class JMXNamespace */ public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception { - if (objectName != null && ! objectName.equals(name)) - throw new IllegalStateException( + // need to synchronize to protect against multiple registration. + synchronized(this) { + if (objectName != null && ! objectName.equals(name)) + throw new IllegalStateException( "Already registered under another name: " + objectName); - objectName = validateHandlerName(name); - mbeanServer = server; + objectName = validateHandlerName(name); + mbeanServer = server; + } return name; } @@ -517,23 +520,23 @@ public class JMXNamespace * reuse JMXNamespace in order to implement sessions... * It is however only available for subclasses in this package. **/ - ObjectName validateHandlerName(ObjectName supliedName) { - if (supliedName == null) + ObjectName validateHandlerName(ObjectName suppliedName) { + if (suppliedName == null) throw new IllegalArgumentException("Must supply a valid name"); final String dirName = JMXNamespaces. - normalizeNamespaceName(supliedName.getDomain()); + normalizeNamespaceName(suppliedName.getDomain()); final ObjectName handlerName = JMXNamespaces.getNamespaceObjectName(dirName); - if (!supliedName.equals(handlerName)) + if (!suppliedName.equals(handlerName)) throw new IllegalArgumentException("invalid name space name: "+ - supliedName); - return supliedName; + suppliedName); + return suppliedName; } /** * This method is part of the {@link MBeanRegistration} interface. * The {@link JMXNamespace} class uses the {@link MBeanRegistration} - * interface in order to get a handle to the MBean server in which it is + * interface in order to get a reference to the MBean server in which it is * registered. *

* This method is called by the MBean server. Application classes should @@ -549,7 +552,7 @@ public class JMXNamespace /** * This method is part of the {@link MBeanRegistration} interface. * The {@link JMXNamespace} class uses the {@link MBeanRegistration} - * interface in order to get a handle to the MBean server in which it is + * interface in order to get a reference to the MBean server in which it is * registered. *

* This method is called by the MBean server. Application classes should @@ -573,8 +576,11 @@ public class JMXNamespace * @see MBeanRegistration#postDeregister MBeanRegistration */ public void postDeregister() { - mbeanServer = null; - objectName = null; + // need to synchronize to protect against multiple registration. + synchronized(this) { + mbeanServer = null; + objectName = null; + } } diff --git a/jdk/src/share/classes/javax/management/namespace/JMXNamespaces.java b/jdk/src/share/classes/javax/management/namespace/JMXNamespaces.java index b3eafd28a20..429a9d466d6 100644 --- a/jdk/src/share/classes/javax/management/namespace/JMXNamespaces.java +++ b/jdk/src/share/classes/javax/management/namespace/JMXNamespaces.java @@ -266,11 +266,15 @@ public class JMXNamespaces { ObjectNameRouter.normalizeNamespacePath(namespace,false, true,false); try { + // We could use Util.newObjectName here - but throwing an + // IllegalArgumentException that contains just the supplied + // namespace instead of the whole ObjectName seems preferable. return ObjectName.getInstance(sourcePath+ NAMESPACE_SEPARATOR+":"+ JMXNamespace.TYPE_ASSIGNMENT); } catch (MalformedObjectNameException x) { - throw new IllegalArgumentException(namespace,x); + throw new IllegalArgumentException("Invalid namespace: " + + namespace,x); } } diff --git a/jdk/src/share/classes/javax/management/namespace/JMXRemoteNamespace.java b/jdk/src/share/classes/javax/management/namespace/JMXRemoteNamespace.java index 1639fd2fc55..1e877e0ce34 100644 --- a/jdk/src/share/classes/javax/management/namespace/JMXRemoteNamespace.java +++ b/jdk/src/share/classes/javax/management/namespace/JMXRemoteNamespace.java @@ -35,6 +35,7 @@ import java.io.IOException; import java.security.AccessControlException; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Level; import java.util.logging.Logger; @@ -125,10 +126,8 @@ public class JMXRemoteNamespace // the underlying JMXConnector. It is used in particular to maintain the // "connected" state in this MBean. // - private static class ConnectionListener implements NotificationListener { - private final JMXRemoteNamespace handler; - private ConnectionListener(JMXRemoteNamespace handler) { - this.handler = handler; + private class ConnectionListener implements NotificationListener { + private ConnectionListener() { } public void handleNotification(Notification notification, Object handback) { @@ -136,7 +135,11 @@ public class JMXRemoteNamespace return; final JMXConnectionNotification cn = (JMXConnectionNotification)notification; - handler.checkState(this,cn,(JMXConnector)handback); + final String type = cn.getType(); + if (JMXConnectionNotification.CLOSED.equals(type) + || JMXConnectionNotification.FAILED.equals(type)) { + checkState(this,cn,(JMXConnector)handback); + } } } @@ -188,7 +191,7 @@ public class JMXRemoteNamespace "Connected", "Emitted when the Connected state of this object changes"); - private static long seqNumber=0; + private static AtomicLong seqNumber = new AtomicLong(0); private final NotificationBroadcasterSupport broadcaster; private final ConnectionListener listener; @@ -237,7 +240,7 @@ public class JMXRemoteNamespace this.optionsMap = JMXNamespaceUtils.unmodifiableMap(optionsMap); // handles (dis)connection events - this.listener = new ConnectionListener(this); + this.listener = new ConnectionListener(); // XXX TODO: remove the probe, or simplify it. this.probed = false; @@ -313,8 +316,8 @@ public class JMXRemoteNamespace broadcaster.removeNotificationListener(listener, filter, handback); } - private static synchronized long getNextSeqNumber() { - return seqNumber++; + private static long getNextSeqNumber() { + return seqNumber.getAndIncrement(); } @@ -362,14 +365,18 @@ public class JMXRemoteNamespace // lock while evaluating the true value of the connected state, // while anyone might also call close() or connect() from a // different thread. - // // The method switchConnection() (called from here too) also has the - // same kind of complex logic. + // same kind of complex logic: // // We use the JMXConnector has a handback to the notification listener // (emittingConnector) in order to be able to determine whether the // notification concerns the current connector in use, or an older - // one. + // one. The 'emittingConnector' is the connector from which the + // notification originated. This could be an 'old' connector - as + // closed() and connect() could already have been called before the + // notification arrived. So what we do is to compare the + // 'emittingConnector' with the current connector, to see if the + // notification actually comes from the curent connector. // boolean remove = false; @@ -486,14 +493,12 @@ public class JMXRemoteNamespace } } - private void closeall(JMXConnector... a) { - for (JMXConnector c : a) { - try { - if (c != null) c.close(); - } catch (Exception x) { - // OK: we're gonna throw the original exception later. - LOG.finest("Ignoring exception when closing connector: "+x); - } + private void close(JMXConnector c) { + try { + if (c != null) c.close(); + } catch (Exception x) { + // OK: we're gonna throw the original exception later. + LOG.finest("Ignoring exception when closing connector: "+x); } } @@ -640,10 +645,10 @@ public class JMXRemoteNamespace msc = aconn.getMBeanServerConnection(); aconn.addConnectionNotificationListener(listener,null,aconn); } catch (IOException io) { - closeall(aconn); + close(aconn); throw io; } catch (RuntimeException x) { - closeall(aconn); + close(aconn); throw x; } diff --git a/jdk/src/share/classes/javax/management/namespace/MBeanServerConnectionWrapper.java b/jdk/src/share/classes/javax/management/namespace/MBeanServerConnectionWrapper.java index f74785ffd59..7eeda961e31 100644 --- a/jdk/src/share/classes/javax/management/namespace/MBeanServerConnectionWrapper.java +++ b/jdk/src/share/classes/javax/management/namespace/MBeanServerConnectionWrapper.java @@ -28,7 +28,6 @@ package javax.management.namespace; import com.sun.jmx.mbeanserver.Util; import java.io.IOException; import java.io.ObjectInputStream; -import java.security.AccessController; import java.util.Set; import javax.management.Attribute; diff --git a/jdk/test/javax/management/namespace/Wombat.java b/jdk/test/javax/management/namespace/Wombat.java index 03dbd020ee3..bef648c0fc9 100644 --- a/jdk/test/javax/management/namespace/Wombat.java +++ b/jdk/test/javax/management/namespace/Wombat.java @@ -68,7 +68,12 @@ public class Wombat extends StandardMBean } public Wombat() throws NotCompliantMBeanException { - super(WombatMBean.class); + this(WombatMBean.class); + } + + public Wombat(Class clazz) + throws NotCompliantMBeanException { + super(clazz); final Random r = new Random(); seed = ((r.nextLong() % MAX_SEED) + MAX_SEED)%MAX_SEED; period = 200 + (((r.nextLong()%80)+80)%80)*10; From 77dfe98c4ed92f6ccc87e1ca1d89803819cb8c05 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Tue, 9 Sep 2008 15:20:07 -0700 Subject: [PATCH 82/95] 6728229: (str) StringBuilder.append(CharSequence) does not throw IndexOutOfBoundsException Major spec rework Reviewed-by: alanb --- .../java/lang/AbstractStringBuilder.java | 444 +++++++++--------- .../share/classes/java/lang/StringBuffer.java | 57 +-- .../classes/java/lang/StringBuilder.java | 56 +-- 3 files changed, 244 insertions(+), 313 deletions(-) diff --git a/jdk/src/share/classes/java/lang/AbstractStringBuilder.java b/jdk/src/share/classes/java/lang/AbstractStringBuilder.java index 4ba130b4989..3ee4c21d0b7 100644 --- a/jdk/src/share/classes/java/lang/AbstractStringBuilder.java +++ b/jdk/src/share/classes/java/lang/AbstractStringBuilder.java @@ -42,7 +42,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { /** * The value is used for character storage. */ - char value[]; + char[] value; /** * The count is the number of characters used. @@ -333,8 +333,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { * dst.length * */ - public void getChars(int srcBegin, int srcEnd, char dst[], - int dstBegin) + public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) { if (srcBegin < 0) throw new StringIndexOutOfBoundsException(srcBegin); @@ -366,14 +365,14 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Appends the string representation of the Object - * argument. + * Appends the string representation of the {@code Object} argument. *

- * The argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then appended to this sequence. + * The overall effect is exactly as if the argument were converted + * to a string by the method {@link String#valueOf(Object)}, + * and the characters of that string were then + * {@link #append(String) appended} to this character sequence. * - * @param obj an Object. + * @param obj an {@code Object}. * @return a reference to this object. */ public AbstractStringBuilder append(Object obj) { @@ -383,17 +382,17 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { /** * Appends the specified string to this character sequence. *

- * The characters of the String argument are appended, in + * The characters of the {@code String} argument are appended, in * order, increasing the length of this sequence by the length of the - * argument. If str is null, then the four - * characters "null" are appended. + * argument. If {@code str} is {@code null}, then the four + * characters {@code "null"} are appended. *

* Let n be the length of this character sequence just prior to - * execution of the append method. Then the character at + * execution of the {@code append} method. Then the character at * index k in the new character sequence is equal to the character * at index k in the old character sequence, if k is less * than n; otherwise, it is equal to the character at index - * k-n in the argument str. + * k-n in the argument {@code str}. * * @param str a string. * @return a reference to this object. @@ -435,33 +434,33 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Appends a subsequence of the specified CharSequence to this + * Appends a subsequence of the specified {@code CharSequence} to this * sequence. *

- * Characters of the argument s, starting at - * index start, are appended, in order, to the contents of - * this sequence up to the (exclusive) index end. The length - * of this sequence is increased by the value of end - start. + * Characters of the argument {@code s}, starting at + * index {@code start}, are appended, in order, to the contents of + * this sequence up to the (exclusive) index {@code end}. The length + * of this sequence is increased by the value of {@code end - start}. *

* Let n be the length of this character sequence just prior to - * execution of the append method. Then the character at + * execution of the {@code append} method. Then the character at * index k in this character sequence becomes equal to the * character at index k in this sequence, if k is less than * n; otherwise, it is equal to the character at index - * k+start-n in the argument s. + * k+start-n in the argument {@code s}. *

- * If s is null, then this method appends + * If {@code s} is {@code null}, then this method appends * characters as if the s parameter was a sequence containing the four - * characters "null". + * characters {@code "null"}. * * @param s the sequence to append. * @param start the starting index of the subsequence to be appended. * @param end the end index of the subsequence to be appended. * @return a reference to this object. * @throws IndexOutOfBoundsException if - * start or end are negative, or - * start is greater than end or - * end is greater than s.length() + * {@code start} is negative, or + * {@code start} is greater than {@code end} or + * {@code end} is greater than {@code s.length()} */ public AbstractStringBuilder append(CharSequence s, int start, int end) { if (s == null) @@ -483,22 +482,22 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Appends the string representation of the char array + * Appends the string representation of the {@code char} array * argument to this sequence. *

* The characters of the array argument are appended, in order, to * the contents of this sequence. The length of this sequence * increases by the length of the argument. *

- * The overall effect is exactly as if the argument were converted to - * a string by the method {@link String#valueOf(char[])} and the - * characters of that string were then {@link #append(String) appended} - * to this character sequence. + * The overall effect is exactly as if the argument were converted + * to a string by the method {@link String#valueOf(char[])}, + * and the characters of that string were then + * {@link #append(String) appended} to this character sequence. * * @param str the characters to be appended. * @return a reference to this object. */ - public AbstractStringBuilder append(char str[]) { + public AbstractStringBuilder append(char[] str) { int newCount = count + str.length; if (newCount > value.length) expandCapacity(newCount); @@ -509,22 +508,25 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { /** * Appends the string representation of a subarray of the - * char array argument to this sequence. + * {@code char} array argument to this sequence. *

- * Characters of the char array str, starting at - * index offset, are appended, in order, to the contents + * Characters of the {@code char} array {@code str}, starting at + * index {@code offset}, are appended, in order, to the contents * of this sequence. The length of this sequence increases - * by the value of len. + * by the value of {@code len}. *

- * The overall effect is exactly as if the arguments were converted to - * a string by the method {@link String#valueOf(char[],int,int)} and the - * characters of that string were then {@link #append(String) appended} - * to this character sequence. + * The overall effect is exactly as if the arguments were converted + * to a string by the method {@link String#valueOf(char[],int,int)}, + * and the characters of that string were then + * {@link #append(String) appended} to this character sequence. * * @param str the characters to be appended. - * @param offset the index of the first char to append. - * @param len the number of chars to append. + * @param offset the index of the first {@code char} to append. + * @param len the number of {@code char}s to append. * @return a reference to this object. + * @throws IndexOutOfBoundsException + * if {@code offset < 0} or {@code len < 0} + * or {@code offset+len > str.length} */ public AbstractStringBuilder append(char str[], int offset, int len) { int newCount = count + len; @@ -536,14 +538,15 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Appends the string representation of the boolean + * Appends the string representation of the {@code boolean} * argument to the sequence. *

- * The argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then appended to this sequence. + * The overall effect is exactly as if the argument were converted + * to a string by the method {@link String#valueOf(boolean)}, + * and the characters of that string were then + * {@link #append(String) appended} to this character sequence. * - * @param b a boolean. + * @param b a {@code boolean}. * @return a reference to this object. */ public AbstractStringBuilder append(boolean b) { @@ -569,18 +572,18 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Appends the string representation of the char + * Appends the string representation of the {@code char} * argument to this sequence. *

* The argument is appended to the contents of this sequence. - * The length of this sequence increases by 1. + * The length of this sequence increases by {@code 1}. *

- * The overall effect is exactly as if the argument were converted to - * a string by the method {@link String#valueOf(char)} and the character - * in that string were then {@link #append(String) appended} to this - * character sequence. + * The overall effect is exactly as if the argument were converted + * to a string by the method {@link String#valueOf(char)}, + * and the character in that string were then + * {@link #append(String) appended} to this character sequence. * - * @param c a char. + * @param c a {@code char}. * @return a reference to this object. */ public AbstractStringBuilder append(char c) { @@ -592,14 +595,15 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Appends the string representation of the int + * Appends the string representation of the {@code int} * argument to this sequence. *

- * The argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then appended to this sequence. + * The overall effect is exactly as if the argument were converted + * to a string by the method {@link String#valueOf(int)}, + * and the characters of that string were then + * {@link #append(String) appended} to this character sequence. * - * @param i an int. + * @param i an {@code int}. * @return a reference to this object. */ public AbstractStringBuilder append(int i) { @@ -618,14 +622,15 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Appends the string representation of the long + * Appends the string representation of the {@code long} * argument to this sequence. *

- * The argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then appended to this sequence. + * The overall effect is exactly as if the argument were converted + * to a string by the method {@link String#valueOf(long)}, + * and the characters of that string were then + * {@link #append(String) appended} to this character sequence. * - * @param l a long. + * @param l a {@code long}. * @return a reference to this object. */ public AbstractStringBuilder append(long l) { @@ -644,14 +649,15 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Appends the string representation of the float + * Appends the string representation of the {@code float} * argument to this sequence. *

- * The argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then appended to this string sequence. + * The overall effect is exactly as if the argument were converted + * to a string by the method {@link String#valueOf(float)}, + * and the characters of that string were then + * {@link #append(String) appended} to this character sequence. * - * @param f a float. + * @param f a {@code float}. * @return a reference to this object. */ public AbstractStringBuilder append(float f) { @@ -660,14 +666,15 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Appends the string representation of the double + * Appends the string representation of the {@code double} * argument to this sequence. *

- * The argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then appended to this sequence. + * The overall effect is exactly as if the argument were converted + * to a string by the method {@link String#valueOf(double)}, + * and the characters of that string were then + * {@link #append(String) appended} to this character sequence. * - * @param d a double. + * @param d a {@code double}. * @return a reference to this object. */ public AbstractStringBuilder append(double d) { @@ -677,17 +684,17 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { /** * Removes the characters in a substring of this sequence. - * The substring begins at the specified start and extends to - * the character at index end - 1 or to the end of the + * The substring begins at the specified {@code start} and extends to + * the character at index {@code end - 1} or to the end of the * sequence if no such character exists. If - * start is equal to end, no changes are made. + * {@code start} is equal to {@code end}, no changes are made. * * @param start The beginning index, inclusive. * @param end The ending index, exclusive. * @return This object. - * @throws StringIndexOutOfBoundsException if start - * is negative, greater than length(), or - * greater than end. + * @throws StringIndexOutOfBoundsException if {@code start} + * is negative, greater than {@code length()}, or + * greater than {@code end}. */ public AbstractStringBuilder delete(int start, int end) { if (start < 0) @@ -705,7 +712,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Appends the string representation of the codePoint + * Appends the string representation of the {@code codePoint} * argument to this sequence. * *

The argument is appended to the contents of this sequence. @@ -713,15 +720,15 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { * {@link Character#charCount(int) Character.charCount(codePoint)}. * *

The overall effect is exactly as if the argument were - * converted to a char array by the method {@link - * Character#toChars(int)} and the character in that array were - * then {@link #append(char[]) appended} to this character + * converted to a {@code char} array by the method + * {@link Character#toChars(int)} and the character in that array + * were then {@link #append(char[]) appended} to this character * sequence. * * @param codePoint a Unicode code point * @return a reference to this object. * @exception IllegalArgumentException if the specified - * codePoint isn't a valid Unicode code point + * {@code codePoint} isn't a valid Unicode code point */ public AbstractStringBuilder appendCodePoint(int codePoint) { if (!Character.isValidCodePoint(codePoint)) { @@ -879,27 +886,27 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Inserts the string representation of a subarray of the str + * Inserts the string representation of a subarray of the {@code str} * array argument into this sequence. The subarray begins at the - * specified offset and extends len chars. + * specified {@code offset} and extends {@code len} {@code char}s. * The characters of the subarray are inserted into this sequence at - * the position indicated by index. The length of this - * sequence increases by len chars. + * the position indicated by {@code index}. The length of this + * sequence increases by {@code len} {@code char}s. * * @param index position at which to insert subarray. - * @param str A char array. - * @param offset the index of the first char in subarray to + * @param str A {@code char} array. + * @param offset the index of the first {@code char} in subarray to * be inserted. - * @param len the number of chars in the subarray to + * @param len the number of {@code char}s in the subarray to * be inserted. * @return This object - * @throws StringIndexOutOfBoundsException if index - * is negative or greater than length(), or - * offset or len are negative, or - * (offset+len) is greater than - * str.length. + * @throws StringIndexOutOfBoundsException if {@code index} + * is negative or greater than {@code length()}, or + * {@code offset} or {@code len} are negative, or + * {@code (offset+len)} is greater than + * {@code str.length}. */ - public AbstractStringBuilder insert(int index, char str[], int offset, + public AbstractStringBuilder insert(int index, char[] str, int offset, int len) { if ((index < 0) || (index > length())) @@ -918,20 +925,21 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Inserts the string representation of the Object + * Inserts the string representation of the {@code Object} * argument into this character sequence. *

- * The second argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then inserted into this sequence at the indicated - * offset. + * The overall effect is exactly as if the second argument were + * converted to a string by the method {@link String#valueOf(Object)}, + * and the characters of that string were then + * {@link #insert(int,String) inserted} into this character + * sequence at the indicated offset. *

- * The offset argument must be greater than or equal to - * 0, and less than or equal to the length of this - * sequence. + * The {@code offset} argument must be greater than or equal to + * {@code 0}, and less than or equal to the {@linkplain #length() length} + * of this sequence. * * @param offset the offset. - * @param obj an Object. + * @param obj an {@code Object}. * @return a reference to this object. * @throws StringIndexOutOfBoundsException if the offset is invalid. */ @@ -942,28 +950,28 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { /** * Inserts the string into this character sequence. *

- * The characters of the String argument are inserted, in + * The characters of the {@code String} argument are inserted, in * order, into this sequence at the indicated offset, moving up any * characters originally above that position and increasing the length * of this sequence by the length of the argument. If - * str is null, then the four characters - * "null" are inserted into this sequence. + * {@code str} is {@code null}, then the four characters + * {@code "null"} are inserted into this sequence. *

* The character at index k in the new character sequence is * equal to: *

    *
  • the character at index k in the old character sequence, if - * k is less than offset - *
  • the character at index k-offset in the - * argument str, if k is not less than - * offset but is less than offset+str.length() - *
  • the character at index k-str.length() in the + * k is less than {@code offset} + *
  • the character at index k{@code -offset} in the + * argument {@code str}, if k is not less than + * {@code offset} but is less than {@code offset+str.length()} + *
  • the character at index k{@code -str.length()} in the * old character sequence, if k is not less than - * offset+str.length() + * {@code offset+str.length()} *

- * The offset argument must be greater than or equal to - * 0, and less than or equal to the length of this - * sequence. + * The {@code offset} argument must be greater than or equal to + * {@code 0}, and less than or equal to the {@linkplain #length() length} + * of this sequence. * * @param offset the offset. * @param str a string. @@ -986,27 +994,30 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Inserts the string representation of the char array + * Inserts the string representation of the {@code char} array * argument into this sequence. *

* The characters of the array argument are inserted into the * contents of this sequence at the position indicated by - * offset. The length of this sequence increases by + * {@code offset}. The length of this sequence increases by * the length of the argument. *

- * The overall effect is exactly as if the argument were converted to - * a string by the method {@link String#valueOf(char[])} and the - * characters of that string were then - * {@link #insert(int,String) inserted} into this - * character sequence at the position indicated by - * offset. + * The overall effect is exactly as if the second argument were + * converted to a string by the method {@link String#valueOf(char[])}, + * and the characters of that string were then + * {@link #insert(int,String) inserted} into this character + * sequence at the indicated offset. + *

+ * The {@code offset} argument must be greater than or equal to + * {@code 0}, and less than or equal to the {@linkplain #length() length} + * of this sequence. * * @param offset the offset. * @param str a character array. * @return a reference to this object. * @throws StringIndexOutOfBoundsException if the offset is invalid. */ - public AbstractStringBuilder insert(int offset, char str[]) { + public AbstractStringBuilder insert(int offset, char[] str) { if ((offset < 0) || (offset > length())) throw new StringIndexOutOfBoundsException(offset); int len = str.length; @@ -1020,18 +1031,20 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Inserts the specified CharSequence into this sequence. + * Inserts the specified {@code CharSequence} into this sequence. *

- * The characters of the CharSequence argument are inserted, + * The characters of the {@code CharSequence} argument are inserted, * in order, into this sequence at the indicated offset, moving up * any characters originally above that position and increasing the length * of this sequence by the length of the argument s. *

* The result of this method is exactly the same as if it were an - * invocation of this object's insert(dstOffset, s, 0, s.length()) method. + * invocation of this object's + * {@link #insert(int,CharSequence,int,int) insert}(dstOffset, s, 0, s.length()) + * method. * - *

If s is null, then the four characters - * "null" are inserted into this sequence. + *

If {@code s} is {@code null}, then the four characters + * {@code "null"} are inserted into this sequence. * * @param dstOffset the offset. * @param s the sequence to be inserted @@ -1047,51 +1060,51 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Inserts a subsequence of the specified CharSequence into + * Inserts a subsequence of the specified {@code CharSequence} into * this sequence. *

- * The subsequence of the argument s specified by - * start and end are inserted, + * The subsequence of the argument {@code s} specified by + * {@code start} and {@code end} are inserted, * in order, into this sequence at the specified destination offset, moving * up any characters originally above that position. The length of this - * sequence is increased by end - start. + * sequence is increased by {@code end - start}. *

* The character at index k in this sequence becomes equal to: *

    *
  • the character at index k in this sequence, if - * k is less than dstOffset - *
  • the character at index k+start-dstOffset in - * the argument s, if k is greater than or equal to - * dstOffset but is less than dstOffset+end-start - *
  • the character at index k-(end-start) in this + * k is less than {@code dstOffset} + *
  • the character at index k{@code +start-dstOffset} in + * the argument {@code s}, if k is greater than or equal to + * {@code dstOffset} but is less than {@code dstOffset+end-start} + *
  • the character at index k{@code -(end-start)} in this * sequence, if k is greater than or equal to - * dstOffset+end-start + * {@code dstOffset+end-start} *

- * The dstOffset argument must be greater than or equal to - * 0, and less than or equal to the length of this - * sequence. + * The {@code dstOffset} argument must be greater than or equal to + * {@code 0}, and less than or equal to the {@linkplain #length() length} + * of this sequence. *

The start argument must be nonnegative, and not greater than - * end. + * {@code end}. *

The end argument must be greater than or equal to - * start, and less than or equal to the length of s. + * {@code start}, and less than or equal to the length of s. * - *

If s is null, then this method inserts + *

If {@code s} is {@code null}, then this method inserts * characters as if the s parameter was a sequence containing the four - * characters "null". + * characters {@code "null"}. * * @param dstOffset the offset in this sequence. * @param s the sequence to be inserted. * @param start the starting index of the subsequence to be inserted. * @param end the end index of the subsequence to be inserted. * @return a reference to this object. - * @throws IndexOutOfBoundsException if dstOffset - * is negative or greater than this.length(), or - * start or end are negative, or - * start is greater than end or - * end is greater than s.length() + * @throws IndexOutOfBoundsException if {@code dstOffset} + * is negative or greater than {@code this.length()}, or + * {@code start} or {@code end} are negative, or + * {@code start} is greater than {@code end} or + * {@code end} is greater than {@code s.length()} */ public AbstractStringBuilder insert(int dstOffset, CharSequence s, - int start, int end) { + int start, int end) { if (s == null) s = "null"; if ((dstOffset < 0) || (dstOffset > this.length())) @@ -1115,20 +1128,21 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Inserts the string representation of the boolean + * Inserts the string representation of the {@code boolean} * argument into this sequence. *

- * The second argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then inserted into this sequence at the indicated - * offset. + * The overall effect is exactly as if the second argument were + * converted to a string by the method {@link String#valueOf(boolean)}, + * and the characters of that string were then + * {@link #insert(int,String) inserted} into this character + * sequence at the indicated offset. *

- * The offset argument must be greater than or equal to - * 0, and less than or equal to the length of this - * sequence. + * The {@code offset} argument must be greater than or equal to + * {@code 0}, and less than or equal to the {@linkplain #length() length} + * of this sequence. * * @param offset the offset. - * @param b a boolean. + * @param b a {@code boolean}. * @return a reference to this object. * @throws StringIndexOutOfBoundsException if the offset is invalid. */ @@ -1137,25 +1151,21 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Inserts the string representation of the char + * Inserts the string representation of the {@code char} * argument into this sequence. *

- * The second argument is inserted into the contents of this sequence - * at the position indicated by offset. The length - * of this sequence increases by one. + * The overall effect is exactly as if the second argument were + * converted to a string by the method {@link String#valueOf(char)}, + * and the character in that string were then + * {@link #insert(int,String) inserted} into this character + * sequence at the indicated offset. *

- * The overall effect is exactly as if the argument were converted to - * a string by the method {@link String#valueOf(char)} and the character - * in that string were then {@link #insert(int, String) inserted} into - * this character sequence at the position indicated by - * offset. - *

- * The offset argument must be greater than or equal to - * 0, and less than or equal to the length of this - * sequence. + * The {@code offset} argument must be greater than or equal to + * {@code 0}, and less than or equal to the {@linkplain #length() length} + * of this sequence. * * @param offset the offset. - * @param c a char. + * @param c a {@code char}. * @return a reference to this object. * @throws IndexOutOfBoundsException if the offset is invalid. */ @@ -1170,20 +1180,21 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Inserts the string representation of the second int + * Inserts the string representation of the second {@code int} * argument into this sequence. *

- * The second argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then inserted into this sequence at the indicated - * offset. + * The overall effect is exactly as if the second argument were + * converted to a string by the method {@link String#valueOf(int)}, + * and the characters of that string were then + * {@link #insert(int,String) inserted} into this character + * sequence at the indicated offset. *

- * The offset argument must be greater than or equal to - * 0, and less than or equal to the length of this - * sequence. + * The {@code offset} argument must be greater than or equal to + * {@code 0}, and less than or equal to the {@linkplain #length() length} + * of this sequence. * * @param offset the offset. - * @param i an int. + * @param i an {@code int}. * @return a reference to this object. * @throws StringIndexOutOfBoundsException if the offset is invalid. */ @@ -1192,20 +1203,21 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Inserts the string representation of the long + * Inserts the string representation of the {@code long} * argument into this sequence. *

- * The second argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then inserted into this sequence at the position - * indicated by offset. + * The overall effect is exactly as if the second argument were + * converted to a string by the method {@link String#valueOf(long)}, + * and the characters of that string were then + * {@link #insert(int,String) inserted} into this character + * sequence at the indicated offset. *

- * The offset argument must be greater than or equal to - * 0, and less than or equal to the length of this - * sequence. + * The {@code offset} argument must be greater than or equal to + * {@code 0}, and less than or equal to the {@linkplain #length() length} + * of this sequence. * * @param offset the offset. - * @param l a long. + * @param l a {@code long}. * @return a reference to this object. * @throws StringIndexOutOfBoundsException if the offset is invalid. */ @@ -1214,20 +1226,21 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Inserts the string representation of the float + * Inserts the string representation of the {@code float} * argument into this sequence. *

- * The second argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then inserted into this sequence at the indicated - * offset. + * The overall effect is exactly as if the second argument were + * converted to a string by the method {@link String#valueOf(float)}, + * and the characters of that string were then + * {@link #insert(int,String) inserted} into this character + * sequence at the indicated offset. *

- * The offset argument must be greater than or equal to - * 0, and less than or equal to the length of this - * sequence. + * The {@code offset} argument must be greater than or equal to + * {@code 0}, and less than or equal to the {@linkplain #length() length} + * of this sequence. * * @param offset the offset. - * @param f a float. + * @param f a {@code float}. * @return a reference to this object. * @throws StringIndexOutOfBoundsException if the offset is invalid. */ @@ -1236,20 +1249,21 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Inserts the string representation of the double + * Inserts the string representation of the {@code double} * argument into this sequence. *

- * The second argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then inserted into this sequence at the indicated - * offset. + * The overall effect is exactly as if the second argument were + * converted to a string by the method {@link String#valueOf(double)}, + * and the characters of that string were then + * {@link #insert(int,String) inserted} into this character + * sequence at the indicated offset. *

- * The offset argument must be greater than or equal to - * 0, and less than or equal to the length of this - * sequence. + * The {@code offset} argument must be greater than or equal to + * {@code 0}, and less than or equal to the {@linkplain #length() length} + * of this sequence. * * @param offset the offset. - * @param d a double. + * @param d a {@code double}. * @return a reference to this object. * @throws StringIndexOutOfBoundsException if the offset is invalid. */ diff --git a/jdk/src/share/classes/java/lang/StringBuffer.java b/jdk/src/share/classes/java/lang/StringBuffer.java index e0ecbef0ebe..f44bb2baedd 100644 --- a/jdk/src/share/classes/java/lang/StringBuffer.java +++ b/jdk/src/share/classes/java/lang/StringBuffer.java @@ -212,7 +212,7 @@ package java.lang; * @throws NullPointerException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ - public synchronized void getChars(int srcBegin, int srcEnd, char dst[], + public synchronized void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) { super.getChars(srcBegin, srcEnd, dst, dstBegin); @@ -228,10 +228,6 @@ package java.lang; value[index] = ch; } - /** - * @see java.lang.String#valueOf(java.lang.Object) - * @see #append(java.lang.String) - */ public synchronized StringBuffer append(Object obj) { super.append(String.valueOf(obj)); return this; @@ -314,20 +310,19 @@ package java.lang; return this; } - public synchronized StringBuffer append(char str[]) { + public synchronized StringBuffer append(char[] str) { super.append(str); return this; } - public synchronized StringBuffer append(char str[], int offset, int len) { + /** + * @throws IndexOutOfBoundsException {@inheritDoc} + */ + public synchronized StringBuffer append(char[] str, int offset, int len) { super.append(str, offset, len); return this; } - /** - * @see java.lang.String#valueOf(boolean) - * @see #append(java.lang.String) - */ public synchronized StringBuffer append(boolean b) { super.append(b); return this; @@ -338,10 +333,6 @@ package java.lang; return this; } - /** - * @see java.lang.String#valueOf(int) - * @see #append(java.lang.String) - */ public synchronized StringBuffer append(int i) { super.append(i); return this; @@ -355,28 +346,16 @@ package java.lang; return this; } - /** - * @see java.lang.String#valueOf(long) - * @see #append(java.lang.String) - */ public synchronized StringBuffer append(long lng) { super.append(lng); return this; } - /** - * @see java.lang.String#valueOf(float) - * @see #append(java.lang.String) - */ public synchronized StringBuffer append(float f) { super.append(f); return this; } - /** - * @see java.lang.String#valueOf(double) - * @see #append(java.lang.String) - */ public synchronized StringBuffer append(double d) { super.append(d); return this; @@ -437,7 +416,7 @@ package java.lang; * @throws StringIndexOutOfBoundsException {@inheritDoc} * @since 1.2 */ - public synchronized StringBuffer insert(int index, char str[], int offset, + public synchronized StringBuffer insert(int index, char[] str, int offset, int len) { super.insert(index, str, offset, len); @@ -446,9 +425,6 @@ package java.lang; /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see java.lang.String#valueOf(java.lang.Object) - * @see #insert(int, java.lang.String) - * @see #length() */ public synchronized StringBuffer insert(int offset, Object obj) { super.insert(offset, String.valueOf(obj)); @@ -457,7 +433,6 @@ package java.lang; /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see #length() */ public synchronized StringBuffer insert(int offset, String str) { super.insert(offset, str); @@ -467,7 +442,7 @@ package java.lang; /** * @throws StringIndexOutOfBoundsException {@inheritDoc} */ - public synchronized StringBuffer insert(int offset, char str[]) { + public synchronized StringBuffer insert(int offset, char[] str) { super.insert(offset, str); return this; } @@ -498,9 +473,6 @@ package java.lang; /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see java.lang.String#valueOf(boolean) - * @see #insert(int, java.lang.String) - * @see #length() */ public StringBuffer insert(int offset, boolean b) { return insert(offset, String.valueOf(b)); @@ -508,7 +480,6 @@ package java.lang; /** * @throws IndexOutOfBoundsException {@inheritDoc} - * @see #length() */ public synchronized StringBuffer insert(int offset, char c) { super.insert(offset, c); @@ -517,9 +488,6 @@ package java.lang; /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see java.lang.String#valueOf(int) - * @see #insert(int, java.lang.String) - * @see #length() */ public StringBuffer insert(int offset, int i) { return insert(offset, String.valueOf(i)); @@ -527,9 +495,6 @@ package java.lang; /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see java.lang.String#valueOf(long) - * @see #insert(int, java.lang.String) - * @see #length() */ public StringBuffer insert(int offset, long l) { return insert(offset, String.valueOf(l)); @@ -537,9 +502,6 @@ package java.lang; /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see java.lang.String#valueOf(float) - * @see #insert(int, java.lang.String) - * @see #length() */ public StringBuffer insert(int offset, float f) { return insert(offset, String.valueOf(f)); @@ -547,9 +509,6 @@ package java.lang; /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see java.lang.String#valueOf(double) - * @see #insert(int, java.lang.String) - * @see #length() */ public StringBuffer insert(int offset, double d) { return insert(offset, String.valueOf(d)); diff --git a/jdk/src/share/classes/java/lang/StringBuilder.java b/jdk/src/share/classes/java/lang/StringBuilder.java index 99f19768d62..e7eea47be47 100644 --- a/jdk/src/share/classes/java/lang/StringBuilder.java +++ b/jdk/src/share/classes/java/lang/StringBuilder.java @@ -124,10 +124,6 @@ public final class StringBuilder append(seq); } - /** - * @see java.lang.String#valueOf(java.lang.Object) - * @see #append(java.lang.String) - */ public StringBuilder append(Object obj) { return append(String.valueOf(obj)); } @@ -175,7 +171,6 @@ public final class StringBuilder } /** - * @throws IndexOutOfBoundsException {@inheritDoc} */ public StringBuilder append(CharSequence s) { if (s == null) @@ -197,20 +192,19 @@ public final class StringBuilder return this; } - public StringBuilder append(char str[]) { + public StringBuilder append(char[] str) { super.append(str); return this; } - public StringBuilder append(char str[], int offset, int len) { + /** + * @throws IndexOutOfBoundsException {@inheritDoc} + */ + public StringBuilder append(char[] str, int offset, int len) { super.append(str, offset, len); return this; } - /** - * @see java.lang.String#valueOf(boolean) - * @see #append(java.lang.String) - */ public StringBuilder append(boolean b) { super.append(b); return this; @@ -221,37 +215,21 @@ public final class StringBuilder return this; } - /** - * @see java.lang.String#valueOf(int) - * @see #append(java.lang.String) - */ public StringBuilder append(int i) { super.append(i); return this; } - /** - * @see java.lang.String#valueOf(long) - * @see #append(java.lang.String) - */ public StringBuilder append(long lng) { super.append(lng); return this; } - /** - * @see java.lang.String#valueOf(float) - * @see #append(java.lang.String) - */ public StringBuilder append(float f) { super.append(f); return this; } - /** - * @see java.lang.String#valueOf(double) - * @see #append(java.lang.String) - */ public StringBuilder append(double d) { super.append(d); return this; @@ -292,7 +270,7 @@ public final class StringBuilder /** * @throws StringIndexOutOfBoundsException {@inheritDoc} */ - public StringBuilder insert(int index, char str[], int offset, + public StringBuilder insert(int index, char[] str, int offset, int len) { super.insert(index, str, offset, len); @@ -301,9 +279,6 @@ public final class StringBuilder /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see java.lang.String#valueOf(java.lang.Object) - * @see #insert(int, java.lang.String) - * @see #length() */ public StringBuilder insert(int offset, Object obj) { return insert(offset, String.valueOf(obj)); @@ -311,7 +286,6 @@ public final class StringBuilder /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see #length() */ public StringBuilder insert(int offset, String str) { super.insert(offset, str); @@ -321,7 +295,7 @@ public final class StringBuilder /** * @throws StringIndexOutOfBoundsException {@inheritDoc} */ - public StringBuilder insert(int offset, char str[]) { + public StringBuilder insert(int offset, char[] str) { super.insert(offset, str); return this; } @@ -349,9 +323,6 @@ public final class StringBuilder /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see java.lang.String#valueOf(boolean) - * @see #insert(int, java.lang.String) - * @see #length() */ public StringBuilder insert(int offset, boolean b) { super.insert(offset, b); @@ -360,7 +331,6 @@ public final class StringBuilder /** * @throws IndexOutOfBoundsException {@inheritDoc} - * @see #length() */ public StringBuilder insert(int offset, char c) { super.insert(offset, c); @@ -369,9 +339,6 @@ public final class StringBuilder /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see java.lang.String#valueOf(int) - * @see #insert(int, java.lang.String) - * @see #length() */ public StringBuilder insert(int offset, int i) { return insert(offset, String.valueOf(i)); @@ -379,9 +346,6 @@ public final class StringBuilder /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see java.lang.String#valueOf(long) - * @see #insert(int, java.lang.String) - * @see #length() */ public StringBuilder insert(int offset, long l) { return insert(offset, String.valueOf(l)); @@ -389,9 +353,6 @@ public final class StringBuilder /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see java.lang.String#valueOf(float) - * @see #insert(int, java.lang.String) - * @see #length() */ public StringBuilder insert(int offset, float f) { return insert(offset, String.valueOf(f)); @@ -399,9 +360,6 @@ public final class StringBuilder /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see java.lang.String#valueOf(double) - * @see #insert(int, java.lang.String) - * @see #length() */ public StringBuilder insert(int offset, double d) { return insert(offset, String.valueOf(d)); From 3eca12f7b7a33129b3ebc3f411cffdcb6e03c0bc Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Tue, 9 Sep 2008 15:20:07 -0700 Subject: [PATCH 83/95] 6733145: (bf) CharBuffer.subSequence can be updated to take advantage of covariant returns Change return type to CharBuffer Reviewed-by: alanb --- jdk/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java | 2 +- jdk/src/share/classes/java/nio/Direct-X-Buffer.java | 2 +- jdk/src/share/classes/java/nio/Heap-X-Buffer.java | 2 +- jdk/src/share/classes/java/nio/StringCharBuffer.java | 2 +- jdk/src/share/classes/java/nio/X-Buffer.java | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/jdk/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java b/jdk/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java index 5761fd867a4..1b959ab6e9f 100644 --- a/jdk/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java +++ b/jdk/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java @@ -186,7 +186,7 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private // --- Methods to support CharSequence --- - public CharSequence subSequence(int start, int end) { + public CharBuffer subSequence(int start, int end) { int pos = position(); int lim = limit(); assert (pos <= lim); diff --git a/jdk/src/share/classes/java/nio/Direct-X-Buffer.java b/jdk/src/share/classes/java/nio/Direct-X-Buffer.java index d1cfb6b5c6a..44915f20742 100644 --- a/jdk/src/share/classes/java/nio/Direct-X-Buffer.java +++ b/jdk/src/share/classes/java/nio/Direct-X-Buffer.java @@ -402,7 +402,7 @@ class Direct$Type$Buffer$RW$$BO$ // --- Methods to support CharSequence --- - public CharSequence subSequence(int start, int end) { + public CharBuffer subSequence(int start, int end) { int pos = position(); int lim = limit(); assert (pos <= lim); diff --git a/jdk/src/share/classes/java/nio/Heap-X-Buffer.java b/jdk/src/share/classes/java/nio/Heap-X-Buffer.java index 0c19ca5549e..ed59c73a842 100644 --- a/jdk/src/share/classes/java/nio/Heap-X-Buffer.java +++ b/jdk/src/share/classes/java/nio/Heap-X-Buffer.java @@ -566,7 +566,7 @@ class Heap$Type$Buffer$RW$ // --- Methods to support CharSequence --- - public CharSequence subSequence(int start, int end) { + public CharBuffer subSequence(int start, int end) { if ((start < 0) || (end > length()) || (start > end)) diff --git a/jdk/src/share/classes/java/nio/StringCharBuffer.java b/jdk/src/share/classes/java/nio/StringCharBuffer.java index 3f49ae1eb12..648b1986fca 100644 --- a/jdk/src/share/classes/java/nio/StringCharBuffer.java +++ b/jdk/src/share/classes/java/nio/StringCharBuffer.java @@ -99,7 +99,7 @@ class StringCharBuffer // package-private return str.toString().substring(start + offset, end + offset); } - public final CharSequence subSequence(int start, int end) { + public final CharBuffer subSequence(int start, int end) { try { int pos = position(); return new StringCharBuffer(str, -1, diff --git a/jdk/src/share/classes/java/nio/X-Buffer.java b/jdk/src/share/classes/java/nio/X-Buffer.java index 99a7468fff8..67cf6db3d8b 100644 --- a/jdk/src/share/classes/java/nio/X-Buffer.java +++ b/jdk/src/share/classes/java/nio/X-Buffer.java @@ -1239,13 +1239,13 @@ public abstract class $Type$Buffer * smaller than start and no larger than * remaining() * - * @return The new character sequence + * @return The new character buffer * * @throws IndexOutOfBoundsException * If the preconditions on start and end * do not hold */ - public abstract CharSequence subSequence(int start, int end); + public abstract CharBuffer subSequence(int start, int end); // --- Methods to support Appendable --- From a4ef2ba11dee41ff61fee08e52867a4213bc6e06 Mon Sep 17 00:00:00 2001 From: Eamonn McManus Date: Wed, 10 Sep 2008 13:36:47 +0200 Subject: [PATCH 84/95] 6734813: Provide a way to construct an ObjectName without checked exceptions 6746649: ObjectName constructors and methods declare unchecked exceptions in throws clauses Reviewed-by: dfuchs --- .../DefaultMBeanServerInterceptor.java | 5 +- .../com/sun/jmx/mbeanserver/Repository.java | 2 +- .../classes/com/sun/jmx/mbeanserver/Util.java | 8 - .../sun/jmx/namespace/DomainInterceptor.java | 4 +- .../lang/management/PlatformComponent.java | 2 +- .../classes/java/util/logging/Logging.java | 2 +- .../javax/management/MBeanServerDelegate.java | 2 +- .../classes/javax/management/ObjectName.java | 161 +++++++++++++--- .../management/QueryNotificationFilter.java | 2 +- .../event/EventClientDelegateMBean.java | 2 +- .../namespace/MBeanServerSupport.java | 14 +- .../share/classes/sun/management/Util.java | 6 +- .../management/ObjectName/ValueOfTest.java | 175 ++++++++++++++++++ 13 files changed, 327 insertions(+), 58 deletions(-) create mode 100644 jdk/test/javax/management/ObjectName/ValueOfTest.java diff --git a/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java b/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java index 7faeb8727fb..7da3406b911 100644 --- a/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java +++ b/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java @@ -613,8 +613,7 @@ public class DefaultMBeanServerInterceptor List result = new ArrayList(domains.length); for (int i = 0; i < domains.length; i++) { try { - ObjectName dom = - Util.newObjectName(domains[i] + ":x=x"); + ObjectName dom = ObjectName.valueOf(domains[i] + ":x=x"); checkMBeanPermission(mbeanServerName, (String) null, null, dom, "getDomains"); result.add(domains[i]); } catch (SecurityException e) { @@ -1170,7 +1169,7 @@ public class DefaultMBeanServerInterceptor if one is supplied where it shouldn't be). */ final String completeName = domain + name; - return Util.newObjectName(completeName); + return ObjectName.valueOf(completeName); } public String getDefaultDomain() { diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Repository.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Repository.java index 5c3339833d6..03f3e5277bd 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Repository.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Repository.java @@ -396,7 +396,7 @@ public class Repository { // Set domain to default if domain is empty and not already set if (dom.length() == 0) - name = Util.newObjectName(domain + name.toString()); + name = ObjectName.valueOf(domain + name.toString()); // Do we have default domain ? if (dom == domain) { // ES: OK (dom & domain are interned) diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java index 93c5c97f646..6307adbf8d9 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java @@ -110,14 +110,6 @@ public class Util { return new ArrayList(c); } - public static ObjectName newObjectName(String s) { - try { - return new ObjectName(s); - } catch (MalformedObjectNameException e) { - throw new IllegalArgumentException(e); - } - } - /* This method can be used by code that is deliberately violating the * allowed checked casts. Rather than marking the whole method containing * the code with @SuppressWarnings, you can use a call to this method for diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/DomainInterceptor.java b/jdk/src/share/classes/com/sun/jmx/namespace/DomainInterceptor.java index 84644d831a5..7b88087a81c 100644 --- a/jdk/src/share/classes/com/sun/jmx/namespace/DomainInterceptor.java +++ b/jdk/src/share/classes/com/sun/jmx/namespace/DomainInterceptor.java @@ -110,7 +110,7 @@ public class DomainInterceptor extends HandlerInterceptor { super(handler); this.domainName = domainName; this.serverName = serverName; - ALL = Util.newObjectName(domainName+":*"); + ALL = ObjectName.valueOf(domainName+":*"); } @Override @@ -437,7 +437,7 @@ public class DomainInterceptor extends HandlerInterceptor { int count=0; for (int i=0;i set = mbs.queryNames(on, null); for (PlatformComponent pc : subComponents) { set.addAll(pc.getObjectNames(mbs)); diff --git a/jdk/src/share/classes/java/util/logging/Logging.java b/jdk/src/share/classes/java/util/logging/Logging.java index 72468699ead..d99782407a5 100644 --- a/jdk/src/share/classes/java/util/logging/Logging.java +++ b/jdk/src/share/classes/java/util/logging/Logging.java @@ -118,6 +118,6 @@ class Logging implements LoggingMXBean { } public ObjectName getObjectName() { - return com.sun.jmx.mbeanserver.Util.newObjectName(LogManager.LOGGING_MXBEAN_NAME); + return ObjectName.valueOf(LogManager.LOGGING_MXBEAN_NAME); } } diff --git a/jdk/src/share/classes/javax/management/MBeanServerDelegate.java b/jdk/src/share/classes/javax/management/MBeanServerDelegate.java index ea4799d3f60..00b82a92ff8 100644 --- a/jdk/src/share/classes/javax/management/MBeanServerDelegate.java +++ b/jdk/src/share/classes/javax/management/MBeanServerDelegate.java @@ -304,7 +304,7 @@ public class MBeanServerDelegate implements MBeanServerDelegateMBean, * @since 1.6 */ public static final ObjectName DELEGATE_NAME = - Util.newObjectName("JMImplementation:type=MBeanServerDelegate"); + ObjectName.valueOf("JMImplementation:type=MBeanServerDelegate"); /* Return a timestamp that is monotonically increasing even if System.currentTimeMillis() isn't (for example, if you call this diff --git a/jdk/src/share/classes/javax/management/ObjectName.java b/jdk/src/share/classes/javax/management/ObjectName.java index 20bcfce7297..8185edc2742 100644 --- a/jdk/src/share/classes/javax/management/ObjectName.java +++ b/jdk/src/share/classes/javax/management/ObjectName.java @@ -413,7 +413,7 @@ public class ObjectName implements Comparable, QueryExp { } private void copyToOtherDomain(String domain, ObjectName aname) - throws MalformedObjectNameException, NullPointerException { + throws MalformedObjectNameException { // The domain cannot be null if (domain == null) @@ -467,7 +467,7 @@ public class ObjectName implements Comparable, QueryExp { * is null. */ private void construct(String name) - throws MalformedObjectNameException, NullPointerException { + throws MalformedObjectNameException { // The name cannot be null if (name == null) @@ -729,7 +729,7 @@ public class ObjectName implements Comparable, QueryExp { * @exception NullPointerException One of the parameters is null. */ private void construct(String domain, Map props) - throws MalformedObjectNameException, NullPointerException { + throws MalformedObjectNameException { // The domain cannot be null if (domain == null) @@ -1071,7 +1071,7 @@ public class ObjectName implements Comparable, QueryExp { * Check if the supplied key is a valid key. */ private static void checkKey(String key) - throws MalformedObjectNameException, NullPointerException { + throws MalformedObjectNameException { if (key == null) throw new NullPointerException("Invalid key (null)"); @@ -1359,9 +1359,10 @@ public class ObjectName implements Comparable, QueryExp { * @exception NullPointerException The name parameter * is null. * + * @see #valueOf(String) */ public static ObjectName getInstance(String name) - throws MalformedObjectNameException, NullPointerException { + throws MalformedObjectNameException { return new ObjectName(name); } @@ -1386,10 +1387,11 @@ public class ObjectName implements Comparable, QueryExp { * follow the rules for quoting. * @exception NullPointerException One of the parameters is null. * + * @see #valueOf(String, String, String) */ public static ObjectName getInstance(String domain, String key, String value) - throws MalformedObjectNameException, NullPointerException { + throws MalformedObjectNameException { return new ObjectName(domain, key, value); } @@ -1417,10 +1419,11 @@ public class ObjectName implements Comparable, QueryExp { * quoting. * @exception NullPointerException One of the parameters is null. * + * @see #valueOf(String, Hashtable) */ public static ObjectName getInstance(String domain, Hashtable table) - throws MalformedObjectNameException, NullPointerException { + throws MalformedObjectNameException { return new ObjectName(domain, table); } @@ -1453,11 +1456,120 @@ public class ObjectName implements Comparable, QueryExp { * @exception NullPointerException The name is null. * */ - public static ObjectName getInstance(ObjectName name) - throws NullPointerException { + public static ObjectName getInstance(ObjectName name) { if (name.getClass().equals(ObjectName.class)) return name; - return Util.newObjectName(name.getSerializedNameString()); + return valueOf(name.getSerializedNameString()); + } + + /** + *

Return an instance of ObjectName that can be used anywhere + * an object obtained with {@link #ObjectName(String) new + * ObjectName(name)} can be used. The returned object may be of + * a subclass of ObjectName. Calling this method twice with the + * same parameters may return the same object or two equal but + * not identical objects.

+ * + *

This method is equivalent to {@link #getInstance(String)} except that + * it does not throw any checked exceptions.

+ * + * @param name A string representation of the object name. + * + * @return an ObjectName corresponding to the given String. + * + * @exception IllegalArgumentException The string passed as a + * parameter does not have the right format. The {@linkplain + * Throwable#getCause() cause} of this exception will be a + * {@link MalformedObjectNameException}. + * @exception NullPointerException The name parameter + * is null. + * + * @since 1.7 + */ + public static ObjectName valueOf(String name) { + try { + return getInstance(name); + } catch (MalformedObjectNameException e) { + throw new IllegalArgumentException(e.getMessage(), e); + // Just plain IllegalArgumentException(e) produces an exception + // message "javax.management.MalformedObjectNameException: ..." + // which is distracting. + } + } + + /** + *

Return an instance of ObjectName that can be used anywhere + * an object obtained with {@link #ObjectName(String, String, + * String) new ObjectName(domain, key, value)} can be used. The + * returned object may be of a subclass of ObjectName. Calling + * this method twice with the same parameters may return the same + * object or two equal but not identical objects.

+ * + *

This method is equivalent to {@link #getInstance(String, String, + * String)} except that it does not throw any checked exceptions.

+ * + * @param domain The domain part of the object name. + * @param key The attribute in the key property of the object name. + * @param value The value in the key property of the object name. + * + * @return an ObjectName corresponding to the given domain, + * key, and value. + * + * @exception IllegalArgumentException The + * domain, key, or value + * contains an illegal character, or value does not + * follow the rules for quoting. The {@linkplain + * Throwable#getCause() cause} of this exception will be a + * {@link MalformedObjectNameException}. + * @exception NullPointerException One of the parameters is null. + * + * @since 1.7 + */ + public static ObjectName valueOf(String domain, String key, String value) { + try { + return getInstance(domain, key, value); + } catch (MalformedObjectNameException e) { + throw new IllegalArgumentException(e.getMessage(), e); + } + } + + /** + *

Return an instance of ObjectName that can be used anywhere + * an object obtained with {@link #ObjectName(String, Hashtable) + * new ObjectName(domain, table)} can be used. The returned + * object may be of a subclass of ObjectName. Calling this method + * twice with the same parameters may return the same object or + * two equal but not identical objects.

+ * + *

This method is equivalent to {@link #getInstance(String, Hashtable)} + * except that it does not throw any checked exceptions.

+ * + * @param domain The domain part of the object name. + * @param table A hash table containing one or more key + * properties. The key of each entry in the table is the key of a + * key property in the object name. The associated value in the + * table is the associated value in the object name. + * + * @return an ObjectName corresponding to the given domain and + * key mappings. + * + * @exception IllegalArgumentException The domain + * contains an illegal character, or one of the keys or values in + * table contains an illegal character, or one of the + * values in table does not follow the rules for + * quoting. The {@linkplain Throwable#getCause() cause} of this exception + * will be a {@link MalformedObjectNameException}. + * @exception NullPointerException One of the parameters is null. + * + * @since 1.7 + */ + public static ObjectName valueOf(String domain, + Hashtable table) { + try { + return new ObjectName(domain, table); + } catch (MalformedObjectNameException e) { + throw new IllegalArgumentException(e.getMessage(), e); + } } /** @@ -1477,7 +1589,7 @@ public class ObjectName implements Comparable, QueryExp { * @since 1.7 **/ public final ObjectName withDomain(String newDomain) - throws NullPointerException, MalformedObjectNameException { + throws MalformedObjectNameException { return new ObjectName(newDomain, this); } @@ -1490,9 +1602,11 @@ public class ObjectName implements Comparable, QueryExp { * parameter does not have the right format. * @exception NullPointerException The name parameter * is null. + * + * @see #valueOf(String) */ public ObjectName(String name) - throws MalformedObjectNameException, NullPointerException { + throws MalformedObjectNameException { construct(name); } @@ -1508,9 +1622,11 @@ public class ObjectName implements Comparable, QueryExp { * contains an illegal character, or value does not * follow the rules for quoting. * @exception NullPointerException One of the parameters is null. + * + * @see #valueOf(String, String, String) */ public ObjectName(String domain, String key, String value) - throws MalformedObjectNameException, NullPointerException { + throws MalformedObjectNameException { // If key or value are null a NullPointerException // will be thrown by the put method in Hashtable. // @@ -1533,9 +1649,11 @@ public class ObjectName implements Comparable, QueryExp { * values in table does not follow the rules for * quoting. * @exception NullPointerException One of the parameters is null. + * + * @see #valueOf(String, Hashtable) */ public ObjectName(String domain, Hashtable table) - throws MalformedObjectNameException, NullPointerException { + throws MalformedObjectNameException { construct(domain, table); /* The exception for when a key or value in the table is not a String is now ClassCastException rather than @@ -1629,8 +1747,7 @@ public class ObjectName implements Comparable, QueryExp { * * @since 1.6 */ - public boolean isPropertyValuePattern(String property) - throws NullPointerException, IllegalArgumentException { + public boolean isPropertyValuePattern(String property) { if (property == null) throw new NullPointerException("key property can't be null"); for (int i = 0; i < _ca_array.length; i++) { @@ -1691,7 +1808,7 @@ public class ObjectName implements Comparable, QueryExp { * * @exception NullPointerException If property is null. */ - public String getKeyProperty(String property) throws NullPointerException { + public String getKeyProperty(String property) { return _getKeyPropertyList().get(property); } @@ -1950,8 +2067,7 @@ public class ObjectName implements Comparable, QueryExp { * @exception NullPointerException if s is null. * */ - public static String quote(String s) - throws NullPointerException { + public static String quote(String s) { final StringBuilder buf = new StringBuilder("\""); final int len = s.length(); for (int i = 0; i < len; i++) { @@ -1995,8 +2111,7 @@ public class ObjectName implements Comparable, QueryExp { * @exception NullPointerException if q is null. * */ - public static String unquote(String q) - throws IllegalArgumentException, NullPointerException { + public static String unquote(String q) { final StringBuilder buf = new StringBuilder(); final int len = q.length(); if (len < 2 || q.charAt(0) != '"' || q.charAt(len - 1) != '"') @@ -2041,7 +2156,7 @@ public class ObjectName implements Comparable, QueryExp { * * @since 1.6 */ - public static final ObjectName WILDCARD = Util.newObjectName("*:*"); + public static final ObjectName WILDCARD = valueOf("*:*"); // Category : Utilities <=================================== @@ -2064,7 +2179,7 @@ public class ObjectName implements Comparable, QueryExp { * @exception NullPointerException if name is null. * */ - public boolean apply(ObjectName name) throws NullPointerException { + public boolean apply(ObjectName name) { if (name == null) throw new NullPointerException(); diff --git a/jdk/src/share/classes/javax/management/QueryNotificationFilter.java b/jdk/src/share/classes/javax/management/QueryNotificationFilter.java index 42451088f2e..7d1990fa2b9 100644 --- a/jdk/src/share/classes/javax/management/QueryNotificationFilter.java +++ b/jdk/src/share/classes/javax/management/QueryNotificationFilter.java @@ -170,7 +170,7 @@ public class QueryNotificationFilter implements NotificationFilter { private static final long serialVersionUID = -8408613922660635231L; private static final ObjectName DEFAULT_NAME = - Util.newObjectName(":type=Notification"); + ObjectName.valueOf(":type=Notification"); private static final QueryExp trueQuery; static { ValueExp zero = Query.value(0); diff --git a/jdk/src/share/classes/javax/management/event/EventClientDelegateMBean.java b/jdk/src/share/classes/javax/management/event/EventClientDelegateMBean.java index ba57cce9cb2..7c0b3107cc4 100644 --- a/jdk/src/share/classes/javax/management/event/EventClientDelegateMBean.java +++ b/jdk/src/share/classes/javax/management/event/EventClientDelegateMBean.java @@ -96,7 +96,7 @@ public interface EventClientDelegateMBean { * {@value #OBJECT_NAME_STRING}. */ public final static ObjectName OBJECT_NAME = - Util.newObjectName(OBJECT_NAME_STRING); + ObjectName.valueOf(OBJECT_NAME_STRING); /** * A unique listener identifier specified for an EventClient. diff --git a/jdk/src/share/classes/javax/management/namespace/MBeanServerSupport.java b/jdk/src/share/classes/javax/management/namespace/MBeanServerSupport.java index 2f0e1983822..903be3c308f 100644 --- a/jdk/src/share/classes/javax/management/namespace/MBeanServerSupport.java +++ b/jdk/src/share/classes/javax/management/namespace/MBeanServerSupport.java @@ -193,14 +193,6 @@ import javax.management.loading.ClassLoaderRepository; * } * * public class PropsMBS extends MBeanServerSupport { - * private static ObjectName newObjectName(String name) { - * try { - * return new ObjectName(name); - * } catch (MalformedObjectNameException e) { - * throw new AssertionError(e); - * } - * } - * * public static class PropertyImpl implements PropertyMBean { * private final String name; * @@ -219,7 +211,7 @@ import javax.management.loading.ClassLoaderRepository; * throws InstanceNotFoundException { * * // Check that the name is a legal one for a Property MBean - * ObjectName namePattern = newObjectName( + * ObjectName namePattern = ObjectName.valueOf( * "com.example:type=Property,name=\"*\""); * if (!namePattern.apply(name)) * throw new InstanceNotFoundException(name); @@ -239,7 +231,7 @@ import javax.management.loading.ClassLoaderRepository; * {@code Set names = new TreeSet();} * Properties props = System.getProperties(); * for (String propName : props.stringPropertyNames()) { - * ObjectName objectName = newObjectName( + * ObjectName objectName = ObjectName.valueOf( * "com.example:type=Property,name=" + * ObjectName.quote(propName)); * names.add(objectName); @@ -278,7 +270,7 @@ import javax.management.loading.ClassLoaderRepository; * } * * public void propertyChanged(String name, String newValue) { - * ObjectName objectName = newObjectName( + * ObjectName objectName = ObjectName.valueOf( * "com.example:type=Property,name=" + ObjectName.quote(name)); * Notification n = new Notification( * "com.example.property.changed", objectName, 0L, diff --git a/jdk/src/share/classes/sun/management/Util.java b/jdk/src/share/classes/sun/management/Util.java index 3c0997531c4..1da80830058 100644 --- a/jdk/src/share/classes/sun/management/Util.java +++ b/jdk/src/share/classes/sun/management/Util.java @@ -43,12 +43,8 @@ class Util { return (String[]) list.toArray(EMPTY_STRING_ARRAY); } - static ObjectName newObjectName(String name) { - return com.sun.jmx.mbeanserver.Util.newObjectName(name); - } - public static ObjectName newObjectName(String domainAndType, String name) { - return newObjectName(domainAndType + ",name=" + name); + return ObjectName.valueOf(domainAndType + ",name=" + name); } private static ManagementPermission monitorPermission = diff --git a/jdk/test/javax/management/ObjectName/ValueOfTest.java b/jdk/test/javax/management/ObjectName/ValueOfTest.java new file mode 100644 index 00000000000..4a68a3d4c5c --- /dev/null +++ b/jdk/test/javax/management/ObjectName/ValueOfTest.java @@ -0,0 +1,175 @@ +/* + * 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 6734813 + * @summary Test the ObjectName.valueOf methods + * @author Eamonn McManus + */ + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Hashtable; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; + +public class ValueOfTest { + public static void main(String[] args) throws Exception { + // Calls that should work + testPositive("d:foo=bar,baz=buh"); + testPositive("foo", "bar", "baz"); + Hashtable h = new Hashtable(); + h.put("foo", "bar"); + h.put("baz", "buh"); + testPositive("domain", h); + + // Calls that should not work + testNegative("d"); + testNegative("d:"); + testNegative("d::foo=bar"); + testNegative("d:", "foo", "bar"); + testNegative("d", "foo=", "bar"); + testNegative("d:", h); + testNegative("d", new Hashtable()); + } + + private static void testPositive(Object... args) throws Exception { + Method valueOf = valueOfMethod(args); + Method getInstance = getInstanceMethod(args); + Constructor constructor = constructor(args); + + Object valueOfValue = valueOf.invoke(null, args); + Object getInstanceValue = getInstance.invoke(null, args); + Object constructorValue = constructor.newInstance(args); + + String argString = + Arrays.toString(args).replace('[', '(').replace(']', ')'); + + if (!valueOfValue.equals(getInstanceValue)) { + throw new Exception( + "valueOf" + argString + " differs from getInstance" + + argString); + } + + if (!valueOfValue.equals(constructorValue)) { + throw new Exception( + "valueOf" + argString + " differs from new ObjectName " + + argString); + } + + System.out.println("OK: valueOf" + argString); + } + + private static void testNegative(Object... args) throws Exception { + Method valueOf = valueOfMethod(args); + Method getInstance = getInstanceMethod(args); + + String argString = + Arrays.toString(args).replace('[', '(').replace(']', ')'); + + final Throwable valueOfException; + try { + valueOf.invoke(null, args); + throw new Exception("valueOf" + argString + " did not fail but should"); + } catch (InvocationTargetException e) { + valueOfException = e.getCause(); + } + if (!(valueOfException instanceof IllegalArgumentException)) { + throw new Exception( + "valueOf" + argString + " threw " + + valueOfException.getClass().getName() + " instead of " + + "IllegalArgumentException", valueOfException); + } + + final Throwable valueOfCause = valueOfException.getCause(); + if (!(valueOfCause instanceof MalformedObjectNameException)) { + throw new Exception( + "valueOf" + argString + " threw exception with wrong " + + "type of cause", valueOfCause); + } + + if (!valueOfException.getMessage().equals(valueOfCause.getMessage())) { + // The IllegalArgumentException should have the same message as + // the MalformedObjectNameException it wraps. + // This isn't specified but is desirable. + throw new Exception( + "valueOf" + argString + ": message in wrapping " + + "IllegalArgumentException (" + valueOfException.getMessage() + + ") differs from message in wrapped " + + "MalformedObjectNameException (" + valueOfCause.getMessage() + + ")"); + } + + final Throwable getInstanceException; + try { + getInstance.invoke(null, args); + throw new Exception("getInstance" + argString + " did not fail but should"); + } catch (InvocationTargetException e) { + getInstanceException = e.getCause(); + } + if (!(getInstanceException instanceof MalformedObjectNameException)) { + throw new Exception( + "getInstance" + argString + " threw wrong exception", + getInstanceException); + } + + if (!valueOfException.getMessage().equals(getInstanceException.getMessage())) { + // Again this is not specified. + throw new Exception( + "Exception message from valueOf" + argString + " (" + + valueOfException.getMessage() + ") differs from message " + + "from getInstance" + argString + " (" + + getInstanceException.getMessage() + ")"); + } + + System.out.println("OK (correct exception): valueOf" + argString); + } + + private static Method valueOfMethod(Object[] args) throws Exception { + return method("valueOf", args); + } + + private static Method getInstanceMethod(Object[] args) throws Exception { + return method("getInstance", args); + } + + private static Method method(String name, Object[] args) throws Exception { + Class[] argTypes = argTypes(args); + return ObjectName.class.getMethod(name, argTypes); + } + + private static Constructor constructor(Object[] args) throws Exception { + Class[] argTypes = argTypes(args); + return ObjectName.class.getConstructor(argTypes); + } + + private static Class[] argTypes(Object[] args) { + Class[] argTypes = new Class[args.length]; + for (int i = 0; i < args.length; i++) + argTypes[i] = args[i].getClass(); + return argTypes; + } +} From 370ae84e7300d41a10ab12a5d55b97a6a7a33e0d Mon Sep 17 00:00:00 2001 From: Eamonn McManus Date: Wed, 10 Sep 2008 14:56:57 +0200 Subject: [PATCH 85/95] 6746759: Fix for 6734813 introduced build break Reviewed-by: dfuchs --- jdk/src/share/classes/sun/management/ClassLoadingImpl.java | 2 +- jdk/src/share/classes/sun/management/CompilationImpl.java | 2 +- jdk/src/share/classes/sun/management/HotSpotDiagnostic.java | 2 +- jdk/src/share/classes/sun/management/HotspotInternal.java | 2 +- .../share/classes/sun/management/ManagementFactoryHelper.java | 4 ++-- jdk/src/share/classes/sun/management/MemoryImpl.java | 2 +- jdk/src/share/classes/sun/management/OperatingSystemImpl.java | 2 +- jdk/src/share/classes/sun/management/RuntimeImpl.java | 2 +- jdk/src/share/classes/sun/management/ThreadImpl.java | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/jdk/src/share/classes/sun/management/ClassLoadingImpl.java b/jdk/src/share/classes/sun/management/ClassLoadingImpl.java index 2f4b6ed0731..9eda5838087 100644 --- a/jdk/src/share/classes/sun/management/ClassLoadingImpl.java +++ b/jdk/src/share/classes/sun/management/ClassLoadingImpl.java @@ -71,6 +71,6 @@ class ClassLoadingImpl implements ClassLoadingMXBean { native static void setVerboseClass(boolean value); public ObjectName getObjectName() { - return Util.newObjectName(ManagementFactory.CLASS_LOADING_MXBEAN_NAME); + return ObjectName.valueOf(ManagementFactory.CLASS_LOADING_MXBEAN_NAME); } } diff --git a/jdk/src/share/classes/sun/management/CompilationImpl.java b/jdk/src/share/classes/sun/management/CompilationImpl.java index d69d9cc641e..9c13e67ebd7 100644 --- a/jdk/src/share/classes/sun/management/CompilationImpl.java +++ b/jdk/src/share/classes/sun/management/CompilationImpl.java @@ -70,7 +70,7 @@ class CompilationImpl implements CompilationMXBean { } public ObjectName getObjectName() { - return Util.newObjectName(ManagementFactory.COMPILATION_MXBEAN_NAME); + return ObjectName.valueOf(ManagementFactory.COMPILATION_MXBEAN_NAME); } diff --git a/jdk/src/share/classes/sun/management/HotSpotDiagnostic.java b/jdk/src/share/classes/sun/management/HotSpotDiagnostic.java index f42188ff135..d33337fcf9f 100644 --- a/jdk/src/share/classes/sun/management/HotSpotDiagnostic.java +++ b/jdk/src/share/classes/sun/management/HotSpotDiagnostic.java @@ -117,6 +117,6 @@ public class HotSpotDiagnostic implements HotSpotDiagnosticMXBean { } public ObjectName getObjectName() { - return Util.newObjectName("com.sun.management:type=HotSpotDiagnostic"); + return ObjectName.valueOf("com.sun.management:type=HotSpotDiagnostic"); } } diff --git a/jdk/src/share/classes/sun/management/HotspotInternal.java b/jdk/src/share/classes/sun/management/HotspotInternal.java index 7006699a4d9..88f9a82680c 100644 --- a/jdk/src/share/classes/sun/management/HotspotInternal.java +++ b/jdk/src/share/classes/sun/management/HotspotInternal.java @@ -41,7 +41,7 @@ public class HotspotInternal private final static String HOTSPOT_INTERNAL_MBEAN_NAME = "sun.management:type=HotspotInternal"; - private static ObjectName objName = Util.newObjectName(HOTSPOT_INTERNAL_MBEAN_NAME); + private static ObjectName objName = ObjectName.valueOf(HOTSPOT_INTERNAL_MBEAN_NAME); private MBeanServer server = null; /** diff --git a/jdk/src/share/classes/sun/management/ManagementFactoryHelper.java b/jdk/src/share/classes/sun/management/ManagementFactoryHelper.java index 9bb4785d7ee..c07acfdbc61 100644 --- a/jdk/src/share/classes/sun/management/ManagementFactoryHelper.java +++ b/jdk/src/share/classes/sun/management/ManagementFactoryHelper.java @@ -220,7 +220,7 @@ public class ManagementFactoryHelper { */ private static void addMBean(MBeanServer mbs, Object mbean, String mbeanName) { try { - final ObjectName objName = Util.newObjectName(mbeanName); + final ObjectName objName = ObjectName.valueOf(mbeanName); // inner class requires these fields to be final final MBeanServer mbs0 = mbs; @@ -280,7 +280,7 @@ public class ManagementFactoryHelper { private static void unregisterMBean(MBeanServer mbs, String mbeanName) { try { - final ObjectName objName = Util.newObjectName(mbeanName); + final ObjectName objName = ObjectName.valueOf(mbeanName); // inner class requires these fields to be final final MBeanServer mbs0 = mbs; diff --git a/jdk/src/share/classes/sun/management/MemoryImpl.java b/jdk/src/share/classes/sun/management/MemoryImpl.java index 29da467ce0b..aa56186ae59 100644 --- a/jdk/src/share/classes/sun/management/MemoryImpl.java +++ b/jdk/src/share/classes/sun/management/MemoryImpl.java @@ -177,7 +177,7 @@ class MemoryImpl extends NotificationEmitterSupport } public ObjectName getObjectName() { - return Util.newObjectName(ManagementFactory.MEMORY_MXBEAN_NAME); + return ObjectName.valueOf(ManagementFactory.MEMORY_MXBEAN_NAME); } } diff --git a/jdk/src/share/classes/sun/management/OperatingSystemImpl.java b/jdk/src/share/classes/sun/management/OperatingSystemImpl.java index cfe729688a7..9ab8b5695ce 100644 --- a/jdk/src/share/classes/sun/management/OperatingSystemImpl.java +++ b/jdk/src/share/classes/sun/management/OperatingSystemImpl.java @@ -74,7 +74,7 @@ public class OperatingSystemImpl implements OperatingSystemMXBean { } } public ObjectName getObjectName() { - return Util.newObjectName(ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME); + return ObjectName.valueOf(ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME); } } diff --git a/jdk/src/share/classes/sun/management/RuntimeImpl.java b/jdk/src/share/classes/sun/management/RuntimeImpl.java index e58040e8388..55bcbdc85f4 100644 --- a/jdk/src/share/classes/sun/management/RuntimeImpl.java +++ b/jdk/src/share/classes/sun/management/RuntimeImpl.java @@ -149,7 +149,7 @@ class RuntimeImpl implements RuntimeMXBean { } public ObjectName getObjectName() { - return Util.newObjectName(ManagementFactory.RUNTIME_MXBEAN_NAME); + return ObjectName.valueOf(ManagementFactory.RUNTIME_MXBEAN_NAME); } } diff --git a/jdk/src/share/classes/sun/management/ThreadImpl.java b/jdk/src/share/classes/sun/management/ThreadImpl.java index d12258b9ea5..565966e9ddd 100644 --- a/jdk/src/share/classes/sun/management/ThreadImpl.java +++ b/jdk/src/share/classes/sun/management/ThreadImpl.java @@ -415,7 +415,7 @@ class ThreadImpl implements ThreadMXBean { private static native void resetContentionTimes0(long tid); public ObjectName getObjectName() { - return Util.newObjectName(ManagementFactory.THREAD_MXBEAN_NAME); + return ObjectName.valueOf(ManagementFactory.THREAD_MXBEAN_NAME); } } From b2e851f920d8a22366dad9414d9030ad0e2f05b4 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Wed, 10 Sep 2008 16:27:13 +0200 Subject: [PATCH 86/95] 6746754: jmx namespace: test for leading separator missing 6669137: RFE: InstanceNotFoundException should have a constructor that takes an ObjectName 6746796: jmx namespaces: Several tests are missing an @bug or @run keyword Note on 6669137: first implementation of 6669137 was actually pushed with 5072476 - here we only have a small update and a test case. Also re-fixes 6737133: Compilation failure of test/javax/management/eventService/LeaseManagerDeadlockTest.java which had failed. Reviewed-by: emcmanus, yjoan --- .../com/sun/jmx/namespace/RoutingProxy.java | 17 +- .../management/InstanceNotFoundException.java | 2 +- .../InstanceNotFoundExceptionTest.java | 76 ++++++ .../NamedMBeanServerTest.java | 1 + .../LeaseManagerDeadlockTest.java | 1 + .../namespace/DomainCreationTest.java | 1 + .../EventWithNamespaceControlTest.java | 1 + .../namespace/EventWithNamespaceTest.java | 2 +- .../namespace/ExportNamespaceTest.java | 1 + .../management/namespace/JMXDomainTest.java | 1 + .../namespace/JMXNamespaceSecurityTest.java | 1 + .../namespace/JMXNamespaceTest.java | 1 + .../namespace/JMXNamespaceViewTest.java | 1 + .../namespace/JMXNamespacesTest.java | 1 + .../namespace/JMXRemoteNamespaceTest.java | 1 + .../management/namespace/LazyDomainTest.java | 1 + .../namespace/LeadingSeparatorsTest.java | 227 ++++++++++++++++++ .../namespace/NamespaceCreationTest.java | 1 + .../namespace/NamespaceNotificationsTest.java | 1 + .../namespace/NullObjectNameTest.java | 1 + .../management/namespace/QueryNamesTest.java | 1 + .../RemoveNotificationListenerTest.java | 1 + .../namespace/RoutingServerProxyTest.java | 1 + .../namespace/SerialParamProcessorTest.java | 1 + .../namespace/SourceNamespaceTest.java | 1 + .../namespace/VirtualMBeanNotifTest.java | 1 + .../namespace/VirtualMBeanTest.java | 2 +- .../namespace/VirtualNamespaceQueryTest.java | 1 + .../namespace/VirtualPropsTest.java | 2 +- 29 files changed, 344 insertions(+), 6 deletions(-) create mode 100644 jdk/test/javax/management/MBeanServer/InstanceNotFoundExceptionTest.java create mode 100644 jdk/test/javax/management/namespace/LeadingSeparatorsTest.java diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingProxy.java b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingProxy.java index e0635c585cf..aa35c5bdaed 100644 --- a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingProxy.java +++ b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingProxy.java @@ -48,6 +48,19 @@ import javax.management.namespace.JMXNamespaces; *

{@link RoutingConnectionProxy}: to narrow down into an * MBeanServerConnection.

*

{@link RoutingServerProxy}: to narrow down into an MBeanServer.

+ * + *

This class can also be used to "broaden" from a namespace. The same + * class is used for both purposes because in both cases all that happens + * is that ObjectNames are rewritten in one way on the way in (e.g. the + * parameter of getMBeanInfo) and another way on the way out (e.g. the + * return value of queryNames).

+ * + *

Specifically, if you narrow into "a//" then you want to add the + * "a//" prefix to ObjectNames on the way in and subtract it on the way + * out. But ClientContext uses this class to subtract the + * "jmx.context//foo=bar//" prefix on the way in and add it back on the + * way out.

+ * *

* This API is a Sun internal API and is subject to changes without notice. *

@@ -245,8 +258,8 @@ public abstract class RoutingProxy throw x; } catch (MBeanException ex) { throw new IOException("Failed to get "+attributeName+": "+ - ex, - ex.getTargetException()); + ex.getCause(), + ex.getCause()); } catch (Exception ex) { throw new IOException("Failed to get "+attributeName+": "+ ex,ex); diff --git a/jdk/src/share/classes/javax/management/InstanceNotFoundException.java b/jdk/src/share/classes/javax/management/InstanceNotFoundException.java index baeaed09500..3a8376f7baf 100644 --- a/jdk/src/share/classes/javax/management/InstanceNotFoundException.java +++ b/jdk/src/share/classes/javax/management/InstanceNotFoundException.java @@ -61,6 +61,6 @@ public class InstanceNotFoundException extends OperationsException { * @since 1.7 */ public InstanceNotFoundException(ObjectName name) { - this(name.toString()); + this(String.valueOf(name)); } } diff --git a/jdk/test/javax/management/MBeanServer/InstanceNotFoundExceptionTest.java b/jdk/test/javax/management/MBeanServer/InstanceNotFoundExceptionTest.java new file mode 100644 index 00000000000..30079655385 --- /dev/null +++ b/jdk/test/javax/management/MBeanServer/InstanceNotFoundExceptionTest.java @@ -0,0 +1,76 @@ +/* + * 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 6669137 + * @summary Test the constructors of InstanceNotFoundExceptionTest. + * @author Daniel Fuchs + * @compile InstanceNotFoundExceptionTest.java + * @run main InstanceNotFoundExceptionTest + */ + +import javax.management.InstanceNotFoundException; +import javax.management.ObjectName; + +public class InstanceNotFoundExceptionTest { + public static void main(String[] args) throws Exception { + final InstanceNotFoundException x = + new InstanceNotFoundException(); + System.out.println("InstanceNotFoundException(): "+x.getMessage()); + + final String msg = "who is toto?"; + final InstanceNotFoundException x2 = + new InstanceNotFoundException(msg); + if (!msg.equals(x2.getMessage())) + throw new Exception("Bad message: expected "+msg+ + ", got "+x2.getMessage()); + System.out.println("InstanceNotFoundException(" + + msg+"): "+x2.getMessage()); + + final InstanceNotFoundException x3 = + new InstanceNotFoundException((String)null); + if (x3.getMessage() != null) + throw new Exception("Bad message: expected "+null+ + ", got "+x3.getMessage()); + System.out.println("InstanceNotFoundException((String)null): "+ + x3.getMessage()); + + final ObjectName n = new ObjectName("who is toto?:type=msg"); + final InstanceNotFoundException x4 = + new InstanceNotFoundException(n); + if (!String.valueOf(n).equals(x4.getMessage())) + throw new Exception("Bad message: expected "+n+ + ", got "+x4.getMessage()); + System.out.println("InstanceNotFoundException(" + + n+"): "+x4.getMessage()); + + final InstanceNotFoundException x5 = + new InstanceNotFoundException((ObjectName)null); + if (!String.valueOf((ObjectName)null).equals(x5.getMessage())) + throw new Exception("Bad message: expected " + + String.valueOf((ObjectName)null)+" got "+x5.getMessage()); + System.out.println("InstanceNotFoundException((ObjectName)null): "+ + x5.getMessage()); + } +} diff --git a/jdk/test/javax/management/MBeanServerFactory/NamedMBeanServerTest.java b/jdk/test/javax/management/MBeanServerFactory/NamedMBeanServerTest.java index e2616831865..8a8d248cbda 100644 --- a/jdk/test/javax/management/MBeanServerFactory/NamedMBeanServerTest.java +++ b/jdk/test/javax/management/MBeanServerFactory/NamedMBeanServerTest.java @@ -25,6 +25,7 @@ * @test * @summary Test named MBeanServers. * @author Daniel Fuchs + * @bug 6299231 * @run clean NamedMBeanServerTest * @run build NamedMBeanServerTest * @run main NamedMBeanServerTest diff --git a/jdk/test/javax/management/eventService/LeaseManagerDeadlockTest.java b/jdk/test/javax/management/eventService/LeaseManagerDeadlockTest.java index 453aafe4bd0..ab7d14d54f2 100644 --- a/jdk/test/javax/management/eventService/LeaseManagerDeadlockTest.java +++ b/jdk/test/javax/management/eventService/LeaseManagerDeadlockTest.java @@ -27,6 +27,7 @@ * @summary Check that a lock is not held when a LeaseManager expires. * @author Eamonn McManus * @compile -XDignore.symbol.file=true LeaseManagerDeadlockTest.java + * @run main LeaseManagerDeadlockTest */ import com.sun.jmx.event.LeaseManager; diff --git a/jdk/test/javax/management/namespace/DomainCreationTest.java b/jdk/test/javax/management/namespace/DomainCreationTest.java index 93a98dc6210..02a09868e13 100644 --- a/jdk/test/javax/management/namespace/DomainCreationTest.java +++ b/jdk/test/javax/management/namespace/DomainCreationTest.java @@ -23,6 +23,7 @@ /* * * @test DomainCreationTest.java + * @bug 5072476 * @summary Test the creation and registration of JMXDomain instances. * @author Daniel Fuchs * @run clean DomainCreationTest Wombat WombatMBean diff --git a/jdk/test/javax/management/namespace/EventWithNamespaceControlTest.java b/jdk/test/javax/management/namespace/EventWithNamespaceControlTest.java index c1e5a9d4647..1e3901104c7 100644 --- a/jdk/test/javax/management/namespace/EventWithNamespaceControlTest.java +++ b/jdk/test/javax/management/namespace/EventWithNamespaceControlTest.java @@ -27,6 +27,7 @@ * @summary Check -Djmx.remote.use.event.service=true and * -Djmx.remote.delegate.event.service * @author Daniel Fuchs + * @bug 5072476 5108776 * @run clean EventWithNamespaceTest EventWithNamespaceControlTest * Wombat WombatMBean JMXRemoteTargetNamespace * NamespaceController NamespaceControllerMBean diff --git a/jdk/test/javax/management/namespace/EventWithNamespaceTest.java b/jdk/test/javax/management/namespace/EventWithNamespaceTest.java index 44fca88c7a4..748fdbeff14 100644 --- a/jdk/test/javax/management/namespace/EventWithNamespaceTest.java +++ b/jdk/test/javax/management/namespace/EventWithNamespaceTest.java @@ -24,7 +24,7 @@ /* * * @test EventWithNamespaceTest.java 1.8 - * @bug 6539857 + * @bug 6539857 5072476 5108776 * @summary General Namespace & Notifications test. * @author Daniel Fuchs * @run clean EventWithNamespaceTest Wombat WombatMBean diff --git a/jdk/test/javax/management/namespace/ExportNamespaceTest.java b/jdk/test/javax/management/namespace/ExportNamespaceTest.java index e734527141c..ec49a4c0c0c 100644 --- a/jdk/test/javax/management/namespace/ExportNamespaceTest.java +++ b/jdk/test/javax/management/namespace/ExportNamespaceTest.java @@ -26,6 +26,7 @@ * @summary Test that you can export a single namespace through a * JMXConnectorServer. * @author Daniel Fuchs + * @bug 5072476 * @run clean ExportNamespaceTest Wombat WombatMBean * @run build ExportNamespaceTest Wombat WombatMBean * @run main ExportNamespaceTest diff --git a/jdk/test/javax/management/namespace/JMXDomainTest.java b/jdk/test/javax/management/namespace/JMXDomainTest.java index 4a1a14e96dd..258cead1ab0 100644 --- a/jdk/test/javax/management/namespace/JMXDomainTest.java +++ b/jdk/test/javax/management/namespace/JMXDomainTest.java @@ -23,6 +23,7 @@ /* * * @test JMXDomainTest.java + * @bug 5072476 * @summary Basic test for JMXDomain. * @author Daniel Fuchs * @run clean JMXDomainTest Wombat WombatMBean diff --git a/jdk/test/javax/management/namespace/JMXNamespaceSecurityTest.java b/jdk/test/javax/management/namespace/JMXNamespaceSecurityTest.java index b948012f1e9..213ffbfb63e 100644 --- a/jdk/test/javax/management/namespace/JMXNamespaceSecurityTest.java +++ b/jdk/test/javax/management/namespace/JMXNamespaceSecurityTest.java @@ -26,6 +26,7 @@ * @test JMXNamespaceSecurityTest.java * @summary General JMXNamespaceSecurityTest test. * @author Daniel Fuchs + * @bug 5072476 6299231 * @run clean JMXNamespaceViewTest JMXNamespaceSecurityTest Wombat WombatMBean * LazyDomainTest * @run build JMXNamespaceSecurityTest JMXNamespaceViewTest Wombat WombatMBean diff --git a/jdk/test/javax/management/namespace/JMXNamespaceTest.java b/jdk/test/javax/management/namespace/JMXNamespaceTest.java index da553f9c8e2..1c2ffac9d6b 100644 --- a/jdk/test/javax/management/namespace/JMXNamespaceTest.java +++ b/jdk/test/javax/management/namespace/JMXNamespaceTest.java @@ -25,6 +25,7 @@ * * @test JMXNamespaceTest.java * @summary General JMXNamespace test. + * @bug 5072476 * @author Daniel Fuchs * @run clean JMXNamespaceTest * Wombat WombatMBean JMXRemoteTargetNamespace diff --git a/jdk/test/javax/management/namespace/JMXNamespaceViewTest.java b/jdk/test/javax/management/namespace/JMXNamespaceViewTest.java index ad51af3014d..e134968296b 100644 --- a/jdk/test/javax/management/namespace/JMXNamespaceViewTest.java +++ b/jdk/test/javax/management/namespace/JMXNamespaceViewTest.java @@ -24,6 +24,7 @@ * * @test JMXNamespaceViewTest.java * @summary Test the JMXNamespaceView class. + * @bug 5072476 * @author Daniel Fuchs * @run clean JMXNamespaceViewTest Wombat WombatMBean * @run build JMXNamespaceViewTest Wombat WombatMBean diff --git a/jdk/test/javax/management/namespace/JMXNamespacesTest.java b/jdk/test/javax/management/namespace/JMXNamespacesTest.java index 4249bf10403..4dc7c518a1a 100644 --- a/jdk/test/javax/management/namespace/JMXNamespacesTest.java +++ b/jdk/test/javax/management/namespace/JMXNamespacesTest.java @@ -24,6 +24,7 @@ * @test JMXNamespacesTest.java * @summary Test the static method that rewrite ObjectNames in JMXNamespacesTest * @author Daniel Fuchs + * @bug 5072476 * @run clean JMXNamespacesTest * @compile -XDignore.symbol.file=true JMXNamespacesTest.java * @run main JMXNamespacesTest diff --git a/jdk/test/javax/management/namespace/JMXRemoteNamespaceTest.java b/jdk/test/javax/management/namespace/JMXRemoteNamespaceTest.java index ccc73bfaf26..8e5f795a6ba 100644 --- a/jdk/test/javax/management/namespace/JMXRemoteNamespaceTest.java +++ b/jdk/test/javax/management/namespace/JMXRemoteNamespaceTest.java @@ -25,6 +25,7 @@ * @test JMXRemoteNamespaceTest.java * @summary Basic tests on a JMXRemoteNamespace. * @author Daniel Fuchs + * @bug 5072476 * @run clean JMXRemoteNamespaceTest Wombat WombatMBean * @run build JMXRemoteNamespaceTest Wombat WombatMBean * @run main JMXRemoteNamespaceTest diff --git a/jdk/test/javax/management/namespace/LazyDomainTest.java b/jdk/test/javax/management/namespace/LazyDomainTest.java index 83439011ed7..eda9b66696d 100644 --- a/jdk/test/javax/management/namespace/LazyDomainTest.java +++ b/jdk/test/javax/management/namespace/LazyDomainTest.java @@ -23,6 +23,7 @@ /* * * @test LazyDomainTest.java + * @bug 5072476 * @summary Basic test for Lazy Domains. * @author Daniel Fuchs * @run clean LazyDomainTest Wombat WombatMBean diff --git a/jdk/test/javax/management/namespace/LeadingSeparatorsTest.java b/jdk/test/javax/management/namespace/LeadingSeparatorsTest.java new file mode 100644 index 00000000000..5660b275317 --- /dev/null +++ b/jdk/test/javax/management/namespace/LeadingSeparatorsTest.java @@ -0,0 +1,227 @@ +/* + * 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 LeadingSeparatorsTest.java + * @summary Test that the semantics of a leading // in ObjectName is respected. + * @author Daniel Fuchs + * @bug 5072476 + * @run clean LeadingSeparatorsTest Wombat WombatMBean + * @compile -XDignore.symbol.file=true LeadingSeparatorsTest.java + * @run build LeadingSeparatorsTest Wombat WombatMBean + * @run main LeadingSeparatorsTest + */ + +import java.lang.management.ManagementFactory; +import java.util.Arrays; +import java.util.Set; +import java.util.HashSet; +import java.util.logging.Logger; +import javax.management.MBeanServer; +import javax.management.MBeanServerFactory; +import javax.management.NotCompliantMBeanException; +import javax.management.ObjectName; +import javax.management.namespace.JMXNamespaces; +import javax.management.namespace.JMXRemoteNamespace; +import javax.management.namespace.JMXNamespace; +import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXConnectorServerFactory; +import javax.management.remote.JMXServiceURL; + +/** + * Class LeadingSeparatorsTest + * @author Sun Microsystems, 2005 - All rights reserved. + */ +public class LeadingSeparatorsTest { + + /** + * A logger for this class. + **/ + private static final Logger LOG = + Logger.getLogger(LeadingSeparatorsTest.class.getName()); + + /** Creates a new instance of NullObjectNameTest */ + public LeadingSeparatorsTest() { + } + + public static interface MyWombatMBean extends WombatMBean { + public Set untrue(ObjectName pat) throws Exception; + } + public static class MyWombat + extends Wombat implements MyWombatMBean { + public MyWombat() throws NotCompliantMBeanException { + super(MyWombatMBean.class); + } + + public Set untrue(ObjectName pat) throws Exception { + final Set res=listMatching(pat.withDomain("*")); + final Set untrue = new HashSet(); + for (ObjectName a:res) { + untrue.add(a.withDomain(pat.getDomain()+"//"+a.getDomain())); + } + return untrue; + } + } + + static String failure=null; + + public static void testRegister() throws Exception { + final MBeanServer top = ManagementFactory.getPlatformMBeanServer(); + final MBeanServer sub = MBeanServerFactory.createMBeanServer(); + final JMXServiceURL url = new JMXServiceURL("rmi",null,0); + final JMXConnectorServer srv = + JMXConnectorServerFactory.newJMXConnectorServer(url,null,sub); + srv.start(); + + try { + + // Create a namespace rmi// that points to 'sub' and flows through + // a JMXRemoteNamespace connected to 'srv' + // The namespace rmi// will accept createMBean, but not registerMBean. + // + final JMXRemoteNamespace rmiHandler = JMXRemoteNamespace. + newJMXRemoteNamespace(srv.getAddress(),null); + top.registerMBean(rmiHandler, + JMXNamespaces.getNamespaceObjectName("rmi")); + top.invoke(JMXNamespaces.getNamespaceObjectName("rmi"), + "connect", null, null); + + // Create a namespace direct// that points to 'sub' and flows + // through a direct reference to 'sub'. + // The namespace direct// will accept createMBean, and registerMBean. + // + final JMXNamespace directHandler = new JMXNamespace(sub); + top.registerMBean(directHandler, + JMXNamespaces.getNamespaceObjectName("direct")); + + final ObjectName n1 = new ObjectName("//direct//w:type=Wombat"); + final ObjectName n2 = new ObjectName("direct//w:type=Wombat"); + final ObjectName n3 = new ObjectName("//rmi//w:type=Wombat"); + final ObjectName n4 = new ObjectName("rmi//w:type=Wombat"); + + // register wombat using an object name with a leading // + final Object obj = new MyWombat(); + // check that returned object name doesn't have the leading // + assertEquals(n2,top.registerMBean(obj, n1).getObjectName()); + System.out.println(n1+" registered"); + + // check that the registered Wombat can be accessed with all its + // names. + System.out.println(n2+" mood is: "+top.getAttribute(n2, "Mood")); + System.out.println(n1+" mood is: "+top.getAttribute(n1, "Mood")); + System.out.println(n4+" mood is: "+top.getAttribute(n4, "Mood")); + System.out.println(n3+" mood is: "+top.getAttribute(n3, "Mood")); + + // call listMatching. The result should not contain any prefix. + final Set res = (Set) + top.invoke(n3, "listMatching", + // remove rmi// from rmi//*:* + JMXNamespaces.deepReplaceHeadNamespace( + new Object[] {ObjectName.WILDCARD.withDomain("rmi//*")}, + "rmi", ""), new String[] {ObjectName.class.getName()}); + + // add rmi// prefix to all names in res. + final Set res1 = + JMXNamespaces.deepReplaceHeadNamespace(res, "", "rmi"); + System.out.println("got: "+res1); + + // compute expected result + final Set res2 = sub.queryNames(null,null); + final Set res3 = new HashSet(); + for (ObjectName o:res2) { + res3.add(o.withDomain("rmi//"+o.getDomain())); + } + System.out.println("expected: "+res3); + assertEquals(res1, res3); + + // invoke "untrue(//niark//niark:*)" + // should return a set were all ObjectNames begin with + // //niark//niark// + // + final Set res4 = (Set) + top.invoke(n3, "untrue", + // remove niark//niark : should remove nothing since + // our ObjectName begins with a leading // + JMXNamespaces.deepReplaceHeadNamespace( + new Object[] { + ObjectName.WILDCARD.withDomain("//niark//niark")}, + "niark//niark", ""), + new String[] {ObjectName.class.getName()}); + System.out.println("got: "+res4); + + // add rmi// should add nothing since the returned names have a + // leading // + // + final Set res5 = + JMXNamespaces.deepReplaceHeadNamespace(res4, "", "rmi"); + System.out.println("got#2: "+res5); + + // compute expected result + final Set res6 = new HashSet(); + for (ObjectName o:res2) { + res6.add(o.withDomain("//niark//niark//"+o.getDomain())); + } + System.out.println("expected: "+res6); + + // both res4 and res5 should be equals to the expected result. + assertEquals(res4, res6); + assertEquals(res5, res6); + + } finally { + srv.stop(); + } + + if (failure != null) + throw new Exception(failure); + + + } + private static void assertEquals(Object x, Object y) { + if (!equal(x, y)) + failed("expected " + string(x) + "; got " + string(y)); + } + + private static boolean equal(Object x, Object y) { + if (x == y) + return true; + if (x == null || y == null) + return false; + if (x.getClass().isArray()) + return Arrays.deepEquals(new Object[] {x}, new Object[] {y}); + return x.equals(y); + } + + private static String string(Object x) { + String s = Arrays.deepToString(new Object[] {x}); + return s.substring(1, s.length() - 1); + } + + + private static void failed(String why) { + failure = why; + new Throwable("FAILED: " + why).printStackTrace(System.out); + } + + public static void main(String[] args) throws Exception { + testRegister(); + } +} diff --git a/jdk/test/javax/management/namespace/NamespaceCreationTest.java b/jdk/test/javax/management/namespace/NamespaceCreationTest.java index 981cdda42ed..871bf022052 100644 --- a/jdk/test/javax/management/namespace/NamespaceCreationTest.java +++ b/jdk/test/javax/management/namespace/NamespaceCreationTest.java @@ -25,6 +25,7 @@ * @test NamespaceCreationTest.java * @summary General JMXNamespace test. * @author Daniel Fuchs + * @bug 5072476 * @run clean NamespaceCreationTest Wombat WombatMBean * @run build NamespaceCreationTest Wombat WombatMBean * @run main NamespaceCreationTest diff --git a/jdk/test/javax/management/namespace/NamespaceNotificationsTest.java b/jdk/test/javax/management/namespace/NamespaceNotificationsTest.java index ae5bb3c5939..9c5a1a04a1c 100644 --- a/jdk/test/javax/management/namespace/NamespaceNotificationsTest.java +++ b/jdk/test/javax/management/namespace/NamespaceNotificationsTest.java @@ -25,6 +25,7 @@ * * @test NamespaceNotificationsTest.java 1.12 * @summary General Namespace & Notifications test. + * @bug 5072476 * @author Daniel Fuchs * @run clean NamespaceNotificationsTest * Wombat WombatMBean JMXRemoteTargetNamespace diff --git a/jdk/test/javax/management/namespace/NullObjectNameTest.java b/jdk/test/javax/management/namespace/NullObjectNameTest.java index 7624fb9d9f2..156e7661db5 100644 --- a/jdk/test/javax/management/namespace/NullObjectNameTest.java +++ b/jdk/test/javax/management/namespace/NullObjectNameTest.java @@ -24,6 +24,7 @@ * @test NullObjectNameTest.java * @summary Test that null ObjectName are correctly handled in namespaces. * @author Daniel Fuchs + * @bug 5072476 * @run clean NullObjectNameTest Wombat WombatMBean * @compile -XDignore.symbol.file=true NullObjectNameTest.java * @run build NullObjectNameTest Wombat WombatMBean diff --git a/jdk/test/javax/management/namespace/QueryNamesTest.java b/jdk/test/javax/management/namespace/QueryNamesTest.java index 6e15c9a7587..1af597aceb9 100644 --- a/jdk/test/javax/management/namespace/QueryNamesTest.java +++ b/jdk/test/javax/management/namespace/QueryNamesTest.java @@ -25,6 +25,7 @@ * @test QueryNamesTest.java 1.4 * @summary Test how queryNames works with Namespaces. * @author Daniel Fuchs + * @bug 5072476 * @run clean QueryNamesTest Wombat WombatMBean * @run build QueryNamesTest Wombat WombatMBean * @run main QueryNamesTest diff --git a/jdk/test/javax/management/namespace/RemoveNotificationListenerTest.java b/jdk/test/javax/management/namespace/RemoveNotificationListenerTest.java index 08375c0dbad..a8ea2aee376 100644 --- a/jdk/test/javax/management/namespace/RemoveNotificationListenerTest.java +++ b/jdk/test/javax/management/namespace/RemoveNotificationListenerTest.java @@ -25,6 +25,7 @@ * @test RemoveNotificationListenerTest.java 1.8 * @summary General RemoveNotificationListenerTest test. * @author Daniel Fuchs + * @bug 5072476 * @run clean RemoveNotificationListenerTest JMXRemoteTargetNamespace * @compile -XDignore.symbol.file=true JMXRemoteTargetNamespace.java * @run build RemoveNotificationListenerTest JMXRemoteTargetNamespace diff --git a/jdk/test/javax/management/namespace/RoutingServerProxyTest.java b/jdk/test/javax/management/namespace/RoutingServerProxyTest.java index c0302698cf2..698021321d1 100644 --- a/jdk/test/javax/management/namespace/RoutingServerProxyTest.java +++ b/jdk/test/javax/management/namespace/RoutingServerProxyTest.java @@ -25,6 +25,7 @@ * @test RoutingServerProxyTest.java 1.6 * @summary General RoutingServerProxyTest test. * @author Daniel Fuchs + * @bug 5072476 * @run clean RoutingServerProxyTest Wombat WombatMBean * @compile -XDignore.symbol.file=true RoutingServerProxyTest.java * @run build RoutingServerProxyTest Wombat WombatMBean diff --git a/jdk/test/javax/management/namespace/SerialParamProcessorTest.java b/jdk/test/javax/management/namespace/SerialParamProcessorTest.java index 26dd77572a5..20df761d0e2 100644 --- a/jdk/test/javax/management/namespace/SerialParamProcessorTest.java +++ b/jdk/test/javax/management/namespace/SerialParamProcessorTest.java @@ -26,6 +26,7 @@ * @test SerialParamProcessorTest.java 1.8 * @summary General SerialParamProcessorTest test. * @author Daniel Fuchs + * @bug 5072476 * @run clean SerialParamProcessorTest Wombat WombatMBean * @compile -XDignore.symbol.file=true SerialParamProcessorTest.java * @run build SerialParamProcessorTest Wombat WombatMBean diff --git a/jdk/test/javax/management/namespace/SourceNamespaceTest.java b/jdk/test/javax/management/namespace/SourceNamespaceTest.java index 745564b8c3d..2335eb29708 100644 --- a/jdk/test/javax/management/namespace/SourceNamespaceTest.java +++ b/jdk/test/javax/management/namespace/SourceNamespaceTest.java @@ -24,6 +24,7 @@ * * @test SourceNamespaceTest.java * @summary Test how queryNames works with Namespaces. + * @bug 5072476 * @author Daniel Fuchs * @run clean SourceNamespaceTest Wombat WombatMBean * @run build SourceNamespaceTest Wombat WombatMBean diff --git a/jdk/test/javax/management/namespace/VirtualMBeanNotifTest.java b/jdk/test/javax/management/namespace/VirtualMBeanNotifTest.java index 301af7acd79..cc7bbaf95b3 100644 --- a/jdk/test/javax/management/namespace/VirtualMBeanNotifTest.java +++ b/jdk/test/javax/management/namespace/VirtualMBeanNotifTest.java @@ -25,6 +25,7 @@ * @test VirtualMBeanNotifTest.java * @bug 5108776 * @build VirtualMBeanNotifTest Wombat WombatMBean + * @run main VirtualMBeanNotifTest * @summary Test that Virtual MBeans can be implemented and emit notifs. * @author Daniel Fuchs */ diff --git a/jdk/test/javax/management/namespace/VirtualMBeanTest.java b/jdk/test/javax/management/namespace/VirtualMBeanTest.java index 85860df348e..03fd3983e63 100644 --- a/jdk/test/javax/management/namespace/VirtualMBeanTest.java +++ b/jdk/test/javax/management/namespace/VirtualMBeanTest.java @@ -23,7 +23,7 @@ /* * @test VirtualMBeanTest.java - * @bug 5108776 + * @bug 5108776 5072476 * @summary Test that Virtual MBeans can be implemented and emit notifs. * @author Eamonn McManus */ diff --git a/jdk/test/javax/management/namespace/VirtualNamespaceQueryTest.java b/jdk/test/javax/management/namespace/VirtualNamespaceQueryTest.java index 020c1224fac..8af244a7bc2 100644 --- a/jdk/test/javax/management/namespace/VirtualNamespaceQueryTest.java +++ b/jdk/test/javax/management/namespace/VirtualNamespaceQueryTest.java @@ -26,6 +26,7 @@ * @test VirtualNamespaceQueryTest.java * @summary General VirtualNamespaceQueryTest test. * @author Daniel Fuchs + * @bug 5072476 * @run clean VirtualNamespaceQueryTest Wombat WombatMBean * NamespaceController NamespaceControllerMBean * JMXRemoteTargetNamespace diff --git a/jdk/test/javax/management/namespace/VirtualPropsTest.java b/jdk/test/javax/management/namespace/VirtualPropsTest.java index 8bb57edd5f7..904cc5359d7 100644 --- a/jdk/test/javax/management/namespace/VirtualPropsTest.java +++ b/jdk/test/javax/management/namespace/VirtualPropsTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 5108776 + * @bug 5108776 5072476 * @summary Test the properties use case for Virtual MBeans that is documented * in MBeanServerSupport. * @author Eamonn McManus From 545b7e4f6202a74d573be6f8bad3ae1a5e0e52d8 Mon Sep 17 00:00:00 2001 From: Sean Mullan Date: Thu, 11 Sep 2008 14:05:16 -0400 Subject: [PATCH 87/95] 6465942: Add problem identification facility to the CertPathValidator framework Add support to the java.security.cert APIs for determining the reason that a certification path is invalid. Reviewed-by: vinnie --- .../cert/CertPathValidatorException.java | 132 ++++++++++++++++-- .../java/security/cert/PKIXReason.java | 77 ++++++++++ .../provider/certpath/BasicChecker.java | 44 +++--- .../provider/certpath/ConstraintsChecker.java | 16 ++- .../certpath/CrlRevocationChecker.java | 29 ++-- .../provider/certpath/ForwardBuilder.java | 6 +- .../provider/certpath/KeyChecker.java | 13 +- .../provider/certpath/OCSPChecker.java | 10 +- .../certpath/PKIXCertPathValidator.java | 39 +++--- .../certpath/PKIXMasterCertPathValidator.java | 15 +- .../provider/certpath/PolicyChecker.java | 21 +-- .../provider/certpath/ReverseBuilder.java | 15 +- .../provider/certpath/SunCertPathBuilder.java | 14 +- .../ValidateCertPath.java | 10 +- .../ReasonTest.java | 67 +++++++++ .../CertPathValidatorException/Serial.java | 113 +++++++++++++++ .../cert/CertPathValidatorException/cert_file | Bin 0 -> 784 bytes .../CertPathValidatorException/jdk6.serial | Bin 0 -> 1519 bytes .../cert/PolicyNode/GetPolicyQualifiers.java | 8 +- 19 files changed, 525 insertions(+), 104 deletions(-) create mode 100644 jdk/src/share/classes/java/security/cert/PKIXReason.java create mode 100644 jdk/test/java/security/cert/CertPathValidatorException/ReasonTest.java create mode 100644 jdk/test/java/security/cert/CertPathValidatorException/Serial.java create mode 100644 jdk/test/java/security/cert/CertPathValidatorException/cert_file create mode 100644 jdk/test/java/security/cert/CertPathValidatorException/jdk6.serial diff --git a/jdk/src/share/classes/java/security/cert/CertPathValidatorException.java b/jdk/src/share/classes/java/security/cert/CertPathValidatorException.java index 5fd70c24a87..8a04aeff5f3 100644 --- a/jdk/src/share/classes/java/security/cert/CertPathValidatorException.java +++ b/jdk/src/share/classes/java/security/cert/CertPathValidatorException.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. + * 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 @@ -25,6 +25,9 @@ package java.security.cert; +import java.io.InvalidObjectException; +import java.io.IOException; +import java.io.ObjectInputStream; import java.security.GeneralSecurityException; /** @@ -36,10 +39,11 @@ import java.security.GeneralSecurityException; * if any, that caused this exception to be thrown. *

* A CertPathValidatorException may also include the - * certification path that was being validated when the exception was thrown - * and the index of the certificate in the certification path that caused the - * exception to be thrown. Use the {@link #getCertPath getCertPath} and - * {@link #getIndex getIndex} methods to retrieve this information. + * certification path that was being validated when the exception was thrown, + * the index of the certificate in the certification path that caused the + * exception to be thrown, and the reason that caused the failure. Use the + * {@link #getCertPath getCertPath}, {@link #getIndex getIndex}, and + * {@link #getReason getReason} methods to retrieve this information. * *

* Concurrent Access @@ -71,12 +75,17 @@ public class CertPathValidatorException extends GeneralSecurityException { */ private CertPath certPath; + /** + * @serial the reason the validation failed + */ + private Reason reason = BasicReason.UNSPECIFIED; + /** * Creates a CertPathValidatorException with * no detail message. */ public CertPathValidatorException() { - super(); + this(null, null); } /** @@ -87,7 +96,7 @@ public class CertPathValidatorException extends GeneralSecurityException { * @param msg the detail message */ public CertPathValidatorException(String msg) { - super(msg); + this(msg, null); } /** @@ -104,7 +113,7 @@ public class CertPathValidatorException extends GeneralSecurityException { * permitted, and indicates that the cause is nonexistent or unknown.) */ public CertPathValidatorException(Throwable cause) { - super(cause); + this(null, cause); } /** @@ -117,7 +126,7 @@ public class CertPathValidatorException extends GeneralSecurityException { * permitted, and indicates that the cause is nonexistent or unknown.) */ public CertPathValidatorException(String msg, Throwable cause) { - super(msg, cause); + this(msg, cause, null, -1); } /** @@ -139,6 +148,32 @@ public class CertPathValidatorException extends GeneralSecurityException { */ public CertPathValidatorException(String msg, Throwable cause, CertPath certPath, int index) { + this(msg, cause, certPath, index, BasicReason.UNSPECIFIED); + } + + /** + * Creates a CertPathValidatorException with the specified + * detail message, cause, certification path, index, and reason. + * + * @param msg the detail message (or null if none) + * @param cause the cause (or null if none) + * @param certPath the certification path that was in the process of + * being validated when the error was encountered + * @param index the index of the certificate in the certification path + * that caused the error (or -1 if not applicable). Note that + * the list of certificates in a CertPath is zero based. + * @param reason the reason the validation failed + * @throws IndexOutOfBoundsException if the index is out of range + * (index < -1 || (certPath != null && index >= + * certPath.getCertificates().size()) + * @throws IllegalArgumentException if certPath is + * null and index is not -1 + * @throws NullPointerException if reason is null + * + * @since 1.7 + */ + public CertPathValidatorException(String msg, Throwable cause, + CertPath certPath, int index, Reason reason) { super(msg, cause); if (certPath == null && index != -1) { throw new IllegalArgumentException(); @@ -147,8 +182,12 @@ public class CertPathValidatorException extends GeneralSecurityException { (certPath != null && index >= certPath.getCertificates().size())) { throw new IndexOutOfBoundsException(); } + if (reason == null) { + throw new NullPointerException("reason can't be null"); + } this.certPath = certPath; this.index = index; + this.reason = reason; } /** @@ -174,4 +213,79 @@ public class CertPathValidatorException extends GeneralSecurityException { return this.index; } + /** + * Returns the reason that the validation failed. The reason is + * associated with the index of the certificate returned by + * {@link getIndex}. + * + * @return the reason that the validation failed, or + * BasicReason.UNSPECIFIED if a reason has not been + * specified + * + * @since 1.7 + */ + public Reason getReason() { + return this.reason; + } + + private void readObject(ObjectInputStream stream) + throws ClassNotFoundException, IOException { + stream.defaultReadObject(); + if (reason == null) { + reason = BasicReason.UNSPECIFIED; + } + if (certPath == null && index != -1) { + throw new InvalidObjectException("certpath is null and index != -1"); + } + if (index < -1 || + (certPath != null && index >= certPath.getCertificates().size())) { + throw new InvalidObjectException("index out of range"); + } + } + + /** + * The reason the validation algorithm failed. + * + * @since 1.7 + */ + public static interface Reason extends java.io.Serializable { } + + + /** + * The BasicReason enumerates the potential reasons that a certification + * path of any type may be invalid. + * + * @since 1.7 + */ + public static enum BasicReason implements Reason { + /** + * Unspecified reason. + */ + UNSPECIFIED, + + /** + * The certificate is expired. + */ + EXPIRED, + + /** + * The certificate is not yet valid. + */ + NOT_YET_VALID, + + /** + * The certificate is revoked. + */ + REVOKED, + + /** + * The revocation status of the certificate could not be determined. + */ + UNDETERMINED_REVOCATION_STATUS, + + /** + * The signature is invalid. + */ + INVALID_SIGNATURE + } } diff --git a/jdk/src/share/classes/java/security/cert/PKIXReason.java b/jdk/src/share/classes/java/security/cert/PKIXReason.java new file mode 100644 index 00000000000..ed798d334f2 --- /dev/null +++ b/jdk/src/share/classes/java/security/cert/PKIXReason.java @@ -0,0 +1,77 @@ +/* + * 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-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.security.cert; + +/** + * The PKIXReason enumerates the potential PKIX-specific reasons + * that an X.509 certification path may be invalid according to the PKIX + * (RFC 3280) standard. These reasons are in addition to those of the + * CertPathValidatorException.BasicReason enumeration. + * + * @since 1.7 + */ +public enum PKIXReason implements CertPathValidatorException.Reason { + /** + * The certificate does not chain correctly. + */ + NAME_CHAINING, + + /** + * The certificate's key usage is invalid. + */ + INVALID_KEY_USAGE, + + /** + * The policy constraints have been violated. + */ + INVALID_POLICY, + + /** + * No acceptable trust anchor found. + */ + NO_TRUST_ANCHOR, + + /** + * The certificate contains one or more unrecognized critical + * extensions. + */ + UNRECOGNIZED_CRIT_EXT, + + /** + * The certificate is not a CA certificate. + */ + NOT_CA_CERT, + + /** + * The path length constraint has been violated. + */ + PATH_TOO_LONG, + + /** + * The name constraints have been violated. + */ + INVALID_NAME +} diff --git a/jdk/src/share/classes/sun/security/provider/certpath/BasicChecker.java b/jdk/src/share/classes/sun/security/provider/certpath/BasicChecker.java index e4f7d1f3d74..491dd4711da 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/BasicChecker.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/BasicChecker.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * 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 @@ -29,12 +29,18 @@ import java.math.BigInteger; import java.util.Collection; import java.util.Date; import java.util.Set; +import java.security.GeneralSecurityException; import java.security.KeyFactory; import java.security.PublicKey; +import java.security.SignatureException; import java.security.cert.Certificate; +import java.security.cert.CertificateExpiredException; +import java.security.cert.CertificateNotYetValidException; +import java.security.cert.CertPathValidatorException; +import java.security.cert.CertPathValidatorException.BasicReason; import java.security.cert.X509Certificate; import java.security.cert.PKIXCertPathChecker; -import java.security.cert.CertPathValidatorException; +import java.security.cert.PKIXReason; import java.security.cert.TrustAnchor; import java.security.interfaces.DSAParams; import java.security.interfaces.DSAPublicKey; @@ -152,11 +158,11 @@ class BasicChecker extends PKIXCertPathChecker { try { cert.verify(prevPubKey, sigProvider); - } catch (Exception e) { - if (debug != null) { - debug.println(e.getMessage()); - e.printStackTrace(); - } + } catch (SignatureException e) { + throw new CertPathValidatorException + (msg + " check failed", e, null, -1, + BasicReason.INVALID_SIGNATURE); + } catch (GeneralSecurityException e) { throw new CertPathValidatorException(msg + " check failed", e); } @@ -176,12 +182,12 @@ class BasicChecker extends PKIXCertPathChecker { try { cert.checkValidity(date); - } catch (Exception e) { - if (debug != null) { - debug.println(e.getMessage()); - e.printStackTrace(); - } - throw new CertPathValidatorException(msg + " check failed", e); + } catch (CertificateExpiredException e) { + throw new CertPathValidatorException + (msg + " check failed", e, null, -1, BasicReason.EXPIRED); + } catch (CertificateNotYetValidException e) { + throw new CertPathValidatorException + (msg + " check failed", e, null, -1, BasicReason.NOT_YET_VALID); } if (debug != null) @@ -204,12 +210,16 @@ class BasicChecker extends PKIXCertPathChecker { // reject null or empty issuer DNs if (X500Name.asX500Name(currIssuer).isEmpty()) { - throw new CertPathValidatorException(msg + " check failed: " + - "empty/null issuer DN in certificate is invalid"); + throw new CertPathValidatorException + (msg + " check failed: " + + "empty/null issuer DN in certificate is invalid", null, + null, -1, PKIXReason.NAME_CHAINING); } if (!(currIssuer.equals(prevSubject))) { - throw new CertPathValidatorException(msg + " check failed"); + throw new CertPathValidatorException + (msg + " check failed", null, null, -1, + PKIXReason.NAME_CHAINING); } if (debug != null) @@ -270,7 +280,7 @@ class BasicChecker extends PKIXCertPathChecker { params.getQ(), params.getG()); usableKey = kf.generatePublic(ks); - } catch (Exception e) { + } catch (GeneralSecurityException e) { throw new CertPathValidatorException("Unable to generate key with" + " inherited parameters: " + e.getMessage(), e); diff --git a/jdk/src/share/classes/sun/security/provider/certpath/ConstraintsChecker.java b/jdk/src/share/classes/sun/security/provider/certpath/ConstraintsChecker.java index 40872d7d6fc..7e2783cca06 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/ConstraintsChecker.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/ConstraintsChecker.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * 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 @@ -32,9 +32,10 @@ import java.util.HashSet; import java.io.IOException; import java.security.cert.Certificate; import java.security.cert.CertificateException; +import java.security.cert.CertPathValidatorException; import java.security.cert.X509Certificate; import java.security.cert.PKIXCertPathChecker; -import java.security.cert.CertPathValidatorException; +import java.security.cert.PKIXReason; import sun.security.util.Debug; import sun.security.x509.PKIXExtensions; import sun.security.x509.NameConstraintsExtension; @@ -147,7 +148,8 @@ class ConstraintsChecker extends PKIXCertPathChecker { try { if (!prevNC.verify(currCert)) { - throw new CertPathValidatorException(msg + " check failed"); + throw new CertPathValidatorException(msg + " check failed", + null, null, -1, PKIXReason.INVALID_NAME); } } catch (IOException ioe) { throw new CertPathValidatorException(ioe); @@ -228,8 +230,9 @@ class ConstraintsChecker extends PKIXCertPathChecker { if (i < certPathLength) { int pathLenConstraint = currCert.getBasicConstraints(); if (pathLenConstraint == -1) { - throw new CertPathValidatorException(msg + " check failed: " - + "this is not a CA certificate"); + throw new CertPathValidatorException + (msg + " check failed: this is not a CA certificate", null, + null, -1, PKIXReason.NOT_CA_CERT); } if (!X509CertImpl.isSelfIssued(currCert)) { @@ -237,7 +240,8 @@ class ConstraintsChecker extends PKIXCertPathChecker { throw new CertPathValidatorException (msg + " check failed: pathLenConstraint violated - " + "this cert must be the last cert in the " - + "certification path"); + + "certification path", null, null, -1, + PKIXReason.PATH_TOO_LONG); } maxPathLength--; } diff --git a/jdk/src/share/classes/sun/security/provider/certpath/CrlRevocationChecker.java b/jdk/src/share/classes/sun/security/provider/certpath/CrlRevocationChecker.java index 747ccba402c..63ee343175d 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/CrlRevocationChecker.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/CrlRevocationChecker.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * 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 @@ -39,6 +39,7 @@ import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.cert.*; +import java.security.cert.CertPathValidatorException.BasicReason; import java.security.interfaces.DSAPublicKey; import javax.security.auth.x500.X500Principal; import sun.security.util.Debug; @@ -268,7 +269,8 @@ class CrlRevocationChecker extends PKIXCertPathChecker { " circular dependency"); } throw new CertPathValidatorException - ("Could not determine revocation status"); + ("Could not determine revocation status", null, null, -1, + BasicReason.UNDETERMINED_REVOCATION_STATUS); } // init the state for this run @@ -324,7 +326,8 @@ class CrlRevocationChecker extends PKIXCertPathChecker { return; } else { throw new CertPathValidatorException - ("Could not determine revocation status"); + ("Could not determine revocation status", null, null, -1, + BasicReason.UNDETERMINED_REVOCATION_STATUS); } } @@ -370,7 +373,8 @@ class CrlRevocationChecker extends PKIXCertPathChecker { + unresCritExts); } throw new CertPathValidatorException - ("Could not determine revocation status"); + ("Could not determine revocation status", null, null, + -1, BasicReason.UNDETERMINED_REVOCATION_STATUS); } } @@ -378,10 +382,11 @@ class CrlRevocationChecker extends PKIXCertPathChecker { if (reasonCode == null) { reasonCode = CRLReason.UNSPECIFIED; } - throw new CertPathValidatorException( - new CertificateRevokedException - (entry.getRevocationDate(), reasonCode, - crl.getIssuerX500Principal(), entry.getExtensions())); + Throwable t = new CertificateRevokedException + (entry.getRevocationDate(), reasonCode, + crl.getIssuerX500Principal(), entry.getExtensions()); + throw new CertPathValidatorException(t.getMessage(), t, + null, -1, BasicReason.REVOKED); } } } @@ -428,7 +433,8 @@ class CrlRevocationChecker extends PKIXCertPathChecker { " circular dependency"); } throw new CertPathValidatorException - ("Could not determine revocation status"); + ("Could not determine revocation status", null, null, + -1, BasicReason.UNDETERMINED_REVOCATION_STATUS); } // If prevKey wasn't trusted, maybe we just didn't have the right @@ -617,7 +623,7 @@ class CrlRevocationChecker extends PKIXCertPathChecker { return; } catch (CertPathValidatorException cpve) { // If it is revoked, rethrow exception - if (cpve.getCause() instanceof CertificateRevokedException) { + if (cpve.getReason() == BasicReason.REVOKED) { throw cpve; } // Otherwise, ignore the exception and @@ -628,7 +634,8 @@ class CrlRevocationChecker extends PKIXCertPathChecker { throw new CertPathValidatorException(iape); } catch (CertPathBuilderException cpbe) { throw new CertPathValidatorException - ("Could not determine revocation status", cpbe); + ("Could not determine revocation status", null, null, + -1, BasicReason.UNDETERMINED_REVOCATION_STATUS); } } } diff --git a/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java b/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java index aa886037312..d8713cdcac4 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java @@ -32,6 +32,7 @@ import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.cert.CertificateException; import java.security.cert.CertPathValidatorException; +import java.security.cert.PKIXReason; import java.security.cert.CertStore; import java.security.cert.CertStoreException; import java.security.cert.PKIXBuilderParameters; @@ -732,8 +733,9 @@ class ForwardBuilder extends Builder { PKIXExtensions.ExtendedKeyUsage_Id.toString()); if (!unresCritExts.isEmpty()) - throw new CertificateException("Unrecognized critical " - + "extension(s)"); + throw new CertPathValidatorException + ("Unrecognized critical extension(s)", null, null, -1, + PKIXReason.UNRECOGNIZED_CRIT_EXT); } } diff --git a/jdk/src/share/classes/sun/security/provider/certpath/KeyChecker.java b/jdk/src/share/classes/sun/security/provider/certpath/KeyChecker.java index 1ed96c567e2..d12031955ff 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/KeyChecker.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/KeyChecker.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved. + * 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 @@ -27,6 +27,7 @@ package sun.security.provider.certpath; import java.util.*; import java.security.cert.*; +import java.security.cert.PKIXReason; import sun.security.util.Debug; import sun.security.x509.PKIXExtensions; @@ -75,11 +76,12 @@ class KeyChecker extends PKIXCertPathChecker { if (!forward) { remainingCerts = certPathLen; } else { - throw new CertPathValidatorException("forward checking not supported"); + throw new CertPathValidatorException + ("forward checking not supported"); } } - public boolean isForwardCheckingSupported() { + public final boolean isForwardCheckingSupported() { return false; } @@ -155,8 +157,9 @@ class KeyChecker extends PKIXCertPathChecker { // throw an exception if the keyCertSign bit is not set if (!keyUsageBits[keyCertSign]) { - throw new CertPathValidatorException(msg + " check failed: " - + "keyCertSign bit is not set"); + throw new CertPathValidatorException + (msg + " check failed: keyCertSign bit is not set", null, + null, -1, PKIXReason.INVALID_KEY_USAGE); } if (debug != null) { diff --git a/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java b/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java index adf5ea68976..35ed85def19 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java @@ -33,6 +33,7 @@ import java.security.Principal; import java.security.PrivilegedAction; import java.security.Security; import java.security.cert.*; +import java.security.cert.CertPathValidatorException.BasicReason; import java.net.*; import javax.security.auth.x500.X500Principal; @@ -381,17 +382,18 @@ class OCSPChecker extends PKIXCertPathChecker { } if (certOCSPStatus == OCSPResponse.CERT_STATUS_REVOKED) { - throw new CertPathValidatorException( - new CertificateRevokedException( + Throwable t = new CertificateRevokedException( ocspResponse.getRevocationTime(), ocspResponse.getRevocationReason(), responderCert.getSubjectX500Principal(), - ocspResponse.getSingleExtensions())); + ocspResponse.getSingleExtensions()); + throw new CertPathValidatorException(t.getMessage(), t, + null, -1, BasicReason.REVOKED); } else if (certOCSPStatus == OCSPResponse.CERT_STATUS_UNKNOWN) { throw new CertPathValidatorException( "Certificate's revocation status is unknown", null, cp, - remainingCerts); + remainingCerts, BasicReason.UNDETERMINED_REVOCATION_STATUS); } } catch (Exception e) { throw new CertPathValidatorException(e); diff --git a/jdk/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java b/jdk/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java index 73d749465a1..63335d2342c 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * 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 @@ -38,6 +38,7 @@ import java.security.cert.CertPathValidatorResult; import java.security.cert.PKIXCertPathChecker; import java.security.cert.PKIXCertPathValidatorResult; import java.security.cert.PKIXParameters; +import java.security.cert.PKIXReason; import java.security.cert.PolicyNode; import java.security.cert.TrustAnchor; import java.security.cert.X509Certificate; @@ -47,7 +48,6 @@ import java.util.List; import java.util.ArrayList; import java.util.Date; import java.util.Set; -import java.util.HashSet; import javax.security.auth.x500.X500Principal; import sun.security.util.Debug; @@ -67,6 +67,7 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi { private List userCheckers; private String sigProvider; private BasicChecker basicChecker; + private String ocspProperty; /** * Default constructor. @@ -126,7 +127,7 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi { // Must copy elements of certList into a new modifiable List before // calling Collections.reverse(). - List certList = new ArrayList + ArrayList certList = new ArrayList ((List)cp.getCertificates()); if (debug != null) { if (certList.isEmpty()) { @@ -201,7 +202,8 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi { } // (b) otherwise, generate new exception throw new CertPathValidatorException - ("Path does not chain with any of the trust anchors"); + ("Path does not chain with any of the trust anchors", + null, null, -1, PKIXReason.NO_TRUST_ANCHOR); } /** @@ -210,7 +212,6 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi { */ private boolean isWorthTrying(X509Certificate trustedCert, X509Certificate firstCert) - throws CertPathValidatorException { if (debug != null) { debug.println("PKIXCertPathValidator.isWorthTrying() checking " @@ -240,7 +241,6 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi { * Internal method to setup the internal state */ private void populateVariables(PKIXParameters pkixParam) - throws CertPathValidatorException { // default value for testDate is current time testDate = pkixParam.getDate(); @@ -250,6 +250,17 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi { userCheckers = pkixParam.getCertPathCheckers(); sigProvider = pkixParam.getSigProvider(); + + if (pkixParam.isRevocationEnabled()) { + // Examine OCSP security property + ocspProperty = AccessController.doPrivileged( + new PrivilegedAction() { + public String run() { + return + Security.getProperty(OCSPChecker.OCSP_ENABLE_PROP); + } + }); + } } /** @@ -259,12 +270,9 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi { */ private PolicyNode doValidate( TrustAnchor anchor, CertPath cpOriginal, - List certList, PKIXParameters pkixParam, + ArrayList certList, PKIXParameters pkixParam, PolicyNodeImpl rootNode) throws CertPathValidatorException { - List certPathCheckers = - new ArrayList(); - int certPathLen = certList.size(); basicChecker = new BasicChecker(anchor, testDate, sigProvider, false); @@ -281,6 +289,8 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi { pkixParam.getPolicyQualifiersRejected(), rootNode); + ArrayList certPathCheckers = + new ArrayList(); // add standard checkers that we will be using certPathCheckers.add(keyChecker); certPathCheckers.add(constraintsChecker); @@ -290,15 +300,6 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi { // only add a revocationChecker if revocation is enabled if (pkixParam.isRevocationEnabled()) { - // Examine OCSP security property - String ocspProperty = AccessController.doPrivileged( - new PrivilegedAction() { - public String run() { - return - Security.getProperty(OCSPChecker.OCSP_ENABLE_PROP); - } - }); - // Use OCSP if it has been enabled if ("true".equalsIgnoreCase(ocspProperty)) { OCSPChecker ocspChecker = diff --git a/jdk/src/share/classes/sun/security/provider/certpath/PKIXMasterCertPathValidator.java b/jdk/src/share/classes/sun/security/provider/certpath/PKIXMasterCertPathValidator.java index faa472f84d1..d5f12168dda 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/PKIXMasterCertPathValidator.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/PKIXMasterCertPathValidator.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * 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 @@ -30,11 +30,12 @@ import sun.security.util.Debug; import java.util.Collections; import java.util.List; import java.util.Set; -import java.util.Iterator; +import java.security.cert.CertificateRevokedException; import java.security.cert.CertPath; import java.security.cert.CertPathValidatorException; -import java.security.cert.CertificateRevokedException; +import java.security.cert.CertPathValidatorException.BasicReason; import java.security.cert.PKIXCertPathChecker; +import java.security.cert.PKIXReason; import java.security.cert.X509Certificate; /** @@ -153,10 +154,11 @@ class PKIXMasterCertPathValidator { */ CertPathValidatorException currentCause = new CertPathValidatorException(cpve.getMessage(), - cpve.getCause(), cpOriginal, cpSize - (i + 1)); + cpve.getCause(), cpOriginal, cpSize - (i + 1), + cpve.getReason()); // Check if OCSP has confirmed that the cert was revoked - if (cpve.getCause() instanceof CertificateRevokedException) { + if (cpve.getReason() == BasicReason.REVOKED) { throw currentCause; } // Check if it is appropriate to failover @@ -184,7 +186,8 @@ class PKIXMasterCertPathValidator { debug.println("checking for unresolvedCritExts"); if (!unresolvedCritExts.isEmpty()) { throw new CertPathValidatorException("unrecognized " + - "critical extension(s)", null, cpOriginal, cpSize-(i+1)); + "critical extension(s)", null, cpOriginal, cpSize-(i+1), + PKIXReason.UNRECOGNIZED_CRIT_EXT); } if (debug != null) diff --git a/jdk/src/share/classes/sun/security/provider/certpath/PolicyChecker.java b/jdk/src/share/classes/sun/security/provider/certpath/PolicyChecker.java index 3b76f621cea..26dc1e52ab9 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/PolicyChecker.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/PolicyChecker.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * 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 @@ -30,11 +30,12 @@ import java.io.IOException; import java.security.cert.Certificate; import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.security.cert.PKIXCertPathChecker; import java.security.cert.CertPathValidatorException; +import java.security.cert.PKIXCertPathChecker; +import java.security.cert.PKIXReason; import java.security.cert.PolicyNode; import java.security.cert.PolicyQualifierInfo; +import java.security.cert.X509Certificate; import sun.security.util.Debug; import sun.security.x509.CertificatePoliciesExtension; @@ -482,8 +483,9 @@ class PolicyChecker extends PKIXCertPathChecker { // the policyQualifiersRejected flag is set in the params if (!pQuals.isEmpty() && rejectPolicyQualifiers && policiesCritical) { - throw new CertPathValidatorException("critical " + - "policy qualifiers present in certificate"); + throw new CertPathValidatorException( + "critical policy qualifiers present in certificate", + null, null, -1, PKIXReason.INVALID_POLICY); } // PKIX: Section 6.1.3: Step (d)(1)(i) @@ -567,7 +569,8 @@ class PolicyChecker extends PKIXCertPathChecker { if ((explicitPolicy == 0) && (rootNode == null)) { throw new CertPathValidatorException - ("non-null policy tree required and policy tree is null"); + ("non-null policy tree required and policy tree is null", + null, null, -1, PKIXReason.INVALID_POLICY); } return rootNode; @@ -776,12 +779,14 @@ class PolicyChecker extends PKIXCertPathChecker { if (issuerDomain.equals(ANY_POLICY)) { throw new CertPathValidatorException - ("encountered an issuerDomainPolicy of ANY_POLICY"); + ("encountered an issuerDomainPolicy of ANY_POLICY", + null, null, -1, PKIXReason.INVALID_POLICY); } if (subjectDomain.equals(ANY_POLICY)) { throw new CertPathValidatorException - ("encountered a subjectDomainPolicy of ANY_POLICY"); + ("encountered a subjectDomainPolicy of ANY_POLICY", + null, null, -1, PKIXReason.INVALID_POLICY); } Set validNodes = diff --git a/jdk/src/share/classes/sun/security/provider/certpath/ReverseBuilder.java b/jdk/src/share/classes/sun/security/provider/certpath/ReverseBuilder.java index c3f2b678f2c..6f826026caf 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/ReverseBuilder.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/ReverseBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * 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 @@ -29,14 +29,15 @@ import java.io.IOException; import java.security.GeneralSecurityException; import java.security.Principal; import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; import java.security.cert.CertPathValidatorException; import java.security.cert.CertStore; import java.security.cert.CertStoreException; import java.security.cert.PKIXBuilderParameters; import java.security.cert.PKIXCertPathChecker; import java.security.cert.PKIXParameters; +import java.security.cert.PKIXReason; import java.security.cert.TrustAnchor; +import java.security.cert.X509Certificate; import java.security.cert.X509CertSelector; import java.util.ArrayList; import java.util.Collection; @@ -402,7 +403,8 @@ class ReverseBuilder extends Builder { */ if ((currentState.remainingCACerts <= 0) && !X509CertImpl.isSelfIssued(cert)) { throw new CertPathValidatorException - ("pathLenConstraint violated, path too long"); + ("pathLenConstraint violated, path too long", null, + null, -1, PKIXReason.PATH_TOO_LONG); } /* @@ -438,7 +440,8 @@ class ReverseBuilder extends Builder { try { if (!currentState.nc.verify(cert)){ throw new CertPathValidatorException - ("name constraints check failed"); + ("name constraints check failed", null, null, -1, + PKIXReason.INVALID_NAME); } } catch (IOException ioe){ throw new CertPathValidatorException(ioe); @@ -483,7 +486,9 @@ class ReverseBuilder extends Builder { unresolvedCritExts.remove(PKIXExtensions.ExtendedKeyUsage_Id.toString()); if (!unresolvedCritExts.isEmpty()) - throw new CertificateException("Unrecognized critical extension(s)"); + throw new CertPathValidatorException + ("Unrecognized critical extension(s)", null, null, -1, + PKIXReason.UNRECOGNIZED_CRIT_EXT); } /* diff --git a/jdk/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java b/jdk/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java index 14ed5309087..0c439349d3c 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * 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 @@ -30,6 +30,9 @@ import java.security.GeneralSecurityException; import java.security.InvalidAlgorithmParameterException; import java.security.Principal; import java.security.PublicKey; +import java.security.cert.*; +import java.security.cert.PKIXReason; +import java.security.interfaces.DSAPublicKey; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -39,10 +42,6 @@ import java.util.Iterator; import java.util.List; import java.util.LinkedList; import java.util.Set; - -import java.security.cert.*; -import java.security.interfaces.DSAPublicKey; - import javax.security.auth.x500.X500Principal; import sun.security.x509.X500Name; @@ -565,8 +564,9 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { (PKIXExtensions.ExtendedKeyUsage_Id.toString()); if (!unresCritExts.isEmpty()) { - throw new CertPathValidatorException("unrecognized " - + "critical extension(s)"); + throw new CertPathValidatorException + ("unrecognized critical extension(s)", null, + null, -1, PKIXReason.UNRECOGNIZED_CRIT_EXT); } } } diff --git a/jdk/test/java/security/cert/CertPathValidator/nameConstraintsRFC822/ValidateCertPath.java b/jdk/test/java/security/cert/CertPathValidator/nameConstraintsRFC822/ValidateCertPath.java index d6102627319..b2666a3105d 100644 --- a/jdk/test/java/security/cert/CertPathValidator/nameConstraintsRFC822/ValidateCertPath.java +++ b/jdk/test/java/security/cert/CertPathValidator/nameConstraintsRFC822/ValidateCertPath.java @@ -1,5 +1,5 @@ /* - * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-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 @@ -34,6 +34,7 @@ import java.io.InputStream; import java.io.IOException; import java.security.cert.*; +import java.security.cert.PKIXReason; import java.util.ArrayList; import java.util.Collections; @@ -69,6 +70,9 @@ public final class ValidateCertPath { validate(path, params); throw new Exception("Successfully validated invalid path."); } catch (CertPathValidatorException e) { + if (e.getReason() != PKIXReason.INVALID_NAME) { + throw new Exception("unexpected reason: " + e.getReason()); + } System.out.println("Path rejected as expected: " + e); } } @@ -86,14 +90,14 @@ public final class ValidateCertPath { args = new String[] {"jane2jane.cer", "jane2steve.cer", "steve2tom.cer"}; TrustAnchor anchor = new TrustAnchor(getCertFromFile(args[0]), null); - List list = new ArrayList(); + List list = new ArrayList(); for (int i = 1; i < args.length; i++) { list.add(0, getCertFromFile(args[i])); } CertificateFactory cf = CertificateFactory.getInstance("X509"); path = cf.generateCertPath(list); - Set anchors = Collections.singleton(anchor); + Set anchors = Collections.singleton(anchor); params = new PKIXParameters(anchors); params.setRevocationEnabled(false); } diff --git a/jdk/test/java/security/cert/CertPathValidatorException/ReasonTest.java b/jdk/test/java/security/cert/CertPathValidatorException/ReasonTest.java new file mode 100644 index 00000000000..3702893ea2a --- /dev/null +++ b/jdk/test/java/security/cert/CertPathValidatorException/ReasonTest.java @@ -0,0 +1,67 @@ +/* + * 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 6465942 + * @summary unit test for CertPathValidatorException.Reason + */ + +import java.security.cert.CertPathValidatorException; +import java.security.cert.CertPathValidatorException.BasicReason; + +public class ReasonTest { + private static volatile boolean failed = false; + public static void main(String[] args) throws Exception { + + // check that getReason returns UNSPECIFIED if reason not specified + CertPathValidatorException cpve = new CertPathValidatorException("abc"); + if (cpve.getReason() != BasicReason.UNSPECIFIED) { + failed = true; + System.err.println("FAILED: unexpected reason: " + cpve.getReason()); + } + + // check that getReason returns specified reason + cpve = new CertPathValidatorException + ("abc", null, null, -1, BasicReason.REVOKED); + if (cpve.getReason() != BasicReason.REVOKED) { + failed = true; + System.err.println("FAILED: unexpected reason: " + cpve.getReason()); + } + + // check that ctor throws NPE when reason is null + try { + cpve = new CertPathValidatorException("abc", null, null, -1, null); + failed = true; + System.err.println("ctor did not throw NPE for null reason"); + } catch (Exception e) { + if (!(e instanceof NullPointerException)) { + failed = true; + System.err.println("FAILED: unexpected exception: " + e); + } + } + if (failed) { + throw new Exception("Some tests FAILED"); + } + } +} diff --git a/jdk/test/java/security/cert/CertPathValidatorException/Serial.java b/jdk/test/java/security/cert/CertPathValidatorException/Serial.java new file mode 100644 index 00000000000..a6ffd3b4cd4 --- /dev/null +++ b/jdk/test/java/security/cert/CertPathValidatorException/Serial.java @@ -0,0 +1,113 @@ +/* + * 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 6465942 + * @summary Test deserialization of CertPathValidatorException + */ + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +//import java.io.FileOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; +import java.security.cert.CertPath; +import java.security.cert.CertPathValidatorException; +import java.security.cert.CertPathValidatorException.BasicReason; +import java.util.Collections; + +/** + * This class tests to see if CertPathValidatorException can be serialized and + * deserialized properly. + */ +public class Serial { + private static volatile boolean failed = false; + public static void main(String[] args) throws Exception { + + File f = new File(System.getProperty("test.src", "."), "cert_file"); + FileInputStream fis = new FileInputStream(f); + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + Certificate c = cf.generateCertificate(fis); + fis.close(); + CertPath cp = cf.generateCertPath(Collections.singletonList(c)); + + CertPathValidatorException cpve1 = + new CertPathValidatorException + ("Test", new Exception("Expired"), cp, 0, BasicReason.EXPIRED); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); +// FileOutputStream fos = new FileOutputStream("jdk7.serial"); + ObjectOutputStream oos = new ObjectOutputStream(baos); +// ObjectOutputStream foos = new ObjectOutputStream(fos); + oos.writeObject(cpve1); +// foos.writeObject(cpve1); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(bais); + CertPathValidatorException cpve2 = + (CertPathValidatorException) ois.readObject(); + check(!cpve1.getMessage().equals(cpve2.getMessage()), + "CertPathValidatorException messages not equal"); + check(!cpve1.getCause().getMessage().equals(cpve2.getCause().getMessage()), + "CertPathValidatorException causes not equal"); + check(!cpve1.getCertPath().equals(cpve2.getCertPath()), + "CertPathValidatorException certpaths not equal"); + check(cpve1.getIndex() != cpve2.getIndex(), + "CertPathValidatorException indexes not equal"); + check(cpve1.getReason() != cpve2.getReason(), + "CertPathValidatorException reasons not equal"); + oos.close(); + ois.close(); + + f = new File(System.getProperty("test.src", "."), "jdk6.serial"); + fis = new FileInputStream(f); + ois = new ObjectInputStream(fis); + cpve2 = (CertPathValidatorException) ois.readObject(); + check(!cpve1.getMessage().equals(cpve2.getMessage()), + "CertPathValidatorException messages not equal"); + check(!cpve1.getCause().getMessage().equals(cpve2.getCause().getMessage()), + "CertPathValidatorException causes not equal"); + check(!cpve1.getCertPath().equals(cpve2.getCertPath()), + "CertPathValidatorException certpaths not equal"); + check(cpve1.getIndex() != cpve2.getIndex(), + "CertPathValidatorException indexes not equal"); +// System.out.println(cpve2.getReason()); + check(cpve2.getReason() != BasicReason.UNSPECIFIED, + "CertPathValidatorException reasons not equal"); + oos.close(); + ois.close(); + if (failed) { + throw new Exception("Some tests FAILED"); + } + } + + private static void check(boolean expr, String message) { + if (expr) { + failed = true; + System.err.println("FAILED: " + message); + } + } +} diff --git a/jdk/test/java/security/cert/CertPathValidatorException/cert_file b/jdk/test/java/security/cert/CertPathValidatorException/cert_file new file mode 100644 index 0000000000000000000000000000000000000000..42af97b376221127bc892d2479e53655ac768b8b GIT binary patch literal 784 zcmXqLV&*YuVmigdVlJI^(tw+dU8~LGoCOOrD}zCfp@0D&8*?ZNn=pH5UUpu7c^*uJ z14D!zLxc-Mgd0PI87^WVC(dhWX<%Y#X=rX@Xk-}$=9(K?K)G~wO%vmGgC<5DSa2`` zIr2=6jSPS5gBxW_g*1cid(F{%^W^zA!Ra7Z9gXc!#e!=u@%ci z`B{E9f4h8C?l6;Sh;WqHM5Aw|pVw(8Ue|j6Nr_oKz?hg?%UqMd${%}F-wb{1!PVZSAW40rFXXTXjyMI}|YWf-O!)?pnlpYuv-nZ*Y zr2n%*c7eu*EuLb9$}fC0#Duq>=QQd$vFxFZSXFmOO|Qm-#p~p>H!mxln76o|`ErxtT#3jn@&fmS< hf$B^6@`IT~B7ZJVp2~YvI;6SF_zE}Eo}lFS+5kZ&AXxwa literal 0 HcmV?d00001 diff --git a/jdk/test/java/security/cert/CertPathValidatorException/jdk6.serial b/jdk/test/java/security/cert/CertPathValidatorException/jdk6.serial new file mode 100644 index 0000000000000000000000000000000000000000..b76d0709c42bf1c9b75821f4434c3dd99aa9d787 GIT binary patch literal 1519 zcmZ4UmVvdnh(R|iu`E%qI5oMnD6^zeFFCcSM9&#W1SFPZgeB%=rX-f+7r9m>rxuiC z=I32Ci;$Vi;+4z9z~srmnwgi9TH(XM0n!9gU&0{k12Rq@W}H4qMjvLJbwv?_8me{f zsd=eIi8;Yg>*4nBWPMZHv_W(!69WTKlQ39QPGVlV9$dwRzw&lc)-p#hRD@&{<(DTW z<)mIcW~y#kzT-4A1G5hUYjR>~acT*JD8zvvv-IIAt$i4HQ&LM3Gjn`Xi;EM}f$D^i z)CHFmW#*+@M>B90mn0@T%GSo3Jg9y$N26oqq zg3O}Sl+q%YMm?~9g5f5@G%~qq+1UJ5vIKdofPsO55g19*hycLQkjQy-mYUh!Rwf1( zPX?}>%)C^;(%hufA|D36l+@&$M3CE^a}tZe&S3+_R$69Gs$XJmD#&F(K38sPNk)DO zTm)>XRS5%IaB5LzVonJIH-w=FazhCNOKxIjUIma2Ni8lZ1)0GOb|i?!3uIY=82lhY z07M8@0L2)9UQkDkcu>NCr!y5;3JFRr(7d_M*X>W9FffHhGq3AmXgW> zh?^@4fT0K!Tk~1`2OCGo187Jwix@O93ji^XK@-y{CKhw)tdj=ZZ0uTX9_K7rm{}PN zats9w_}G|3S=fZxL-Vrp^2_sJA{-bZ>=+_k7$V#lBFu0R137VCOG^V2LrX(*6GJ1* zC@|OD&;rV(vum0dw;MDu>cE175y+8eYHVcqTOZsgTPma(bl+=^-kT@SzX@&+vU%^q za9Ga1VOyYDrfaN&QsD1M+un#@`;UIzW$^9v?9iO+jn)maCi$Pz61Hd03|P8k{`?m# z)dEU~{CBUs{%`v+=^xhN&yTHGCd$w9yZPJYqjHCtOhbgD#3mYjEB(AqJMp^K`%g;D zl5;P5FdkKL;f;X5m* ztl$01>Q&Rva35}4_NMf}$nd^hS0eqN6|xI7Hf-?}D^z~rqah}|{XC~p&xvIZZN#d& zLuz_89xPrbr@eVu>BPLn_1wP{O_M(UPO4&5u|BipQL1bMjz{c=RLKU8(SEd8XNd|_Dbm=$Ys@=)z&6#us!Y0@h>-x_`)4)lMEI=Q2V_% z-r|p0(zi{FT>+x+;>#TuTof*2*l!-Cx~cEOs&{(qHH#XrOwijYoHS$m1y;`cU%$ww zr%K7Qikvh*F2k|@Le-b6Z^fB3{g*wM{l`7^I%@!5rRLVj*&p^^Tf4V+#;=)*PAF-Z zS)ai`he;&3arcvyNNfLZH+KH+ Date: Wed, 5 Jul 2017 16:39:59 +0200 Subject: [PATCH 88/95] 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 From 996e6846f403c7f9ef68c14933b36603365dc1fe Mon Sep 17 00:00:00 2001 From: "J. Duke" Date: Wed, 5 Jul 2017 16:40:32 +0200 Subject: [PATCH 89/95] Added tag jdk7-b34 for changeset 90cf935adb35 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 14b040b0551..d63506837b5 100644 --- a/.hgtags +++ b/.hgtags @@ -8,3 +8,4 @@ bee4731164a06ddece1297ae58db24aca6a1c626 jdk7-b30 cd8b8f500face60d1566d850857a7fccadbd383a jdk7-b31 a9f1805e3ba9ca520cad199d522c84af5433e85a jdk7-b32 6838c1a3296aaa3572364d2ce7d70826cee96286 jdk7-b33 +90cf935adb353bb0af4b46fb0677e841fd24c000 jdk7-b34 From e786504157d6f7ffe2da4a978a1d80924984b60a Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 11 Sep 2008 11:25:53 -0700 Subject: [PATCH 90/95] Added tag jdk7-b35 for changeset 61dbf0534cc0 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index 88db46731dd..5a4391f4df5 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -9,3 +9,4 @@ b7474b739d13bacd9972f88ac91f6350b7b0be12 jdk7-b31 c51121419e30eac5f0fbbce45ff1711c4ce0de28 jdk7-b32 fa4c0a6cdd25d97d4e6f5d7aa180bcbb0e0d56af jdk7-b33 434055a0716ee44bca712ebca02fc04b20e6e288 jdk7-b34 +cf4894b78ceb966326e93bf221db0c2d14d59218 jdk7-b35 From 3020470ba90fe039acd9da13334c51b1405adc94 Mon Sep 17 00:00:00 2001 From: Dave Bristor Date: Thu, 11 Sep 2008 14:58:57 -0700 Subject: [PATCH 91/95] 6440786: Cannot create a ZIP file containing zero entries Allow reading and writing of ZIP files with zero entries. Reviewed-by: alanb --- .../java/util/zip/ZipOutputStream.java | 5 +- jdk/src/share/native/java/util/zip/zip_util.c | 26 +++- jdk/test/java/util/zip/TestEmptyZip.java | 147 ++++++++++++++++++ 3 files changed, 167 insertions(+), 11 deletions(-) create mode 100644 jdk/test/java/util/zip/TestEmptyZip.java diff --git a/jdk/src/share/classes/java/util/zip/ZipOutputStream.java b/jdk/src/share/classes/java/util/zip/ZipOutputStream.java index 65394268297..797a37392fe 100644 --- a/jdk/src/share/classes/java/util/zip/ZipOutputStream.java +++ b/jdk/src/share/classes/java/util/zip/ZipOutputStream.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-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 @@ -317,9 +317,6 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants { if (current != null) { closeEntry(); } - if (xentries.size() < 1) { - throw new ZipException("ZIP file must have at least one entry"); - } // write central directory long off = written; for (XEntry xentry : xentries) diff --git a/jdk/src/share/native/java/util/zip/zip_util.c b/jdk/src/share/native/java/util/zip/zip_util.c index 1f6e04a1f7e..5d518cf4ced 100644 --- a/jdk/src/share/native/java/util/zip/zip_util.c +++ b/jdk/src/share/native/java/util/zip/zip_util.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-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 @@ -722,16 +722,22 @@ ZIP_Put_In_Cache(const char *name, ZFILE zfd, char **pmsg, jlong lastModified) } len = zip->len = ZFILE_Lseek(zfd, 0, SEEK_END); - if (len == -1) { - if (pmsg && JVM_GetLastErrorString(errbuf, sizeof(errbuf)) > 0) - *pmsg = errbuf; + if (len <= 0) { + if (len == 0) { /* zip file is empty */ + if (pmsg) { + *pmsg = "zip file is empty"; + } + } else { /* error */ + if (pmsg && JVM_GetLastErrorString(errbuf, sizeof(errbuf)) > 0) + *pmsg = errbuf; + } ZFILE_Close(zfd); freeZip(zip); return NULL; } zip->zfd = zfd; - if (readCEN(zip, -1) <= 0) { + if (readCEN(zip, -1) < 0) { /* An error occurred while trying to read the zip file */ if (pmsg != 0) { /* Set the zip error message */ @@ -947,10 +953,15 @@ jzentry * ZIP_GetEntry(jzfile *zip, char *name, jint ulen) { unsigned int hsh = hash(name); - jint idx = zip->table[hsh % zip->tablelen]; - jzentry *ze; + jint idx; + jzentry *ze = 0; ZIP_Lock(zip); + if (zip->total == 0) { + goto Finally; + } + + idx = zip->table[hsh % zip->tablelen]; /* * This while loop is an optimization where a double lookup @@ -1025,6 +1036,7 @@ ZIP_GetEntry(jzfile *zip, char *name, jint ulen) ulen = 0; } +Finally: ZIP_Unlock(zip); return ze; } diff --git a/jdk/test/java/util/zip/TestEmptyZip.java b/jdk/test/java/util/zip/TestEmptyZip.java new file mode 100644 index 00000000000..d19dee4d446 --- /dev/null +++ b/jdk/test/java/util/zip/TestEmptyZip.java @@ -0,0 +1,147 @@ +/* + * 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 6334003 6440786 + * @summary Test ability to write and read zip files that have no entries. + * @author Dave Bristor + */ + +import java.io.*; +import java.util.*; +import java.util.zip.*; + +public class TestEmptyZip { + public static void realMain(String[] args) throws Throwable { + String zipName = "foo.zip"; + File f = new File(System.getProperty("test.scratch", "."), zipName); + if (f.exists() && !f.delete()) { + throw new Exception("failed to delete " + zipName); + } + + // Verify 0-length file cannot be read + f.createNewFile(); + ZipFile zf = null; + try { + zf = new ZipFile(f); + fail(); + } catch (Exception ex) { + check(ex.getMessage().contains("zip file is empty")); + } finally { + if (zf != null) { + zf.close(); + } + } + + ZipInputStream zis = null; + try { + zis = new ZipInputStream(new FileInputStream(f)); + ZipEntry ze = zis.getNextEntry(); + check(ze == null); + } catch (Exception ex) { + unexpected(ex); + } finally { + if (zis != null) { + zis.close(); + } + } + + f.delete(); + + // Verify 0-entries file can be written + write(f); + + // Verify 0-entries file can be read + readFile(f); + readStream(f); + + f.delete(); + } + + static void write(File f) throws Exception { + ZipOutputStream zos = null; + try { + zos = new ZipOutputStream(new FileOutputStream(f)); + zos.finish(); + zos.close(); + pass(); + } catch (Exception ex) { + unexpected(ex); + } finally { + if (zos != null) { + zos.close(); + } + } + } + + static void readFile(File f) throws Exception { + ZipFile zf = null; + try { + zf = new ZipFile(f); + + Enumeration e = zf.entries(); + while (e.hasMoreElements()) { + ZipEntry entry = (ZipEntry) e.nextElement(); + fail(); + } + zf.close(); + pass(); + } catch (Exception ex) { + unexpected(ex); + } finally { + if (zf != null) { + zf.close(); + } + } + } + + static void readStream(File f) throws Exception { + ZipInputStream zis = null; + try { + zis = new ZipInputStream(new FileInputStream(f)); + ZipEntry ze = zis.getNextEntry(); + check(ze == null); + byte[] buf = new byte[1024]; + check(zis.read(buf, 0, 1024) == -1); + } finally { + if (zis != null) { + zis.close(); + } + } + } + + //--------------------- Infrastructure --------------------------- + static volatile int passed = 0, failed = 0; + static boolean pass() {passed++; return true;} + static boolean fail() {failed++; Thread.dumpStack(); return false;} + static boolean fail(String msg) {System.out.println(msg); return fail();} + static void unexpected(Throwable t) {failed++; t.printStackTrace();} + static boolean check(boolean cond) {if (cond) pass(); else fail(); return cond;} + static boolean equal(Object x, Object y) { + if (x == null ? y == null : x.equals(y)) return pass(); + else return fail(x + " not equal to " + y);} + public static void main(String[] args) throws Throwable { + try {realMain(args);} catch (Throwable t) {unexpected(t);} + System.out.println("\nPassed = " + passed + " failed = " + failed); + if (failed > 0) throw new AssertionError("Some tests failed");} +} From a1e4e3ec9422583eca37172f3fa8fe79f2623319 Mon Sep 17 00:00:00 2001 From: Eamonn McManus Date: Fri, 12 Sep 2008 15:17:52 +0200 Subject: [PATCH 92/95] 6747411: EventClient causes thread leaks Reworked thread management in EventClient and related classes. Reviewed-by: sjiang, dfuchs --- .../com/sun/jmx/event/LeaseManager.java | 11 +- .../sun/jmx/event/RepeatedSingletonJob.java | 4 +- .../internal/ClientCommunicatorAdmin.java | 4 +- .../javax/management/event/EventClient.java | 5 +- .../management/event/FetchingEventRelay.java | 52 +++--- .../event/RMIPushEventForwarder.java | 2 +- .../management/remote/rmi/RMIConnector.java | 2 +- .../eventService/EventClientThreadTest.java | 176 ++++++++++++++++++ .../eventService/SharingThreadTest.java | 2 +- 9 files changed, 220 insertions(+), 38 deletions(-) create mode 100644 jdk/test/javax/management/eventService/EventClientThreadTest.java diff --git a/jdk/src/share/classes/com/sun/jmx/event/LeaseManager.java b/jdk/src/share/classes/com/sun/jmx/event/LeaseManager.java index cb1b88bf514..33409a06ce9 100644 --- a/jdk/src/share/classes/com/sun/jmx/event/LeaseManager.java +++ b/jdk/src/share/classes/com/sun/jmx/event/LeaseManager.java @@ -27,7 +27,6 @@ package com.sun.jmx.event; import com.sun.jmx.remote.util.ClassLogger; import java.util.concurrent.Executors; -import java.util.concurrent.FutureTask; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -115,6 +114,7 @@ public class LeaseManager { scheduled = null; } callback.run(); + executor.shutdown(); } } @@ -131,6 +131,13 @@ public class LeaseManager { logger.trace("stop", "canceling lease"); scheduled.cancel(false); scheduled = null; + try { + executor.shutdown(); + } catch (SecurityException e) { + // OK: caller doesn't have RuntimePermission("modifyThread") + // which is unlikely in reality but triggers a test failure otherwise + logger.trace("stop", "exception from executor.shutdown", e); + } } private final Runnable callback; @@ -138,7 +145,7 @@ public class LeaseManager { private final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1, - new DaemonThreadFactory("LeaseManager")); + new DaemonThreadFactory("JMX LeaseManager %d")); private static final ClassLogger logger = new ClassLogger("javax.management.event", "LeaseManager"); diff --git a/jdk/src/share/classes/com/sun/jmx/event/RepeatedSingletonJob.java b/jdk/src/share/classes/com/sun/jmx/event/RepeatedSingletonJob.java index 7de1b40e92d..2fe4a3a152b 100644 --- a/jdk/src/share/classes/com/sun/jmx/event/RepeatedSingletonJob.java +++ b/jdk/src/share/classes/com/sun/jmx/event/RepeatedSingletonJob.java @@ -95,7 +95,9 @@ public abstract class RepeatedSingletonJob implements Runnable { executor.execute(this); } catch (RejectedExecutionException e) { logger.warning( - "setEventReceiver", "Executor threw exception", e); + "execute", + "Executor threw exception (" + this.getClass().getName() + ")", + e); throw new RejectedExecutionException( "Executor.execute threw exception -" + "should not be possible", e); diff --git a/jdk/src/share/classes/com/sun/jmx/remote/internal/ClientCommunicatorAdmin.java b/jdk/src/share/classes/com/sun/jmx/remote/internal/ClientCommunicatorAdmin.java index a6635aad8bd..f90cbc4c50a 100644 --- a/jdk/src/share/classes/com/sun/jmx/remote/internal/ClientCommunicatorAdmin.java +++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/ClientCommunicatorAdmin.java @@ -32,13 +32,15 @@ import com.sun.jmx.remote.util.ClassLogger; import com.sun.jmx.remote.util.EnvHelp; public abstract class ClientCommunicatorAdmin { + private static volatile long threadNo = 1; + public ClientCommunicatorAdmin(long period) { this.period = period; if (period > 0) { checker = new Checker(); - Thread t = new Thread(checker); + Thread t = new Thread(checker, "JMX client heartbeat " + ++threadNo); t.setDaemon(true); t.start(); } else diff --git a/jdk/src/share/classes/javax/management/event/EventClient.java b/jdk/src/share/classes/javax/management/event/EventClient.java index 4b81013531f..10a4df5004b 100644 --- a/jdk/src/share/classes/javax/management/event/EventClient.java +++ b/jdk/src/share/classes/javax/management/event/EventClient.java @@ -264,11 +264,12 @@ public class EventClient implements EventConsumer, NotificationManager { new PerThreadGroupPool.Create() { public ScheduledThreadPoolExecutor createThreadPool(ThreadGroup group) { ThreadFactory daemonThreadFactory = new DaemonThreadFactory( - "EventClient lease renewer %d"); + "JMX EventClient lease renewer %d"); ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor( 20, daemonThreadFactory); - exec.setKeepAliveTime(3, TimeUnit.SECONDS); + exec.setKeepAliveTime(1, TimeUnit.SECONDS); exec.allowCoreThreadTimeOut(true); + exec.setRemoveOnCancelPolicy(true); return exec; } }; diff --git a/jdk/src/share/classes/javax/management/event/FetchingEventRelay.java b/jdk/src/share/classes/javax/management/event/FetchingEventRelay.java index 2b65f9b12d6..9aa68df0fe1 100644 --- a/jdk/src/share/classes/javax/management/event/FetchingEventRelay.java +++ b/jdk/src/share/classes/javax/management/event/FetchingEventRelay.java @@ -31,10 +31,8 @@ import com.sun.jmx.remote.util.ClassLogger; import java.io.IOException; import java.io.NotSerializableException; import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import javax.management.MBeanException; @@ -215,50 +213,47 @@ public class FetchingEventRelay implements EventRelay { this.maxNotifs = maxNotifs; if (executor == null) { - executor = Executors.newSingleThreadScheduledExecutor( + ScheduledThreadPoolExecutor stpe = new ScheduledThreadPoolExecutor(1, daemonThreadFactory); - } + stpe.setKeepAliveTime(1, TimeUnit.SECONDS); + stpe.allowCoreThreadTimeOut(true); + executor = stpe; + this.defaultExecutor = stpe; + } else + this.defaultExecutor = null; this.executor = executor; - if (executor instanceof ScheduledExecutorService) - leaseScheduler = (ScheduledExecutorService) executor; - else { - leaseScheduler = Executors.newSingleThreadScheduledExecutor( - daemonThreadFactory); - } startSequenceNumber = 0; fetchingJob = new MyJob(); } - public void setEventReceiver(EventReceiver eventReceiver) { + public synchronized void setEventReceiver(EventReceiver eventReceiver) { if (logger.traceOn()) { logger.trace("setEventReceiver", ""+eventReceiver); } EventReceiver old = this.eventReceiver; - synchronized(fetchingJob) { - this.eventReceiver = eventReceiver; - if (old == null && eventReceiver != null) - fetchingJob.resume(); - } + this.eventReceiver = eventReceiver; + if (old == null && eventReceiver != null) + fetchingJob.resume(); } public String getClientId() { return clientId; } - public void stop() { + public synchronized void stop() { if (logger.traceOn()) { logger.trace("stop", ""); } - synchronized(fetchingJob) { - if (stopped) { - return; - } - - stopped = true; - clientId = null; + if (stopped) { + return; } + + stopped = true; + clientId = null; + if (defaultExecutor != null) + defaultExecutor.shutdown(); } private class MyJob extends RepeatedSingletonJob { @@ -372,10 +367,9 @@ public class FetchingEventRelay implements EventRelay { private final EventClientDelegateMBean delegate; private String clientId; private boolean stopped = false; - private volatile ScheduledFuture leaseRenewalFuture; private final Executor executor; - private final ScheduledExecutorService leaseScheduler; + private final ExecutorService defaultExecutor; private final MyJob fetchingJob; private final long timeout; @@ -385,5 +379,5 @@ public class FetchingEventRelay implements EventRelay { new ClassLogger("javax.management.event", "FetchingEventRelay"); private static final ThreadFactory daemonThreadFactory = - new DaemonThreadFactory("FetchingEventRelay-executor"); + new DaemonThreadFactory("JMX FetchingEventRelay executor %d"); } diff --git a/jdk/src/share/classes/javax/management/event/RMIPushEventForwarder.java b/jdk/src/share/classes/javax/management/event/RMIPushEventForwarder.java index 2018f98adfc..751300d5443 100644 --- a/jdk/src/share/classes/javax/management/event/RMIPushEventForwarder.java +++ b/jdk/src/share/classes/javax/management/event/RMIPushEventForwarder.java @@ -185,7 +185,7 @@ public class RMIPushEventForwarder implements EventForwarder { private static final ExecutorService executor = Executors.newCachedThreadPool( - new DaemonThreadFactory("RMIEventForwarder Executor")); + new DaemonThreadFactory("JMX RMIEventForwarder Executor")); private final SendingJob sendingJob = new SendingJob(); private final BlockingQueue buffer; diff --git a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java index bdcbb15685b..a620235ac13 100644 --- a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java +++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java @@ -420,7 +420,7 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable new PerThreadGroupPool.Create() { public ThreadPoolExecutor createThreadPool(ThreadGroup group) { ThreadFactory daemonThreadFactory = new DaemonThreadFactory( - "RMIConnector listener dispatch %d"); + "JMX RMIConnector listener dispatch %d"); ThreadPoolExecutor exec = new ThreadPoolExecutor( 1, 10, 1, TimeUnit.SECONDS, new LinkedBlockingDeque(), diff --git a/jdk/test/javax/management/eventService/EventClientThreadTest.java b/jdk/test/javax/management/eventService/EventClientThreadTest.java new file mode 100644 index 00000000000..910bc9cc2d2 --- /dev/null +++ b/jdk/test/javax/management/eventService/EventClientThreadTest.java @@ -0,0 +1,176 @@ +/* + * 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 6747411 + * @summary Check that EventClient instances don't leak threads. + * @author Eamonn McManus + */ + +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.Set; +import java.util.TreeSet; +import javax.management.MBeanServer; +import javax.management.MBeanServerConnection; +import javax.management.MBeanServerDelegate; +import javax.management.MBeanServerNotification; +import javax.management.Notification; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import javax.management.ObjectName; +import javax.management.event.EventClient; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXConnectorServerFactory; +import javax.management.remote.JMXServiceURL; + +public class EventClientThreadTest { + private static final int MAX_TIME_SECONDS = 20; + + private static final BlockingQueue queue = + new ArrayBlockingQueue(100); + + private static final NotificationListener queueListener = + new NotificationListener() { + public void handleNotification(Notification notification, + Object handback) { + queue.add(notification); + } + }; + + private static final NotificationFilter dummyFilter = + new NotificationFilter() { + public boolean isNotificationEnabled(Notification notification) { + return true; + } + }; + + public static void main(String[] args) throws Exception { + long start = System.currentTimeMillis(); + long deadline = start + MAX_TIME_SECONDS * 1000; + + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://"); + JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer( + url, null, mbs); + cs.start(); + JMXServiceURL addr = cs.getAddress(); + JMXConnector cc = JMXConnectorFactory.connect(addr); + MBeanServerConnection mbsc = cc.getMBeanServerConnection(); + + ThreadMXBean threads = ManagementFactory.getThreadMXBean(); + + System.out.println("Opening and closing some EventClients..."); + // If we create a connection, then create and destroy EventClients + // over it, then close it, there should be no "JMX *" threads left. + for (int i = 0; i < 5; i++) + test(mbsc); + + cc.close(); + + showTime("opening and closing initial EventClients", start); + + Set jmxThreads = threadsMatching("JMX .*"); + while (!jmxThreads.isEmpty() && System.currentTimeMillis() < deadline) { + Set jmxThreadsNow = threadsMatching("JMX .*"); + Set gone = new TreeSet(jmxThreads); + gone.removeAll(jmxThreadsNow); + for (String s : gone) + showTime("expiry of \"" + s + "\"", start); + jmxThreads = jmxThreadsNow; + Thread.sleep(10); + } + if (System.currentTimeMillis() >= deadline) { + showThreads(threads); + throw new Exception("Timed out waiting for JMX threads to expire"); + } + + showTime("waiting for JMX threads to expire", start); + + System.out.println("TEST PASSED"); + } + + static void showThreads(ThreadMXBean threads) throws Exception { + long[] ids = threads.getAllThreadIds(); + for (long id : ids) { + ThreadInfo ti = threads.getThreadInfo(id); + String name = (ti == null) ? "(defunct)" : ti.getThreadName(); + System.out.printf("%4d %s\n", id, name); + } + } + + static void showTime(String what, long start) { + long elapsed = System.currentTimeMillis() - start; + System.out.printf("Time after %s: %.3f s\n", what, elapsed / 1000.0); + } + + static Set threadsMatching(String pattern) { + Set matching = new TreeSet(); + ThreadMXBean threads = ManagementFactory.getThreadMXBean(); + long[] ids = threads.getAllThreadIds(); + for (long id : ids) { + ThreadInfo ti = threads.getThreadInfo(id); + String name = (ti == null) ? "(defunct)" : ti.getThreadName(); + if (name.matches(pattern)) + matching.add(name); + } + return matching; + } + + static void test(MBeanServerConnection mbsc) throws Exception { + final ObjectName delegateName = MBeanServerDelegate.DELEGATE_NAME; + final ObjectName testName = new ObjectName("test:type=Test"); + EventClient ec = new EventClient(mbsc); + ec.addNotificationListener(delegateName, queueListener, null, null); + mbsc.createMBean(MBeanServerDelegate.class.getName(), testName); + mbsc.unregisterMBean(testName); + final String[] expectedTypes = { + MBeanServerNotification.REGISTRATION_NOTIFICATION, + MBeanServerNotification.UNREGISTRATION_NOTIFICATION, + }; + for (String s : expectedTypes) { + Notification n = queue.poll(3, TimeUnit.SECONDS); + if (n == null) + throw new Exception("Timed out waiting for notif: " + s); + if (!(n instanceof MBeanServerNotification)) + throw new Exception("Got notif of wrong class: " + n.getClass()); + if (!n.getType().equals(s)) { + throw new Exception("Got notif of wrong type: " + n.getType() + + " (expecting " + s + ")"); + } + } + ec.removeNotificationListener(delegateName, queueListener); + + ec.addNotificationListener(delegateName, queueListener, dummyFilter, "foo"); + ec.removeNotificationListener(delegateName, queueListener, dummyFilter, "foo"); + + ec.close(); + } +} \ No newline at end of file diff --git a/jdk/test/javax/management/eventService/SharingThreadTest.java b/jdk/test/javax/management/eventService/SharingThreadTest.java index a3d7fd37a3c..7339d0806da 100644 --- a/jdk/test/javax/management/eventService/SharingThreadTest.java +++ b/jdk/test/javax/management/eventService/SharingThreadTest.java @@ -1,4 +1,4 @@ -/*/* +/* * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * From 38e8cbedc6c45f3a51cbe0433ec7bd6fde3845ac Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Fri, 12 Sep 2008 17:58:15 +0200 Subject: [PATCH 93/95] 6747899: jmx namespaces: hooks for permission checks should be defined in HandlerInterceptor Reviewed-by: emcmanus --- .../sun/jmx/namespace/HandlerInterceptor.java | 163 +++++++++++++++++- .../RoutingMBeanServerConnection.java | 162 ++--------------- 2 files changed, 174 insertions(+), 151 deletions(-) diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/HandlerInterceptor.java b/jdk/src/share/classes/com/sun/jmx/namespace/HandlerInterceptor.java index 7c2f3934859..56672441956 100644 --- a/jdk/src/share/classes/com/sun/jmx/namespace/HandlerInterceptor.java +++ b/jdk/src/share/classes/com/sun/jmx/namespace/HandlerInterceptor.java @@ -135,7 +135,11 @@ public abstract class HandlerInterceptor public AttributeList getAttributes(ObjectName name, String[] attributes) throws InstanceNotFoundException, ReflectionException { try { - return super.getAttributes(name, attributes); + final String[] authorized = + checkAttributes(name,attributes,"getAttribute"); + final AttributeList attrList = + super.getAttributes(name,authorized); + return attrList; } catch (IOException ex) { throw handleIOException(ex,"getAttributes",name,attributes); } @@ -185,7 +189,8 @@ public abstract class HandlerInterceptor public void removeNotificationListener(ObjectName name, ObjectName listener) throws InstanceNotFoundException, ListenerNotFoundException { try { - super.removeNotificationListener(name, listener); + check(name,null,"removeNotificationListener"); + super.removeNotificationListener(name,listener); } catch (IOException ex) { throw handleIOException(ex,"removeNotificationListener",name,listener); } @@ -205,7 +210,9 @@ public abstract class HandlerInterceptor @Override public String[] getDomains() { try { - return super.getDomains(); + check(null,null,"getDomains"); + final String[] domains = super.getDomains(); + return checkDomains(domains,"getDomains"); } catch (IOException ex) { throw handleIOException(ex,"getDomains"); } @@ -228,7 +235,10 @@ public abstract class HandlerInterceptor InvalidAttributeValueException, MBeanException, ReflectionException { try { - super.setAttribute(name, attribute); + check(name, + (attribute==null?null:attribute.getName()), + "setAttribute"); + super.setAttribute(name,attribute); } catch (IOException ex) { throw handleIOException(ex,"setAttribute",name, attribute); } @@ -237,8 +247,10 @@ public abstract class HandlerInterceptor // From MBeanServerConnection: catch & handles IOException @Override public Set queryNames(ObjectName name, QueryExp query) { + if (name == null) name=ObjectName.WILDCARD; try { - return super.queryNames(name, query); + checkPattern(name,null,"queryNames"); + return super.queryNames(name,query); } catch (IOException ex) { throw handleIOException(ex,"queryNames",name, query); } @@ -247,8 +259,10 @@ public abstract class HandlerInterceptor // From MBeanServerConnection: catch & handles IOException @Override public Set queryMBeans(ObjectName name, QueryExp query) { + if (name == null) name=ObjectName.WILDCARD; try { - return super.queryMBeans(name, query); + checkPattern(name,null,"queryMBeans"); + return super.queryMBeans(name,query); } catch (IOException ex) { throw handleIOException(ex,"queryMBeans",name, query); } @@ -259,6 +273,7 @@ public abstract class HandlerInterceptor public boolean isInstanceOf(ObjectName name, String className) throws InstanceNotFoundException { try { + check(name, null, "isInstanceOf"); return super.isInstanceOf(name, className); } catch (IOException ex) { throw handleIOException(ex,"isInstanceOf",name, className); @@ -272,6 +287,8 @@ public abstract class HandlerInterceptor MBeanRegistrationException, MBeanException, NotCompliantMBeanException { try { + checkCreate(name, className, "instantiate"); + checkCreate(name, className, "registerMBean"); return super.createMBean(className, name); } catch (IOException ex) { throw handleIOException(ex,"createMBean",className, name); @@ -286,6 +303,8 @@ public abstract class HandlerInterceptor MBeanRegistrationException, MBeanException, NotCompliantMBeanException, InstanceNotFoundException { try { + checkCreate(name, className, "instantiate"); + checkCreate(name, className, "registerMBean"); return super.createMBean(className, name, loaderName); } catch (IOException ex) { throw handleIOException(ex,"createMBean",className, name, loaderName); @@ -298,6 +317,7 @@ public abstract class HandlerInterceptor throws MBeanException, AttributeNotFoundException, InstanceNotFoundException, ReflectionException { try { + check(name, attribute, "getAttribute"); return super.getAttribute(name, attribute); } catch (IOException ex) { throw handleIOException(ex,"getAttribute",name, attribute); @@ -310,6 +330,7 @@ public abstract class HandlerInterceptor NotificationFilter filter, Object handback) throws InstanceNotFoundException, ListenerNotFoundException { try { + check(name,null,"removeNotificationListener"); super.removeNotificationListener(name, listener, filter, handback); } catch (IOException ex) { throw handleIOException(ex,"removeNotificationListener",name, @@ -324,6 +345,7 @@ public abstract class HandlerInterceptor Object handback) throws InstanceNotFoundException, ListenerNotFoundException { try { + check(name,null,"removeNotificationListener"); super.removeNotificationListener(name, listener, filter, handback); } catch (IOException ex) { throw handleIOException(ex,"removeNotificationListener",name, @@ -337,6 +359,7 @@ public abstract class HandlerInterceptor NotificationListener listener) throws InstanceNotFoundException, ListenerNotFoundException { try { + check(name,null,"removeNotificationListener"); super.removeNotificationListener(name, listener); } catch (IOException ex) { throw handleIOException(ex,"removeNotificationListener",name, @@ -350,6 +373,7 @@ public abstract class HandlerInterceptor NotificationListener listener, NotificationFilter filter, Object handback) throws InstanceNotFoundException { try { + check(name,null,"addNotificationListener"); super.addNotificationListener(name, listener, filter, handback); } catch (IOException ex) { throw handleIOException(ex,"addNotificationListener",name, @@ -363,6 +387,7 @@ public abstract class HandlerInterceptor NotificationFilter filter, Object handback) throws InstanceNotFoundException { try { + check(name,null,"addNotificationListener"); super.addNotificationListener(name, listener, filter, handback); } catch (IOException ex) { throw handleIOException(ex,"addNotificationListener",name, @@ -385,6 +410,7 @@ public abstract class HandlerInterceptor public void unregisterMBean(ObjectName name) throws InstanceNotFoundException, MBeanRegistrationException { try { + check(name, null, "unregisterMBean"); super.unregisterMBean(name); } catch (IOException ex) { throw handleIOException(ex,"unregisterMBean",name); @@ -397,6 +423,7 @@ public abstract class HandlerInterceptor throws InstanceNotFoundException, IntrospectionException, ReflectionException { try { + check(name, null, "getMBeanInfo"); return super.getMBeanInfo(name); } catch (IOException ex) { throw handleIOException(ex,"getMBeanInfo",name); @@ -408,6 +435,7 @@ public abstract class HandlerInterceptor public ObjectInstance getObjectInstance(ObjectName name) throws InstanceNotFoundException { try { + check(name, null, "getObjectInstance"); return super.getObjectInstance(name); } catch (IOException ex) { throw handleIOException(ex,"getObjectInstance",name); @@ -422,6 +450,8 @@ public abstract class HandlerInterceptor MBeanRegistrationException, MBeanException, NotCompliantMBeanException { try { + checkCreate(name, className, "instantiate"); + checkCreate(name, className, "registerMBean"); return super.createMBean(className, name, params, signature); } catch (IOException ex) { throw handleIOException(ex,"createMBean",className, name, @@ -437,6 +467,8 @@ public abstract class HandlerInterceptor MBeanRegistrationException, MBeanException, NotCompliantMBeanException, InstanceNotFoundException { try { + checkCreate(name, className, "instantiate"); + checkCreate(name, className, "registerMBean"); return super.createMBean(className, name, loaderName, params, signature); } catch (IOException ex) { @@ -450,7 +482,9 @@ public abstract class HandlerInterceptor public AttributeList setAttributes(ObjectName name,AttributeList attributes) throws InstanceNotFoundException, ReflectionException { try { - return super.setAttributes(name, attributes); + final AttributeList authorized = + checkAttributes(name, attributes, "setAttribute"); + return super.setAttributes(name, authorized); } catch (IOException ex) { throw handleIOException(ex,"setAttributes",name, attributes); } @@ -462,6 +496,7 @@ public abstract class HandlerInterceptor String[] signature) throws InstanceNotFoundException, MBeanException, ReflectionException { try { + check(name, operationName, "invoke"); return super.invoke(name, operationName, params, signature); } catch (IOException ex) { throw handleIOException(ex,"invoke",name, operationName, @@ -582,4 +617,118 @@ public abstract class HandlerInterceptor "Not supported in this namespace: "+namespace)); } + /** + * A result might be excluded for security reasons. + */ + @Override + boolean excludesFromResult(ObjectName targetName, String queryMethod) { + return !checkQuery(targetName, queryMethod); + } + + + //---------------------------------------------------------------------- + // Hooks for checking permissions + //---------------------------------------------------------------------- + + /** + * This method is a hook to implement permission checking in subclasses. + * A subclass may override this method and throw a {@link + * SecurityException} if the permission is denied. + * + * @param routingName The name of the MBean in the enclosing context. + * This is of the form {@code //}. + * @param member The {@link + * javax.management.namespace.JMXNamespacePermission#getMember member} + * name. + * @param action The {@link + * javax.management.namespace.JMXNamespacePermission#getActions action} + * name. + * @throws SecurityException if the caller doesn't have the permission + * to perform the given action on the MBean pointed to + * by routingName. + */ + abstract void check(ObjectName routingName, + String member, String action); + + // called in createMBean and registerMBean + abstract void checkCreate(ObjectName routingName, String className, + String action); + + /** + * This is a hook to implement permission checking in subclasses. + * + * Checks that the caller has sufficient permission for returning + * information about {@code sourceName} in {@code action}. + * + * Subclass may override this method and return false if the caller + * doesn't have sufficient permissions. + * + * @param routingName The name of the MBean to include or exclude from + * the query, expressed in the enclosing context. + * This is of the form {@code //}. + * @param action one of "queryNames" or "queryMBeans" + * @return true if {@code sourceName} can be returned. + */ + abstract boolean checkQuery(ObjectName routingName, String action); + + /** + * This method is a hook to implement permission checking in subclasses. + * + * @param routingName The name of the MBean in the enclosing context. + * This is of the form {@code //}. + * @param attributes The list of attributes to check permission for. + * @param action one of "getAttribute" or "setAttribute" + * @return The list of attributes for which the callers has the + * appropriate {@link + * javax.management.namespace.JMXNamespacePermission}. + * @throws SecurityException if the caller doesn't have the permission + * to perform {@code action} on the MBean pointed to by routingName. + */ + abstract String[] checkAttributes(ObjectName routingName, + String[] attributes, String action); + + /** + * This method is a hook to implement permission checking in subclasses. + * + * @param routingName The name of the MBean in the enclosing context. + * This is of the form {@code //}. + * @param attributes The list of attributes to check permission for. + * @param action one of "getAttribute" or "setAttribute" + * @return The list of attributes for which the callers has the + * appropriate {@link + * javax.management.namespace.JMXNamespacePermission}. + * @throws SecurityException if the caller doesn't have the permission + * to perform {@code action} on the MBean pointed to by routingName. + */ + abstract AttributeList checkAttributes(ObjectName routingName, + AttributeList attributes, String action); + + /** + * This method is a hook to implement permission checking in subclasses. + * Checks that the caller as the necessary permissions to view the + * given domain. If not remove the domains for which the caller doesn't + * have permission from the list. + *

+ * By default, this method always returns {@code domains} + * + * @param domains The domains to return. + * @param action "getDomains" + * @return a filtered list of domains. + */ + String[] checkDomains(String[] domains, String action) { + return domains; + } + + // A priori check for queryNames/queryMBeans/ + void checkPattern(ObjectName routingPattern, + String member, String action) { + // pattern is checked only at posteriori by checkQuery. + // checking it a priori usually doesn't work, because ObjectName.apply + // does not work between two patterns. + // We only check that we have the permission requested for 'action'. + check(null,null,action); + } + + + } diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingMBeanServerConnection.java b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingMBeanServerConnection.java index 70df9b504dd..7022e7e2973 100644 --- a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingMBeanServerConnection.java +++ b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingMBeanServerConnection.java @@ -161,11 +161,7 @@ public abstract class RoutingMBeanServerConnection tmp = source().queryNames(sourceName,query); final Set out = processOutputNames(tmp); //System.err.println("queryNames: out: "+out); @@ -467,7 +442,6 @@ public abstract class RoutingMBeanServerConnection//}. - * @param attributes The list of attributes to check permission for. - * @param action one of "getAttribute" or "setAttribute" - * @return The list of attributes for which the callers has the - * appropriate {@link - * javax.management.namespace.JMXNamespacePermission}. + * @param name A target object name expressed in the caller's + * context. In the case of cascading, where the source + * is a sub agent mounted on e.g. namespace "foo", + * that would be a name prefixed by "foo//"... + * @param queryMethod either "queryNames" or "queryMBeans". + * @return true if the name must be excluded. */ - String[] checkAttributes(ObjectName routingName, - String[] attributes, String action) { - check(routingName,null,action); - return attributes; + boolean excludesFromResult(ObjectName targetName, String queryMethod) { + return false; } - /** - * This method is a hook to implement permission checking in subclasses. - * By default, this method does nothing and simply returns - * {@code attribute}. - * - * @param routingName The name of the MBean in the enclosing context. - * This is of the form {@code //}. - * @param attributes The list of attributes to check permission for. - * @param action one of "getAttribute" or "setAttribute" - * @return The list of attributes for which the callers has the - * appropriate {@link - * javax.management.namespace.JMXNamespacePermission}. - */ - AttributeList checkAttributes(ObjectName routingName, - AttributeList attributes, String action) { - check(routingName,null,action); - return attributes; - } - - /** - * This method is a hook to implement permission checking in subclasses. - * By default, this method does nothing. - * A subclass may override this method and throw a {@link - * SecurityException} if the permission is denied. - * - * @param routingName The name of the MBean in the enclosing context. - * This is of the form {@code //}. - * @param member The {@link - * javax.management.namespace.JMXNamespacePermission#getMember member} - * name. - * @param action The {@link - * javax.management.namespace.JMXNamespacePermission#getActions action} - * name. - */ - void check(ObjectName routingName, - String member, String action) { - } - - // called in createMBean and registerMBean - void checkCreate(ObjectName routingName, String className, - String action) { - } - - // A priori check for queryNames/queryMBeans/ - void checkPattern(ObjectName routingPattern, - String member, String action) { - // pattern is checked only at posteriori by checkQuery. - // checking it a priori usually doesn't work, because ObjectName.apply - // does not work between two patterns. - // We only check that we have the permission requested for 'action'. - check(null,null,action); - } - - - /** - * This is a hook to implement permission checking in subclasses. - * - * Checks that the caller has sufficient permission for returning - * information about {@code sourceName} in {@code action}. - * - * By default always return true. Subclass may override this method - * and return false if the caller doesn't have sufficient permissions. - * - * @param routingName The name of the MBean to include or exclude from - * the query, expressed in the enclosing context. - * This is of the form {@code //}. - * @param action one of "queryNames" or "queryMBeans" - * @return true if {@code sourceName} can be returned. - */ - boolean checkQuery(ObjectName routingName, String action) { - return true; - } - - /** - * This method is a hook to implement permission checking in subclasses. - * Checks that the caller as the necessary permissions to view the - * given domain. If not remove the domains for which the caller doesn't - * have permission from the list. - *

- * By default, this method always returns {@code domains} - * - * @param domains The domains to return. - * @param action "getDomains" - * @return a filtered list of domains. - */ - String[] checkDomains(String[] domains, String action) { - return domains; - } } From c3552d0201826914e6d14941f4f34af0929aeb4f Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Fri, 12 Sep 2008 19:06:38 +0200 Subject: [PATCH 94/95] 6747983: jmx namespace: unspecified self-link detection logic Reviewed-by: emcmanus --- .../jmx/namespace/NamespaceInterceptor.java | 226 +------------- .../namespace/JMXRemoteNamespace.java | 112 +------ .../namespace/JMXNamespaceTest.java | 278 +++--------------- 3 files changed, 42 insertions(+), 574 deletions(-) diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java b/jdk/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java index 11afeb2afc1..6862066d2bc 100644 --- a/jdk/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java +++ b/jdk/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java @@ -25,22 +25,15 @@ package com.sun.jmx.namespace; import com.sun.jmx.defaults.JmxProperties; -import java.io.IOException; import java.util.ArrayList; -import java.util.Collections; import java.util.List; -import java.util.Set; -import java.util.UUID; import java.util.logging.Logger; import javax.management.Attribute; import javax.management.AttributeList; import javax.management.MBeanServer; -import javax.management.MBeanServerConnection; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; -import javax.management.QueryExp; -import javax.management.namespace.JMXNamespaces; import javax.management.namespace.JMXNamespace; import javax.management.namespace.JMXNamespacePermission; @@ -54,8 +47,6 @@ import javax.management.namespace.JMXNamespacePermission; */ public class NamespaceInterceptor extends HandlerInterceptor { - private static final Logger PROBE_LOG = Logger.getLogger( - JmxProperties.NAMESPACE_LOGGER+".probe"); // The target name space in which the NamepsaceHandler is mounted. private final String targetNs; @@ -64,21 +55,6 @@ public class NamespaceInterceptor extends HandlerInterceptor { private final ObjectNameRouter proc; - /** - * Internal hack. The JMXRemoteNamespace can be closed and reconnected. - * Each time the JMXRemoteNamespace connects, a probe should be sent - * to detect cycle. The MBeanServer exposed by JMXRemoteNamespace thus - * implements the DynamicProbe interface, which makes it possible for - * this handler to know that it should send a new probe. - * - * XXX: TODO this probe thing is way too complex and fragile. - * This *must* go away or be replaced by something simpler. - * ideas are welcomed. - **/ - public static interface DynamicProbe { - public boolean isProbeRequested(); - } - /** * Creates a new instance of NamespaceInterceptor */ @@ -100,164 +76,6 @@ public class NamespaceInterceptor extends HandlerInterceptor { ", namespace="+this.targetNs+")"; } - /* - * XXX: TODO this probe thing is way too complex and fragile. - * This *must* go away or be replaced by something simpler. - * ideas are welcomed. - */ - private volatile boolean probed = false; - private volatile ObjectName probe; - - // Query Pattern that we will send through the source server in order - // to detect self-linking namespaces. - // - // XXX: TODO this probe thing is way too complex and fragile. - // This *must* go away or be replaced by something simpler. - // ideas are welcomed. - final ObjectName makeProbePattern(ObjectName probe) - throws MalformedObjectNameException { - - // we could probably link the probe pattern with the probe - e.g. - // using the UUID as key in the pattern - but is it worth it? it - // also has some side effects on the context namespace - because - // such a probe may get rejected by the jmx.context// namespace. - // - // The trick here is to devise a pattern that is not likely to - // be blocked by intermediate levels. Querying for all namespace - // handlers in the source (or source namespace) is more likely to - // achieve this goal. - // - return ObjectName.getInstance("*" + - JMXNamespaces.NAMESPACE_SEPARATOR + ":" + - JMXNamespace.TYPE_ASSIGNMENT); - } - - // tell whether the name pattern corresponds to what might have been - // sent as a probe. - // XXX: TODO this probe thing is way too complex and fragile. - // This *must* go away or be replaced by something simpler. - // ideas are welcomed. - final boolean isProbePattern(ObjectName name) { - final ObjectName p = probe; - if (p == null) return false; - try { - return String.valueOf(name).endsWith(targetNs+ - JMXNamespaces.NAMESPACE_SEPARATOR + "*" + - JMXNamespaces.NAMESPACE_SEPARATOR + ":" + - JMXNamespace.TYPE_ASSIGNMENT); - } catch (RuntimeException x) { - // should not happen. - PROBE_LOG.finest("Ignoring unexpected exception in self link detection: "+ - x); - return false; - } - } - - // The first time a request reaches this NamespaceInterceptor, the - // interceptor will send a probe to detect whether the underlying - // JMXNamespace links to itslef. - // - // One way to create such self-linking namespace would be for instance - // to create a JMXNamespace whose getSourceServer() method would return: - // JMXNamespaces.narrowToNamespace(getMBeanServer(), - // getObjectName().getDomain()) - // - // If such an MBeanServer is returned, then any call to that MBeanServer - // will trigger an infinite loop. - // There can be even trickier configurations if remote connections are - // involved. - // - // In order to prevent this from happening, the NamespaceInterceptor will - // send a probe, in an attempt to detect whether it will receive it at - // the other end. If the probe is received, an exception will be thrown - // in order to break the recursion. The probe is only sent once - when - // the first request to the namespace occurs. The DynamicProbe interface - // can also be used by a Sun JMXNamespace implementation to request the - // emission of a probe at any time (see JMXRemoteNamespace - // implementation). - // - // Probes work this way: the NamespaceInterceptor sets a flag and sends - // a queryNames() request. If a queryNames() request comes in when the flag - // is on, then it deduces that there is a self-linking loop - and instead - // of calling queryNames() on the source MBeanServer of the JMXNamespace - // handler (which would cause the loop to go on) it breaks the recursion - // by returning the probe ObjectName. - // If the NamespaceInterceptor receives the probe ObjectName as result of - // its original sendProbe() request it knows that it has been looping - // back on itslef and throws an IOException... - // - // - // XXX: TODO this probe thing is way too complex and fragile. - // This *must* go away or be replaced by something simpler. - // ideas are welcomed. - // - final void sendProbe(MBeanServerConnection msc) - throws IOException { - try { - PROBE_LOG.fine("Sending probe"); - - // This is just to prevent any other thread to modify - // the probe while the detection cycle is in progress. - // - final ObjectName probePattern; - // we don't want to synchronize on this - we use targetNs - // because it's non null and final. - synchronized (targetNs) { - probed = false; - if (probe != null) { - throw new IOException("concurent connection in progress"); - } - final String uuid = UUID.randomUUID().toString(); - final String endprobe = - JMXNamespaces.NAMESPACE_SEPARATOR + uuid + - ":type=Probe,key="+uuid; - final ObjectName newprobe = - ObjectName.getInstance(endprobe); - probePattern = makeProbePattern(newprobe); - probe = newprobe; - } - - try { - PROBE_LOG.finer("Probe query: "+probePattern+" expecting: "+probe); - final Set res = msc.queryNames(probePattern, null); - final ObjectName expected = probe; - PROBE_LOG.finer("Probe res: "+res); - if (res.contains(expected)) { - throw new IOException("namespace " + - targetNs + " is linking to itself: " + - "cycle detected by probe"); - } - } catch (SecurityException x) { - PROBE_LOG.finer("Can't check for cycles: " + x); - // can't do anything.... - } catch (RuntimeException x) { - PROBE_LOG.finer("Exception raised by queryNames: " + x); - throw x; - } finally { - probe = null; - } - } catch (MalformedObjectNameException x) { - final IOException io = - new IOException("invalid name space: probe failed"); - io.initCause(x); - throw io; - } - PROBE_LOG.fine("Probe returned - no cycles"); - probed = true; - } - - // allows a Sun implementation JMX Namespace, such as the - // JMXRemoteNamespace, to control when a probe should be sent. - // - // XXX: TODO this probe thing is way too complex and fragile. - // This *must* go away or be replaced by something simpler. - // ideas are welcomed. - private boolean isProbeRequested(Object o) { - if (o instanceof DynamicProbe) - return ((DynamicProbe)o).isProbeRequested(); - return false; - } - /** * This method will send a probe to detect self-linking name spaces. * A self linking namespace is a namespace that links back directly @@ -277,29 +95,9 @@ public class NamespaceInterceptor extends HandlerInterceptor { * (see JMXRemoteNamespace implementation). */ private MBeanServer connection() { - try { - final MBeanServer c = super.source(); - if (probe != null) // should not happen - throw new RuntimeException("connection is being probed"); - - if (probed == false || isProbeRequested(c)) { - try { - // Should not happen if class well behaved. - // Never probed. Force it. - //System.err.println("sending probe for " + - // "target="+targetNs+", source="+srcNs); - sendProbe(c); - } catch (IOException io) { - throw new RuntimeException(io.getMessage(), io); - } - } - - if (c != null) { - return c; - } - } catch (RuntimeException x) { - throw x; - } + final MBeanServer c = super.source(); + if (c != null) return c; + // should not come here throw new NullPointerException("getMBeanServerConnection"); } @@ -315,24 +113,6 @@ public class NamespaceInterceptor extends HandlerInterceptor { return super.source(); } - /** - * Calls {@link MBeanServerConnection#queryNames queryNames} - * on the underlying - * {@link #getMBeanServerConnection MBeanServerConnection}. - **/ - @Override - public final Set queryNames(ObjectName name, QueryExp query) { - // XXX: TODO this probe thing is way too complex and fragile. - // This *must* go away or be replaced by something simpler. - // ideas are welcomed. - PROBE_LOG.finer("probe is: "+probe+" pattern is: "+name); - if (probe != null && isProbePattern(name)) { - PROBE_LOG.finer("Return probe: "+probe); - return Collections.singleton(probe); - } - return super.queryNames(name, query); - } - @Override protected ObjectName toSource(ObjectName targetName) throws MalformedObjectNameException { diff --git a/jdk/src/share/classes/javax/management/namespace/JMXRemoteNamespace.java b/jdk/src/share/classes/javax/management/namespace/JMXRemoteNamespace.java index 1e877e0ce34..6958f57f2d7 100644 --- a/jdk/src/share/classes/javax/management/namespace/JMXRemoteNamespace.java +++ b/jdk/src/share/classes/javax/management/namespace/JMXRemoteNamespace.java @@ -28,11 +28,9 @@ package javax.management.namespace; import com.sun.jmx.defaults.JmxProperties; import com.sun.jmx.mbeanserver.Util; import com.sun.jmx.namespace.JMXNamespaceUtils; -import com.sun.jmx.namespace.NamespaceInterceptor.DynamicProbe; import com.sun.jmx.remote.util.EnvHelp; import java.io.IOException; -import java.security.AccessControlException; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; @@ -44,9 +42,7 @@ import javax.management.AttributeChangeNotification; import javax.management.InstanceNotFoundException; import javax.management.ListenerNotFoundException; import javax.management.MBeanNotificationInfo; -import javax.management.MBeanPermission; import javax.management.MBeanServerConnection; -import javax.management.MalformedObjectNameException; import javax.management.Notification; import javax.management.NotificationBroadcasterSupport; import javax.management.NotificationEmitter; @@ -118,9 +114,6 @@ public class JMXRemoteNamespace */ private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER; - private static final Logger PROBE_LOG = Logger.getLogger( - JmxProperties.NAMESPACE_LOGGER_NAME+".probe"); - // This connection listener is used to listen for connection events from // the underlying JMXConnector. It is used in particular to maintain the @@ -153,8 +146,7 @@ public class JMXRemoteNamespace // because the one that is actually used is the one supplied by the // override of getMBeanServerConnection(). private static class JMXRemoteNamespaceDelegate - extends MBeanServerConnectionWrapper - implements DynamicProbe { + extends MBeanServerConnectionWrapper { private volatile JMXRemoteNamespace parent=null; JMXRemoteNamespaceDelegate() { @@ -180,9 +172,6 @@ public class JMXRemoteNamespace } - public boolean isProbeRequested() { - return this.parent.isProbeRequested(); - } } private static final MBeanNotificationInfo connectNotification = @@ -201,7 +190,6 @@ public class JMXRemoteNamespace private volatile MBeanServerConnection server = null; private volatile JMXConnector conn = null; private volatile ClassLoader defaultClassLoader = null; - private volatile boolean probed; /** * Creates a new instance of {@code JMXRemoteNamespace}. @@ -241,9 +229,6 @@ public class JMXRemoteNamespace // handles (dis)connection events this.listener = new ConnectionListener(); - - // XXX TODO: remove the probe, or simplify it. - this.probed = false; } /** @@ -274,10 +259,6 @@ public class JMXRemoteNamespace return optionsMap; } - boolean isProbeRequested() { - return probed==false; - } - public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) { broadcaster.addNotificationListener(listener, filter, handback); @@ -603,26 +584,7 @@ public class JMXRemoteNamespace } public void connect() throws IOException { - if (conn != null) { - try { - // This is much too fragile. It must go away! - PROBE_LOG.finest("Probing again..."); - triggerProbe(getMBeanServerConnection()); - } catch(Exception x) { - close(); - Throwable cause = x; - // if the cause is a security exception - rethrows it... - while (cause != null) { - if (cause instanceof SecurityException) - throw (SecurityException) cause; - cause = cause.getCause(); - } - throw new IOException("connection failed: cycle?",x); - } - } LOG.fine("connecting..."); - // TODO remove these traces - // System.err.println(getInitParameter()+" connecting"); final Map env = new HashMap(getEnvMap()); try { @@ -652,79 +614,9 @@ public class JMXRemoteNamespace throw x; } - - // XXX Revisit here - // Note from the author: This business of switching connection is - // incredibly complex. Isn't there any means to simplify it? - // switchConnection(conn,aconn,msc); - try { - triggerProbe(msc); - } catch(Exception x) { - close(); - Throwable cause = x; - // if the cause is a security exception - rethrows it... - while (cause != null) { - if (cause instanceof SecurityException) - throw (SecurityException) cause; - cause = cause.getCause(); - } - throw new IOException("connection failed: cycle?",x); - } - LOG.fine("connected."); - } - // If this is a self-linking namespace, this method should trigger - // the emission of a probe in the wrapping NamespaceInterceptor. - // The first call to source() in the wrapping NamespaceInterceptor - // causes the emission of the probe. - // - // Note: the MBeanServer returned by getSourceServer - // (our private JMXRemoteNamespaceDelegate inner class) - // implements a sun private interface (DynamicProbe) which is - // used by the NamespaceInterceptor to determine whether it should - // send a probe or not. - // We needed this interface here because the NamespaceInterceptor - // has otherwise no means to knows that this object has just - // connected, and that a new probe should be sent. - // - // Probes work this way: the NamespaceInterceptor sets a flag and sends - // a queryNames() request. If a queryNames() request comes in when the flag - // is on, then it deduces that there is a self-linking loop - and instead - // of calling queryNames() on the JMXNamespace (which would cause the - // loop to go on) it breaks the recursion by returning the probe ObjectName. - // If the NamespaceInterceptor receives the probe ObjectName as result of - // its original queryNames() it knows that it has been looping back on - // itslef and throws an Exception - which will be raised through this - // method, thus preventing the connection to be established... - // - // More info in the com.sun.jmx.namespace.NamespaceInterceptor class - // - // XXX: TODO this probe thing is way too complex and fragile. - // This *must* go away or be replaced by something simpler. - // ideas are welcomed. - // - private void triggerProbe(final MBeanServerConnection msc) - throws MalformedObjectNameException, IOException { - // Query Pattern that we will send through the source server in order - // to detect self-linking namespaces. - // - // - final ObjectName pattern; - pattern = ObjectName.getInstance("*" + - JMXNamespaces.NAMESPACE_SEPARATOR + ":" + - JMXNamespace.TYPE_ASSIGNMENT); - probed = false; - try { - msc.queryNames(pattern, null); - probed = true; - } catch (AccessControlException x) { - // if we have an MBeanPermission missing then do nothing... - if (!(x.getPermission() instanceof MBeanPermission)) - throw x; - PROBE_LOG.finer("Can't check for cycles: " + x); - probed = false; // no need to do it again... - } + LOG.fine("connected."); } public void close() throws IOException { diff --git a/jdk/test/javax/management/namespace/JMXNamespaceTest.java b/jdk/test/javax/management/namespace/JMXNamespaceTest.java index 1c2ffac9d6b..a35377112aa 100644 --- a/jdk/test/javax/management/namespace/JMXNamespaceTest.java +++ b/jdk/test/javax/management/namespace/JMXNamespaceTest.java @@ -35,7 +35,6 @@ * NamespaceController.java NamespaceControllerMBean.java * @run main/othervm JMXNamespaceTest */ -import java.io.IOException; import java.lang.management.ManagementFactory; import java.lang.management.MemoryMXBean; import java.lang.reflect.InvocationTargetException; @@ -52,10 +51,10 @@ import javax.management.InvalidAttributeValueException; import javax.management.JMX; import javax.management.MBeanServer; import javax.management.MBeanServerConnection; +import javax.management.MBeanServerFactory; import javax.management.NotificationEmitter; import javax.management.ObjectInstance; import javax.management.ObjectName; -import javax.management.RuntimeOperationsException; import javax.management.StandardMBean; import javax.management.namespace.JMXNamespaces; import javax.management.namespace.JMXNamespace; @@ -155,7 +154,7 @@ public class JMXNamespaceTest { } } - private static class SimpleTestConf { + public static class SimpleTestConf { public final Wombat wombat; public final StandardMBean mbean; public final String dirname; @@ -457,259 +456,56 @@ public class JMXNamespaceTest { } } - /** - * Test cycle detection. - * mkdir test ; cd test ; ln -s . kanga ; ln -s kanga/kanga/roo/kanga roo - * touch kanga/roo/wombat - **/ - public static void probeKangaRooTest(String[] args) { - final SimpleTestConf conf; + public static void verySimpleTest(String[] args) { + System.err.println("verySimpleTest: starting"); try { - conf = new SimpleTestConf(args); - try { - final JMXServiceURL url = - new JMXServiceURL("rmi","localHost",0); - final Map empty = Collections.emptyMap(); - final JMXConnectorServer server = - JMXConnectorServerFactory.newJMXConnectorServer(url, - empty,conf.server); - server.start(); - final JMXServiceURL address = server.getAddress(); - final JMXConnector client = - JMXConnectorFactory.connect(address, - empty); - final String[] signature = { - JMXServiceURL.class.getName(), - Map.class.getName(), - }; - - final Object[] params = { - address, - null, - }; - final MBeanServerConnection c = - client.getMBeanServerConnection(); - - // ln -s . kanga - final ObjectName dirName1 = - new ObjectName("kanga//:type=JMXNamespace"); - c.createMBean(JMXRemoteTargetNamespace.class.getName(), - dirName1, params,signature); - c.invoke(dirName1, "connect", null, null); - try { - // ln -s kanga//kanga//roo//kanga roo - final JMXNamespace local = new JMXNamespace( - new MBeanServerConnectionWrapper(null, - JMXNamespaceTest.class.getClassLoader()){ - - @Override - protected MBeanServerConnection getMBeanServerConnection() { - return JMXNamespaces.narrowToNamespace(c, - "kanga//kanga//roo//kanga" - ); - } - - }); - final ObjectName dirName2 = - new ObjectName("roo//:type=JMXNamespace"); - conf.server.registerMBean(local,dirName2); - System.out.println(dirName2 + " created!"); - try { - // touch kanga/roo/wombat - final ObjectName wombatName1 = - new ObjectName("kanga//roo//"+conf.wombatName); - final WombatMBean wombat1 = - JMX.newMBeanProxy(c,wombatName1,WombatMBean.class); - final String newCaption="I am still the same old wombat"; - Exception x = null; - try { - wombat1.setCaption(newCaption); - } catch (RuntimeOperationsException r) { - x=r.getTargetException(); - System.out.println("Got expected exception: " + x); - // r.printStackTrace(); - } - if (x == null) - throw new RuntimeException("cycle not detected!"); - } finally { - c.unregisterMBean(dirName2); - } - } finally { - c.unregisterMBean(dirName1); - client.close(); - server.stop(); - } - } finally { - conf.close(); - } - System.err.println("probeKangaRooTest PASSED"); + final MBeanServer srv = MBeanServerFactory.createMBeanServer(); + srv.registerMBean(new JMXNamespace( + JMXNamespaces.narrowToNamespace(srv, "foo")), + JMXNamespaces.getNamespaceObjectName("foo")); + throw new Exception("Excpected IllegalArgumentException not raised."); + } catch (IllegalArgumentException x) { + System.err.println("verySimpleTest: got expected exception: "+x); } catch (Exception x) { - System.err.println("probeKangaRooTest FAILED: " +x); + System.err.println("verySimpleTest FAILED: " +x); x.printStackTrace(); throw new RuntimeException(x); } + System.err.println("verySimpleTest: PASSED"); } - /** - * Test cycle detection 2. - * mkdir test ; cd test ; ln -s . roo ; ln -s roo/roo kanga - * touch kanga/roo/wombat ; rm roo ; ln -s kanga roo ; - * touch kanga/roo/wombat - * - **/ - public static void probeKangaRooCycleTest(String[] args) { - final SimpleTestConf conf; - try { - conf = new SimpleTestConf(args); - Exception failed = null; - try { - final JMXServiceURL url = - new JMXServiceURL("rmi","localHost",0); - final Map empty = Collections.emptyMap(); - final JMXConnectorServer server = - JMXConnectorServerFactory.newJMXConnectorServer(url, - empty,conf.server); - server.start(); - final JMXServiceURL address = server.getAddress(); - final JMXConnector client = - JMXConnectorFactory.connect(address, - empty); - final String[] signature = { - JMXServiceURL.class.getName(), - Map.class.getName(), - }; - final String[] signature2 = { - JMXServiceURL.class.getName(), - Map.class.getName(), - String.class.getName() - }; - final Object[] params = { - address, - Collections.emptyMap(), - }; - final Object[] params2 = { - address, - null, - "kanga", - }; - final MBeanServerConnection c = - client.getMBeanServerConnection(); - // ln -s . roo - final ObjectName dirName1 = - new ObjectName("roo//:type=JMXNamespace"); - c.createMBean(JMXRemoteTargetNamespace.class.getName(), - dirName1, params,signature); - c.invoke(dirName1, "connect",null,null); - try { - final Map emptyMap = - Collections.emptyMap(); - final JMXNamespace local = new JMXNamespace( - new MBeanServerConnectionWrapper( - JMXNamespaces.narrowToNamespace(c, - "roo//roo//"), - JMXNamespaceTest.class.getClassLoader())) { - }; - // ln -s roo/roo kanga - final ObjectName dirName2 = - new ObjectName("kanga//:type=JMXNamespace"); - conf.server.registerMBean(local,dirName2); - System.out.println(dirName2 + " created!"); - try { - // touch kanga/roo/wombat - final ObjectName wombatName1 = - new ObjectName("kanga//roo//"+conf.wombatName); - final WombatMBean wombat1 = - JMX.newMBeanProxy(c,wombatName1,WombatMBean.class); - final String newCaption="I am still the same old wombat"; - wombat1.setCaption(newCaption); - // rm roo - c.unregisterMBean(dirName1); - // ln -s kanga roo - System.err.println("**** Creating " + dirName1 + - " ****"); - c.createMBean(JMXRemoteTargetNamespace.class.getName(), - dirName1, params2,signature2); - System.err.println("**** Created " + dirName1 + - " ****"); - Exception x = null; - try { - // touch kanga/roo/wombat - wombat1.setCaption(newCaption+" I hope"); - } catch (RuntimeOperationsException r) { - x=(Exception)r.getCause(); - System.out.println("Got expected exception: " + x); - //r.printStackTrace(); - } - if (x == null) - throw new RuntimeException("should have failed!"); - x = null; - try { - // ls kanga/roo/wombat - System.err.println("**** Connecting " + dirName1 + - " ****"); - JMX.newMBeanProxy(c,dirName1, - JMXRemoteNamespaceMBean.class).connect(); - System.err.println("**** Connected " + dirName1 + - " ****"); - } catch (IOException r) { - x=r; - System.out.println("Got expected exception: " + x); - //r.printStackTrace(); - } - System.err.println("**** Expected Exception Not Raised ****"); - if (x == null) { - System.out.println(dirName1+" contains: "+ - c.queryNames(new ObjectName( - dirName1.getDomain()+"*:*"),null)); - throw new RuntimeException("cycle not detected!"); - } - } catch (Exception t) { - if (failed == null) failed = t; - } finally { - c.unregisterMBean(dirName2); - } - } finally { - try { - c.unregisterMBean(dirName1); - } catch (Exception t) { - if (failed == null) failed = t; - System.err.println("Failed to unregister "+dirName1+ - ": "+t); - } - try { - client.close(); - } catch (Exception t) { - if (failed == null) failed = t; - System.err.println("Failed to close client: "+t); - } - try { - server.stop(); - } catch (Exception t) { - if (failed == null) failed = t; - System.err.println("Failed to stop server: "+t); - } - } - } finally { - try { - conf.close(); - } catch (Exception t) { - if (failed == null) failed = t; - System.err.println("Failed to stop server: "+t); - } - } - if (failed != null) throw failed; - System.err.println("probeKangaRooCycleTest PASSED"); + public static void verySimpleTest2(String[] args) { + System.err.println("verySimpleTest2: starting"); + try { + final MBeanServer srv = MBeanServerFactory.createMBeanServer(); + final JMXConnectorServer cs = JMXConnectorServerFactory. + newJMXConnectorServer(new JMXServiceURL("rmi",null,0), + null, srv); + cs.start(); + final JMXConnector cc = JMXConnectorFactory.connect(cs.getAddress()); + + srv.registerMBean(new JMXNamespace( + new MBeanServerConnectionWrapper( + JMXNamespaces.narrowToNamespace( + cc.getMBeanServerConnection(), + "foo"))), + JMXNamespaces.getNamespaceObjectName("foo")); + throw new Exception("Excpected IllegalArgumentException not raised."); + } catch (IllegalArgumentException x) { + System.err.println("verySimpleTest2: got expected exception: "+x); } catch (Exception x) { - System.err.println("probeKangaRooCycleTest FAILED: " +x); + System.err.println("verySimpleTest2 FAILED: " +x); x.printStackTrace(); throw new RuntimeException(x); } + System.err.println("verySimpleTest2: PASSED"); } + public static void main(String[] args) { simpleTest(args); recursiveTest(args); - probeKangaRooTest(args); - probeKangaRooCycleTest(args); + verySimpleTest(args); + verySimpleTest2(args); } } From b56f92d23b9864980c44dbb3aa3e53aa9a42d886 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Wed, 17 Sep 2008 13:40:40 +0200 Subject: [PATCH 95/95] 6748745: JConsole: plotters don't resize well when the window is resized Part of the fix was contributed by jfdenise Reviewed-by: jfdenise --- .../classes/sun/tools/jconsole/Plotter.java | 22 ++++++-- .../jconsole/inspector/XMBeanAttributes.java | 4 +- .../tools/jconsole/inspector/XPlotter.java | 2 +- .../jconsole/inspector/XPlottingViewer.java | 51 +++++++++---------- 4 files changed, 44 insertions(+), 35 deletions(-) diff --git a/jdk/src/share/classes/sun/tools/jconsole/Plotter.java b/jdk/src/share/classes/sun/tools/jconsole/Plotter.java index ea9d637ed7a..5c8305bac7a 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/Plotter.java +++ b/jdk/src/share/classes/sun/tools/jconsole/Plotter.java @@ -30,18 +30,15 @@ import java.awt.event.*; import java.beans.*; import java.io.*; import java.lang.reflect.Array; -import java.text.*; import java.util.*; import javax.accessibility.*; import javax.swing.*; import javax.swing.border.*; -import javax.swing.event.*; import javax.swing.filechooser.*; import javax.swing.filechooser.FileFilter; import com.sun.tools.jconsole.JConsoleContext; -import com.sun.tools.jconsole.JConsoleContext.ConnectionState; import static com.sun.tools.jconsole.JConsoleContext.ConnectionState.*; @@ -130,6 +127,7 @@ public class Plotter extends JComponent private int bottomMargin = 45; private int leftMargin = 65; private int rightMargin = 70; + private final boolean displayLegend; public Plotter() { this(Unit.NONE, 0); @@ -139,15 +137,21 @@ public class Plotter extends JComponent this(unit, 0); } + public Plotter(Unit unit, int decimals) { + this(unit,decimals,true); + } + // Note: If decimals > 0 then values must be decimally shifted left // that many places, i.e. multiplied by Math.pow(10.0, decimals). - public Plotter(Unit unit, int decimals) { + public Plotter(Unit unit, int decimals, boolean displayLegend) { + this.displayLegend = displayLegend; setUnit(unit); setDecimals(decimals); enableEvents(AWTEvent.MOUSE_EVENT_MASK); addMouseListener(new MouseAdapter() { + @Override public void mousePressed(MouseEvent e) { if (getParent() instanceof PlotterPanel) { getParent().requestFocusInWindow(); @@ -240,6 +244,7 @@ public class Plotter extends JComponent } } + @Override public JPopupMenu getComponentPopupMenu() { if (popupMenu == null) { popupMenu = new JPopupMenu(Resources.getText("Chart:")); @@ -330,6 +335,7 @@ public class Plotter extends JComponent } } + @Override public void paintComponent(Graphics g) { super.paintComponent(g); @@ -670,7 +676,7 @@ public class Plotter extends JComponent curValue += "%"; } int valWidth = fm.stringWidth(curValue); - String legend = seq.name; + String legend = (displayLegend?seq.name:""); int legendWidth = fm.stringWidth(legend); if (checkRightMargin(valWidth) || checkRightMargin(legendWidth)) { // Wait for next repaint @@ -986,10 +992,12 @@ public class Plotter extends JComponent } private static class SaveDataFileChooser extends JFileChooser { + private static final long serialVersionUID = -5182890922369369669L; SaveDataFileChooser() { setFileFilter(new FileNameExtensionFilter("CSV file", "csv")); } + @Override public void approveSelection() { File file = getSelectedFile(); if (file != null) { @@ -1034,6 +1042,7 @@ public class Plotter extends JComponent } } + @Override public AccessibleContext getAccessibleContext() { if (accessibleContext == null) { accessibleContext = new AccessiblePlotter(); @@ -1042,10 +1051,12 @@ public class Plotter extends JComponent } protected class AccessiblePlotter extends AccessibleJComponent { + private static final long serialVersionUID = -3847205410473510922L; protected AccessiblePlotter() { setAccessibleName(getText("Plotter.accessibleName")); } + @Override public String getAccessibleName() { String name = super.getAccessibleName(); @@ -1076,6 +1087,7 @@ public class Plotter extends JComponent return name; } + @Override public AccessibleRole getAccessibleRole() { return AccessibleRole.CANVAS; } diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanAttributes.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanAttributes.java index 5fca79d3777..4fe9e737fd1 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanAttributes.java +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanAttributes.java @@ -872,8 +872,8 @@ public class XMBeanAttributes extends XTable { MaximizedCellRenderer(Component comp) { this.comp = comp; Dimension d = comp.getPreferredSize(); - if (d.getHeight() > 200) { - comp.setPreferredSize(new Dimension((int) d.getWidth(), 200)); + if (d.getHeight() > 220) { + comp.setPreferredSize(new Dimension((int) d.getWidth(), 220)); } } @Override diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlotter.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlotter.java index 24b4104b7c5..8be8c5ca898 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlotter.java +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlotter.java @@ -34,7 +34,7 @@ public class XPlotter extends Plotter { JTable table; public XPlotter(JTable table, Plotter.Unit unit) { - super(unit); + super(unit,0,false); this.table = table; } @Override diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlottingViewer.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlottingViewer.java index 7da7576b552..0c074a5599e 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlottingViewer.java +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlottingViewer.java @@ -27,14 +27,10 @@ package sun.tools.jconsole.inspector; import java.awt.*; import java.awt.event.*; -import java.io.*; import java.util.*; import java.util.Timer; -import javax.management.*; import javax.swing.*; -import javax.swing.border.*; -import javax.swing.event.*; import sun.tools.jconsole.*; @@ -127,6 +123,7 @@ public class XPlottingViewer extends PlotterPanel implements ActionListener { setBackground(g.getColor()); plotter.paintComponent(g); }*/ + @Override public void actionPerformed(ActionEvent evt) { plotterCache.remove(key); Timer t = timerCache.remove(key); @@ -141,9 +138,11 @@ public class XPlottingViewer extends PlotterPanel implements ActionListener { JTable table) { final Plotter plotter = new XPlotter(table, Plotter.Unit.NONE) { Dimension prefSize = new Dimension(400, 170); + @Override public Dimension getPreferredSize() { return prefSize; } + @Override public Dimension getMinimumSize() { return prefSize; } @@ -183,42 +182,40 @@ public class XPlottingViewer extends PlotterPanel implements ActionListener { return plotter; } - //Create Plotter display private void setupDisplay(Plotter plotter) { - //setLayout(new GridLayout(2,0)); - GridBagLayout gbl = new GridBagLayout(); - setLayout(gbl); + final JPanel buttonPanel = new JPanel(); + final GridBagLayout gbl = new GridBagLayout(); + buttonPanel.setLayout(gbl); + setLayout(new BorderLayout()); plotButton = new JButton(Resources.getText("Discard chart")); plotButton.addActionListener(this); plotButton.setEnabled(true); - // Add the display to the top four cells GridBagConstraints buttonConstraints = new GridBagConstraints(); buttonConstraints.gridx = 0; buttonConstraints.gridy = 0; buttonConstraints.fill = GridBagConstraints.VERTICAL; buttonConstraints.anchor = GridBagConstraints.CENTER; gbl.setConstraints(plotButton, buttonConstraints); - add(plotButton); - - GridBagConstraints plotterConstraints = new GridBagConstraints(); - plotterConstraints.gridx = 0; - plotterConstraints.gridy = 1; - plotterConstraints.weightx = 1; - //plotterConstraints.gridwidth = (int) plotter.getPreferredSize().getWidth(); - //plotterConstraints.gridheight = (int) plotter.getPreferredSize().getHeight(); - plotterConstraints.fill = GridBagConstraints.VERTICAL; - gbl.setConstraints(plotter, plotterConstraints); - - - //bordered = new JPanel(); - //bordered.setPreferredSize(new Dimension(400, 250)); - //bordered.add(plotButton); - //bordered.add(plotter); - - //add(bordered); + buttonPanel.add(plotButton); + if (attributeName != null && attributeName.length()!=0) { + final JPanel plotterLabelPanel = new JPanel(); + final JLabel label = new JLabel(attributeName); + final GridBagLayout gbl2 = new GridBagLayout(); + plotterLabelPanel.setLayout(gbl2); + final GridBagConstraints labelConstraints = new GridBagConstraints(); + labelConstraints.gridx = 0; + labelConstraints.gridy = 0; + labelConstraints.fill = GridBagConstraints.VERTICAL; + labelConstraints.anchor = GridBagConstraints.CENTER; + labelConstraints.ipady = 10; + gbl2.setConstraints(label, labelConstraints); + plotterLabelPanel.add(label); + add(plotterLabelPanel, BorderLayout.NORTH); + } setPlotter(plotter); + add(buttonPanel, BorderLayout.SOUTH); repaint(); }