Mercurial > hg > truffle
diff src/share/vm/runtime/stubCodeGenerator.cpp @ 0:a61af66fc99e jdk7-b24
Initial load
author | duke |
---|---|
date | Sat, 01 Dec 2007 00:00:00 +0000 |
parents | |
children | c7c777385a15 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/runtime/stubCodeGenerator.cpp Sat Dec 01 00:00:00 2007 +0000 @@ -0,0 +1,145 @@ +/* + * Copyright 1997-2004 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/_stubCodeGenerator.cpp.incl" + + +// Implementation of StubCodeDesc + +StubCodeDesc* StubCodeDesc::_list = NULL; +int StubCodeDesc::_count = 0; + + +StubCodeDesc* StubCodeDesc::desc_for(address pc) { + StubCodeDesc* p = _list; + while (p != NULL && !p->contains(pc)) p = p->_next; + // p == NULL || p->contains(pc) + return p; +} + + +StubCodeDesc* StubCodeDesc::desc_for_index(int index) { + StubCodeDesc* p = _list; + while (p != NULL && p->index() != index) p = p->_next; + return p; +} + + +const char* StubCodeDesc::name_for(address pc) { + StubCodeDesc* p = desc_for(pc); + return p == NULL ? NULL : p->name(); +} + + +void StubCodeDesc::print() { + tty->print(group()); + tty->print("::"); + tty->print(name()); + tty->print(" [" INTPTR_FORMAT ", " INTPTR_FORMAT "[ (%d bytes)", begin(), end(), size_in_bytes()); +} + + + +// Implementation of StubCodeGenerator + +StubCodeGenerator::StubCodeGenerator(CodeBuffer* code) { + _masm = new MacroAssembler(code); + _first_stub = _last_stub = NULL; +} + +#ifndef PRODUCT +extern "C" { + static int compare_cdesc(const void* void_a, const void* void_b) { + int ai = (*((StubCodeDesc**) void_a))->index(); + int bi = (*((StubCodeDesc**) void_b))->index(); + return ai - bi; + } +} +#endif + +StubCodeGenerator::~StubCodeGenerator() { +#ifndef PRODUCT + if (PrintStubCode) { + CodeBuffer* cbuf = _masm->code(); + CodeBlob* blob = CodeCache::find_blob_unsafe(cbuf->insts()->start()); + if (blob != NULL) { + blob->set_comments(cbuf->comments()); + } + bool saw_first = false; + StubCodeDesc* toprint[1000]; + int toprint_len = 0; + for (StubCodeDesc* cdesc = _last_stub; cdesc != NULL; cdesc = cdesc->_next) { + toprint[toprint_len++] = cdesc; + if (cdesc == _first_stub) { saw_first = true; break; } + } + assert(saw_first, "must get both first & last"); + // Print in reverse order: + qsort(toprint, toprint_len, sizeof(toprint[0]), compare_cdesc); + for (int i = 0; i < toprint_len; i++) { + StubCodeDesc* cdesc = toprint[i]; + cdesc->print(); + tty->cr(); + Disassembler::decode(cdesc->begin(), cdesc->end()); + tty->cr(); + } + } +#endif //PRODUCT +} + + +void StubCodeGenerator::stub_prolog(StubCodeDesc* cdesc) { + // default implementation - do nothing +} + + +void StubCodeGenerator::stub_epilog(StubCodeDesc* cdesc) { + // default implementation - record the cdesc + if (_first_stub == NULL) _first_stub = cdesc; + _last_stub = cdesc; +} + + +// Implementation of CodeMark + +StubCodeMark::StubCodeMark(StubCodeGenerator* cgen, const char* group, const char* name) { + _cgen = cgen; + _cdesc = new StubCodeDesc(group, name, _cgen->assembler()->pc()); + _cgen->stub_prolog(_cdesc); + // define the stub's beginning (= entry point) to be after the prolog: + _cdesc->set_begin(_cgen->assembler()->pc()); +} + +StubCodeMark::~StubCodeMark() { + _cgen->assembler()->flush(); + _cdesc->set_end(_cgen->assembler()->pc()); + assert(StubCodeDesc::_list == _cdesc, "expected order on list"); + _cgen->stub_epilog(_cdesc); + VTune::register_stub(_cdesc->name(), _cdesc->begin(), _cdesc->end()); + Forte::register_stub(_cdesc->name(), _cdesc->begin(), _cdesc->end()); + + if (JvmtiExport::should_post_dynamic_code_generated()) { + JvmtiExport::post_dynamic_code_generated(_cdesc->name(), _cdesc->begin(), _cdesc->end()); + } +}