duke@435: /* duke@435: * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * duke@435: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, duke@435: * CA 95054 USA or visit www.sun.com if you need additional information or duke@435: * have any questions. duke@435: * duke@435: */ duke@435: duke@435: //------------------------------OptoRuntime------------------------------------ duke@435: // Opto compiler runtime routines duke@435: // duke@435: // These are all generated from Ideal graphs. They are called with the duke@435: // Java calling convention. Internally they call C++. They are made once at duke@435: // startup time and Opto compiles calls to them later. duke@435: // Things are broken up into quads: the signature they will be called with, duke@435: // the address of the generated code, the corresponding C++ code and an duke@435: // nmethod. duke@435: duke@435: // The signature (returned by "xxx_Type()") is used at startup time by the duke@435: // Generator to make the generated code "xxx_Java". Opto compiles calls duke@435: // to the generated code "xxx_Java". When the compiled code gets executed, duke@435: // it calls the C++ code "xxx_C". The generated nmethod is saved in the duke@435: // CodeCache. Exception handlers use the nmethod to get the callee-save duke@435: // register OopMaps. duke@435: class CallInfo; duke@435: duke@435: // duke@435: // NamedCounters are tagged counters which can be used for profiling duke@435: // code in various ways. Currently they are used by the lock coarsening code duke@435: // duke@435: duke@435: class NamedCounter : public CHeapObj { duke@435: public: duke@435: enum CounterTag { duke@435: NoTag, duke@435: LockCounter, duke@435: EliminatedLockCounter, duke@435: BiasedLockingCounter duke@435: }; duke@435: duke@435: private: duke@435: const char * _name; duke@435: int _count; duke@435: CounterTag _tag; duke@435: NamedCounter* _next; duke@435: duke@435: public: duke@435: NamedCounter(const char *n, CounterTag tag = NoTag): duke@435: _name(n), duke@435: _count(0), duke@435: _next(NULL), duke@435: _tag(tag) {} duke@435: duke@435: const char * name() const { return _name; } duke@435: int count() const { return _count; } duke@435: address addr() { return (address)&_count; } duke@435: CounterTag tag() const { return _tag; } duke@435: void set_tag(CounterTag tag) { _tag = tag; } duke@435: duke@435: NamedCounter* next() const { return _next; } duke@435: void set_next(NamedCounter* next) { duke@435: assert(_next == NULL, "already set"); duke@435: _next = next; duke@435: } duke@435: duke@435: }; duke@435: duke@435: class BiasedLockingNamedCounter : public NamedCounter { duke@435: private: duke@435: BiasedLockingCounters _counters; duke@435: duke@435: public: duke@435: BiasedLockingNamedCounter(const char *n) : duke@435: NamedCounter(n, BiasedLockingCounter), _counters() {} duke@435: duke@435: BiasedLockingCounters* counters() { return &_counters; } duke@435: }; duke@435: duke@435: typedef const TypeFunc*(*TypeFunc_generator)(); duke@435: duke@435: class OptoRuntime : public AllStatic { duke@435: friend class Matcher; // allow access to stub names duke@435: duke@435: private: duke@435: // define stubs duke@435: static address generate_stub(ciEnv* ci_env, TypeFunc_generator gen, address C_function, const char *name, int is_fancy_jump, bool pass_tls, bool save_arguments, bool return_pc); duke@435: duke@435: // References to generated stubs duke@435: static address _new_instance_Java; duke@435: static address _new_array_Java; duke@435: static address _multianewarray2_Java; duke@435: static address _multianewarray3_Java; duke@435: static address _multianewarray4_Java; duke@435: static address _multianewarray5_Java; ysr@777: static address _g1_wb_pre_Java; ysr@777: static address _g1_wb_post_Java; duke@435: static address _vtable_must_compile_Java; duke@435: static address _complete_monitor_locking_Java; duke@435: static address _rethrow_Java; duke@435: duke@435: static address _slow_arraycopy_Java; duke@435: static address _register_finalizer_Java; duke@435: duke@435: # ifdef ENABLE_ZAP_DEAD_LOCALS duke@435: static address _zap_dead_Java_locals_Java; duke@435: static address _zap_dead_native_locals_Java; duke@435: # endif duke@435: duke@435: duke@435: // duke@435: // Implementation of runtime methods duke@435: // ================================= duke@435: duke@435: // Allocate storage for a Java instance. duke@435: static void new_instance_C(klassOopDesc* instance_klass, JavaThread *thread); duke@435: duke@435: // Allocate storage for a objArray or typeArray duke@435: static void new_array_C(klassOopDesc* array_klass, int len, JavaThread *thread); duke@435: duke@435: // Post-allocation step for implementing ReduceInitialCardMarks: duke@435: static void do_eager_card_mark(JavaThread* thread); duke@435: duke@435: // Allocate storage for a multi-dimensional arrays duke@435: // Note: needs to be fixed for arbitrary number of dimensions duke@435: static void multianewarray2_C(klassOopDesc* klass, int len1, int len2, JavaThread *thread); duke@435: static void multianewarray3_C(klassOopDesc* klass, int len1, int len2, int len3, JavaThread *thread); duke@435: static void multianewarray4_C(klassOopDesc* klass, int len1, int len2, int len3, int len4, JavaThread *thread); duke@435: static void multianewarray5_C(klassOopDesc* klass, int len1, int len2, int len3, int len4, int len5, JavaThread *thread); ysr@777: static void g1_wb_pre_C(oopDesc* orig, JavaThread* thread); ysr@777: static void g1_wb_post_C(void* card_addr, JavaThread* thread); duke@435: duke@435: public: duke@435: // Slow-path Locking and Unlocking duke@435: static void complete_monitor_locking_C(oopDesc* obj, BasicLock* lock, JavaThread* thread); duke@435: static void complete_monitor_unlocking_C(oopDesc* obj, BasicLock* lock); duke@435: duke@435: private: duke@435: duke@435: // Implicit exception support duke@435: static void throw_null_exception_C(JavaThread* thread); duke@435: duke@435: // Exception handling duke@435: static address handle_exception_C (JavaThread* thread); duke@435: static address handle_exception_C_helper(JavaThread* thread, nmethod*& nm); duke@435: static address rethrow_C (oopDesc* exception, JavaThread *thread, address return_pc ); duke@435: static void deoptimize_caller_frame (JavaThread *thread, bool doit); duke@435: duke@435: // CodeBlob support duke@435: // =================================================================== duke@435: duke@435: static ExceptionBlob* _exception_blob; duke@435: static void generate_exception_blob(); duke@435: duke@435: static void register_finalizer(oopDesc* obj, JavaThread* thread); duke@435: duke@435: // zaping dead locals, either from Java frames or from native frames duke@435: # ifdef ENABLE_ZAP_DEAD_LOCALS duke@435: static void zap_dead_Java_locals_C( JavaThread* thread); duke@435: static void zap_dead_native_locals_C( JavaThread* thread); duke@435: duke@435: static void zap_dead_java_or_native_locals( JavaThread*, bool (*)(frame*)); duke@435: duke@435: public: duke@435: static int ZapDeadCompiledLocals_count; duke@435: duke@435: # endif duke@435: duke@435: duke@435: public: duke@435: duke@435: static bool is_callee_saved_register(MachRegisterNumbers reg); duke@435: duke@435: // One time only generate runtime code stubs duke@435: static void generate(ciEnv* env); duke@435: duke@435: // Returns the name of a stub duke@435: static const char* stub_name(address entry); duke@435: duke@435: // access to runtime stubs entry points for java code duke@435: static address new_instance_Java() { return _new_instance_Java; } duke@435: static address new_array_Java() { return _new_array_Java; } duke@435: static address multianewarray2_Java() { return _multianewarray2_Java; } duke@435: static address multianewarray3_Java() { return _multianewarray3_Java; } duke@435: static address multianewarray4_Java() { return _multianewarray4_Java; } duke@435: static address multianewarray5_Java() { return _multianewarray5_Java; } ysr@777: static address g1_wb_pre_Java() { return _g1_wb_pre_Java; } ysr@777: static address g1_wb_post_Java() { return _g1_wb_post_Java; } duke@435: static address vtable_must_compile_stub() { return _vtable_must_compile_Java; } duke@435: static address complete_monitor_locking_Java() { return _complete_monitor_locking_Java; } duke@435: duke@435: static address slow_arraycopy_Java() { return _slow_arraycopy_Java; } duke@435: static address register_finalizer_Java() { return _register_finalizer_Java; } duke@435: duke@435: duke@435: # ifdef ENABLE_ZAP_DEAD_LOCALS duke@435: static address zap_dead_locals_stub(bool is_native) { return is_native duke@435: ? _zap_dead_native_locals_Java duke@435: : _zap_dead_Java_locals_Java; } duke@435: static MachNode* node_to_call_zap_dead_locals(Node* n, int block_num, bool is_native); duke@435: # endif duke@435: duke@435: static ExceptionBlob* exception_blob() { return _exception_blob; } duke@435: duke@435: // Leaf routines helping with method data update duke@435: static void profile_receiver_type_C(DataLayout* data, oopDesc* receiver); duke@435: duke@435: // Implicit exception support duke@435: static void throw_div0_exception_C (JavaThread* thread); duke@435: static void throw_stack_overflow_error_C(JavaThread* thread); duke@435: duke@435: // Exception handling duke@435: static address rethrow_stub() { return _rethrow_Java; } duke@435: duke@435: duke@435: // Type functions duke@435: // ====================================================== duke@435: duke@435: static const TypeFunc* new_instance_Type(); // object allocation (slow case) duke@435: static const TypeFunc* new_array_Type (); // [a]newarray (slow case) duke@435: static const TypeFunc* multianewarray_Type(int ndim); // multianewarray duke@435: static const TypeFunc* multianewarray2_Type(); // multianewarray duke@435: static const TypeFunc* multianewarray3_Type(); // multianewarray duke@435: static const TypeFunc* multianewarray4_Type(); // multianewarray duke@435: static const TypeFunc* multianewarray5_Type(); // multianewarray ysr@777: static const TypeFunc* g1_wb_pre_Type(); ysr@777: static const TypeFunc* g1_wb_post_Type(); duke@435: static const TypeFunc* complete_monitor_enter_Type(); duke@435: static const TypeFunc* complete_monitor_exit_Type(); duke@435: static const TypeFunc* uncommon_trap_Type(); duke@435: static const TypeFunc* athrow_Type(); duke@435: static const TypeFunc* rethrow_Type(); duke@435: static const TypeFunc* Math_D_D_Type(); // sin,cos & friends duke@435: static const TypeFunc* Math_DD_D_Type(); // mod,pow & friends duke@435: static const TypeFunc* modf_Type(); duke@435: static const TypeFunc* l2f_Type(); duke@435: static const TypeFunc* current_time_millis_Type(); duke@435: duke@435: static const TypeFunc* flush_windows_Type(); duke@435: duke@435: // arraycopy routine types duke@435: static const TypeFunc* fast_arraycopy_Type(); // bit-blasters duke@435: static const TypeFunc* checkcast_arraycopy_Type(); duke@435: static const TypeFunc* generic_arraycopy_Type(); duke@435: static const TypeFunc* slow_arraycopy_Type(); // the full routine duke@435: duke@435: // leaf on stack replacement interpreter accessor types duke@435: static const TypeFunc* osr_end_Type(); duke@435: duke@435: // leaf methodData routine types duke@435: static const TypeFunc* profile_receiver_type_Type(); duke@435: duke@435: // leaf on stack replacement interpreter accessor types duke@435: static const TypeFunc* fetch_int_Type(); duke@435: static const TypeFunc* fetch_long_Type(); duke@435: static const TypeFunc* fetch_float_Type(); duke@435: static const TypeFunc* fetch_double_Type(); duke@435: static const TypeFunc* fetch_oop_Type(); duke@435: static const TypeFunc* fetch_monitor_Type(); duke@435: duke@435: static const TypeFunc* register_finalizer_Type(); duke@435: duke@435: // Dtrace support duke@435: static const TypeFunc* dtrace_method_entry_exit_Type(); duke@435: static const TypeFunc* dtrace_object_alloc_Type(); duke@435: duke@435: # ifdef ENABLE_ZAP_DEAD_LOCALS duke@435: static const TypeFunc* zap_dead_locals_Type(); duke@435: # endif duke@435: duke@435: private: duke@435: static NamedCounter * volatile _named_counters; duke@435: duke@435: public: duke@435: // helper function which creates a named counter labeled with the duke@435: // if they are available duke@435: static NamedCounter* new_named_counter(JVMState* jvms, NamedCounter::CounterTag tag); duke@435: duke@435: // dumps all the named counters duke@435: static void print_named_counters(); duke@435: duke@435: };