00001 /* Copyright 1994, 1995 LongView Technologies L.L.C. $Revision: 1.32 $ */ 00002 /* Copyright (c) 2006, Sun Microsystems, Inc. 00003 All rights reserved. 00004 00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 00006 following conditions are met: 00007 00008 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 00009 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 00010 disclaimer in the documentation and/or other materials provided with the distribution. 00011 * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived 00012 from this software without specific prior written permission. 00013 00014 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 00015 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 00016 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00017 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00018 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 00019 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 00020 00021 00022 */ 00023 00024 // CodeIterator is a simple but fast iterator for 00025 // scanning byte code instructions in a methodOop. 00026 00027 class CodeIterator: public StackObj { 00028 private: 00029 methodOop method; 00030 u_char* current; 00031 u_char* end; 00032 00033 inline void align(); 00034 inline u_char* align(u_char* p) const { return (u_char*) (((int) p + 3) & (~3)); } 00035 00036 public: 00037 // Constructor 00038 CodeIterator(methodOop method, int startBCI = 1); 00039 CodeIterator(u_char* hp); 00040 00041 // Advance to next instruction 00042 // Returns false if we passed the end. 00043 bool advance() { 00044 current = next_hp(); 00045 return current < end; 00046 } 00047 00048 // accessors 00049 u_char byte_at(int offset_from_instruction) { return current[offset_from_instruction]; } 00050 oop oop_at(int offset_from_instruction) { return *aligned_oop(offset_from_instruction); } 00051 int word_at(int offset_from_instruction) { return (int) *aligned_oop(offset_from_instruction); } 00052 00053 Bytecodes::Code code() const { return Bytecodes::Code(*current); } 00054 Bytecodes::CodeType code_type() const { return Bytecodes::code_type(code()); } 00055 Bytecodes::Format format() const { return Bytecodes::format(code()); } 00056 Bytecodes::SendType send() const { return Bytecodes::send_type(code()); } 00057 Bytecodes::ArgumentSpec argumentsType() const { return Bytecodes::argument_spec(code()); } 00058 bool pop_result() const { return Bytecodes::pop_tos(code()); } 00059 Bytecodes::LoopType loopType() const { return Bytecodes::loop_type(code()); } 00060 int bci() const; 00061 int next_bci() const; 00062 u_char* hp() const { return current; } 00063 u_char* next_hp() const; 00064 00065 // FOR DEOPTIMIZATION 00066 // Returns the interpreter return point for the current byte code. 00067 char* interpreter_return_point(bool restore_value = false) const; 00068 00069 void set_bci(int bci); 00070 00071 // returns the location of an aligned oop 00072 oop* aligned_oop(int offset_from_instruction) { 00073 return (oop*) align(current + offset_from_instruction); 00074 } 00075 00076 bool is_message_send() const { return Bytecodes::code_type(code()) == Bytecodes::message_send; } 00077 bool is_primitive_call() const { return Bytecodes::code_type(code()) == Bytecodes::primitive_call; } 00078 bool is_dll_call() const { return Bytecodes::code_type(code()) == Bytecodes::dll_call; } 00079 00080 // Returns the address of the block method if the current butecode is a push closure, NULL otherwise. 00081 oop* block_method_addr(); 00082 00083 // Returns the block method if the current butecode is a push closure, NULL otherwise. 00084 methodOop block_method(); 00085 00086 // Customization 00087 void customize_class_var_code(klassOop to_klass); 00088 void recustomize_class_var_code(klassOop from_klass, klassOop to_klass); 00089 void uncustomize_class_var_code(klassOop from_klass); 00090 00091 void customize_inst_var_code(klassOop to_klass); 00092 void recustomize_inst_var_code(klassOop from_klass, klassOop to_klass); 00093 void uncustomize_inst_var_code(klassOop from_klass); 00094 00095 // Returns the inline cache iff the current instruction is a send 00096 InterpretedIC* ic(); 00097 InterpretedPrim_Cache* prim_cache(); 00098 InterpretedDLL_Cache* dll_cache(); 00099 00100 // For byte code manipulation 00101 void set_code(u_char code) { *current = code; } 00102 };