00001 /* Copyright 1994, 1995 LongView Technologies L.L.C. $Revision: 1.13 $ */ 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 # include "incls/_precompiled.incl" 00025 # include "incls/_mixinOop.cpp.incl" 00026 00027 int mixinOopDesc::inst_var_offset(symbolOop name, int non_indexable_size) const { 00028 objArrayOop array = instVars(); 00029 int length = array->length(); 00030 for (int index = 1; index <= length; index++) { 00031 if (array->obj_at(index) == name) { 00032 return non_indexable_size - (length - index + 1); 00033 } 00034 } 00035 return -1; 00036 } 00037 00038 void mixinOopDesc::bootstrap_object(bootstrap* st) { 00039 memOopDesc::bootstrap_header(st); 00040 st->read_oop((oop*)&addr()->_methods); 00041 st->read_oop((oop*)&addr()->_inst_vars); 00042 st->read_oop((oop*)&addr()->_class_vars); 00043 st->read_oop((oop*)&addr()->_primary_invocation); 00044 st->read_oop((oop*)&addr()->_class_mixin); 00045 st->read_oop((oop*)&addr()->_installed); 00046 memOopDesc::bootstrap_body(st, header_size()); 00047 } 00048 00049 int mixinOopDesc::number_of_methods() const { 00050 return methods()->length(); 00051 } 00052 00053 methodOop mixinOopDesc::method_at(int index) const { 00054 return methodOop(methods()->obj_at(index)); 00055 } 00056 00057 void mixinOopDesc::add_method(methodOop method) { 00058 objArrayOop old_array = methods(); 00059 symbolOop selector = method->selector(); 00060 // Find out if a method with the same selector exists. 00061 for (int index = 1; index <= old_array->length(); index++) { 00062 assert(old_array->obj_at(index)->is_method(), "must be method"); 00063 methodOop m = methodOop(old_array->obj_at(index)); 00064 if (m->selector() == selector) { 00065 objArrayOop new_array = old_array->copy(); 00066 new_array->obj_at_put(index, method); 00067 set_methods(new_array); 00068 return; 00069 } 00070 } 00071 // Extend the array 00072 set_methods(old_array->copy_add(method)); 00073 } 00074 00075 methodOop mixinOopDesc::remove_method_at(int index) { 00076 methodOop method = method_at(index); 00077 set_methods(methods()->copy_remove(index)); 00078 return method; 00079 } 00080 00081 bool mixinOopDesc::includes_method(methodOop method) { 00082 objArrayOop array = methods(); 00083 for (int index = 1; index <= array->length(); index++) { 00084 methodOop m = methodOop(array->obj_at(index)); 00085 if (m == method) return true; 00086 } 00087 return false; 00088 } 00089 00090 int mixinOopDesc::number_of_instVars() const { 00091 return instVars()->length(); 00092 } 00093 00094 symbolOop mixinOopDesc::instVar_at(int index) const { 00095 return symbolOop(instVars()->obj_at(index)); 00096 } 00097 00098 void mixinOopDesc::add_instVar(symbolOop name) { 00099 objArrayOop old_array = instVars(); 00100 // Find out if it already exists. 00101 for (int index = 1; index <= old_array->length(); index ++) { 00102 assert(old_array->obj_at(index)->is_symbol(), "must be symbol"); 00103 if (old_array->obj_at(index) == name) return; 00104 } 00105 // Extend the array 00106 set_instVars(old_array->copy_add(name)); 00107 } 00108 00109 symbolOop mixinOopDesc::remove_instVar_at(int index) { 00110 symbolOop name = instVar_at(index); 00111 set_instVars(instVars()->copy_remove(index, 1)); 00112 return name; 00113 } 00114 00115 bool mixinOopDesc::includes_instVar(symbolOop name) { 00116 objArrayOop array = instVars(); 00117 for (int index = 1; index <= array->length(); index++) { 00118 symbolOop elem = symbolOop(array->obj_at(index)); 00119 if (elem == name) return true; 00120 } 00121 return false; 00122 } 00123 00124 int mixinOopDesc::number_of_classVars() const { 00125 return classVars()->length(); 00126 } 00127 00128 symbolOop mixinOopDesc::classVar_at(int index) const { 00129 return symbolOop(classVars()->obj_at(index)); 00130 } 00131 00132 void mixinOopDesc::add_classVar(symbolOop name) { 00133 objArrayOop old_array = classVars(); 00134 // Find out if it already exists. 00135 for (int index = 1; index <= old_array->length(); index++) { 00136 symbolOop elem = symbolOop(old_array->obj_at(index)); 00137 if (elem == name) return; 00138 } 00139 // Extend the array 00140 set_classVars(old_array->copy_add(name)); 00141 } 00142 00143 symbolOop mixinOopDesc::remove_classVar_at(int index) { 00144 symbolOop name = classVar_at(index); 00145 set_classVars(classVars()->copy_remove(index)); 00146 return name; 00147 } 00148 00149 00150 bool mixinOopDesc::includes_classVar(symbolOop name) { 00151 objArrayOop array = classVars(); 00152 for (int index = 1; index <= array->length(); index++) { 00153 symbolOop elem = symbolOop(array->obj_at(index)); 00154 if (elem == name) return true; 00155 } 00156 return false; 00157 } 00158 00159 bool mixinOopDesc::is_installed() const { 00160 if (installed() == trueObj) return true; 00161 assert(installed() == falseObj, "verify installed"); 00162 return false; 00163 } 00164 00165 bool mixinOopDesc::has_primary_invocation() const { 00166 return primary_invocation()->is_klass(); 00167 } 00168 00169 void mixinOopDesc::apply_mixin(mixinOop m) { 00170 set_methods(m->methods()); 00171 } 00172 00173 void mixinOopDesc::customize_for(klassOop klass) { 00174 objArrayOop array = methods(); 00175 for (int index = 1; index <= array->length(); index++) { 00176 methodOop m = methodOop(array->obj_at(index)); 00177 m->customize_for(klass, this); 00178 } 00179 } 00180 00181 void mixinOopDesc::uncustomize_methods() { 00182 objArrayOop array = methods(); 00183 for (int index = 1; index <= array->length(); index++) { 00184 methodOop m = methodOop(array->obj_at(index)); 00185 m->uncustomize_for(this); 00186 } 00187 }