00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 # include "incls/_precompiled.incl"
00025 # include "incls/_prim.cpp.incl"
00026
00027
00028
00029
00030
00031 #include "prims.inc"
00032
00033
00034
00035
00036 typedef oop (*prim_fntype0)();
00037 typedef oop (*prim_fntype1)(oop);
00038 typedef oop (*prim_fntype2)(oop, oop);
00039 typedef oop (*prim_fntype3)(oop, oop, oop);
00040 typedef oop (*prim_fntype4)(oop, oop, oop, oop);
00041 typedef oop (*prim_fntype5)(oop, oop, oop, oop, oop);
00042 typedef oop (*prim_fntype6)(oop, oop, oop, oop, oop, oop);
00043 typedef oop (*prim_fntype7)(oop, oop, oop, oop, oop, oop, oop);
00044 typedef oop (*prim_fntype8)(oop, oop, oop, oop, oop, oop, oop, oop);
00045 typedef oop (*prim_fntype9)(oop, oop, oop, oop, oop, oop, oop, oop, oop);
00046
00047
00048 oop primitive_desc::eval(oop* a) {
00049 const bool reverseArgs = true;
00050 oop res;
00051 if (reverseArgs) {
00052 switch (number_of_parameters()) {
00053 case 0: res = ((prim_fntype0)_fn)(); break;
00054 case 1: res = ((prim_fntype1)_fn)(a[0]); break;
00055 case 2: res = ((prim_fntype2)_fn)(a[1], a[0]); break;
00056 case 3: res = ((prim_fntype3)_fn)(a[2], a[1], a[0]); break;
00057 case 4: res = ((prim_fntype4)_fn)(a[3], a[2], a[1], a[0]); break;
00058 case 5: res = ((prim_fntype5)_fn)(a[4], a[3], a[2], a[1], a[0]); break;
00059 case 6: res = ((prim_fntype6)_fn)(a[5], a[4], a[3], a[2], a[1], a[0]); break;
00060 case 7: res = ((prim_fntype7)_fn)(a[6], a[5], a[4], a[3], a[2], a[1], a[0]); break;
00061 case 8: res = ((prim_fntype8)_fn)(a[7], a[6], a[5], a[4], a[3], a[2], a[1], a[0]); break;
00062 case 9: res = ((prim_fntype9)_fn)(a[8], a[7], a[6], a[5], a[4], a[3], a[2], a[1], a[0]); break;
00063 default: ShouldNotReachHere();
00064 }
00065 } else {
00066 switch (number_of_parameters()) {
00067 case 0: res = ((prim_fntype0)_fn)(); break;
00068 case 1: res = ((prim_fntype1)_fn)(a[0]); break;
00069 case 2: res = ((prim_fntype2)_fn)(a[0], a[1]); break;
00070 case 3: res = ((prim_fntype3)_fn)(a[0], a[1], a[2]); break;
00071 case 4: res = ((prim_fntype4)_fn)(a[0], a[1], a[2], a[3]); break;
00072 case 5: res = ((prim_fntype5)_fn)(a[0], a[1], a[2], a[3], a[4]); break;
00073 case 6: res = ((prim_fntype6)_fn)(a[0], a[1], a[2], a[3], a[4], a[5]); break;
00074 case 7: res = ((prim_fntype7)_fn)(a[0], a[1], a[2], a[3], a[4], a[5], a[6]); break;
00075 case 8: res = ((prim_fntype8)_fn)(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]); break;
00076 case 9: res = ((prim_fntype9)_fn)(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]); break;
00077 default: ShouldNotReachHere();
00078 }
00079 }
00080 return res;
00081 }
00082
00083
00084 void primitives::print_table() {
00085 std->print_cr("Primitive table:");
00086 for (int index = 0; index < size_of_primitive_table; index++) {
00087 primitive_desc* e = primitive_table[index];
00088 std->print("%3d ",index);
00089 e->print();
00090 }
00091 std->print_cr(" - format: <index> <name> <number_of_parameters> <flags> [category]");
00092 std->print_cr(" flags: R = has receiver, F = has failure block,");
00093 std->print_cr(" S = can scavenge, N = can perform NLR,");
00094 std->print_cr(" C = can be constant folded, D = can invoke Delta code");
00095 std->print_cr(" I = internal, P = needs Delta fp code");
00096 std->print_cr(" W = can walk stack (computed)");
00097 }
00098
00099
00100 bool primitive_desc::can_walk_stack() const {
00101 return can_scavenge() || can_invoke_delta() || can_perform_NLR();
00102 }
00103
00104
00105 symbolOop primitive_desc::selector() const {
00106 return oopFactory::new_symbol(name());
00107 }
00108
00109
00110 void primitive_desc::print() {
00111 std->print("%48s %d %s%s%s%s%s%s%s%s%s",
00112 name(),
00113 number_of_parameters(),
00114 has_receiver() ? "R" : "_",
00115 can_fail() ? "F" : "_",
00116 can_scavenge() ? "S" : "_",
00117 can_walk_stack() ? "W" : "_",
00118 can_perform_NLR() ? "N" : "_",
00119 can_be_constant_folded() ? "C" : "_",
00120 can_invoke_delta() ? "D" : "_",
00121 is_internal() ? "I" : "_",
00122 needs_delta_fp_code() ? "P" : "_");
00123 switch(group()) {
00124 case IntComparisonPrimitive: std->print(", smi compare"); break;
00125 case IntArithmeticPrimitive: std->print(", smi arith"); break;
00126 case FloatComparisonPrimitive: std->print(", double compare"); break;
00127 case FloatArithmeticPrimitive: std->print(", double arith"); break;
00128 case ByteArrayPrimitive: std->print(", byte array op."); break;
00129 case DoubleByteArrayPrimitive: std->print(", double-byte array op."); break;
00130 case ObjArrayPrimitive: std->print(", array op."); break;
00131 case BlockPrimitive: std->print(", block/context"); break;
00132 case NormalPrimitive: break;
00133 default: fatal("Unknown primitive group");
00134 }
00135 std->cr();
00136 }
00137
00138
00139 char* primitive_desc::parameter_type(int index) const {
00140 assert((0 <= index) && (index < number_of_parameters()), "illegal parameter index");
00141 return _types[1 + index];
00142 }
00143
00144
00145 char* primitive_desc::return_type() const {
00146 return _types[0];
00147 }
00148
00149
00150 Expr* primitive_desc::convertToKlass(char* type, PReg* p, Node* n) const {
00151 if (0 == strcmp(type, "SmallInteger")) return new KlassExpr(Universe::smiKlassObj(), p, n);
00152 if (0 == strcmp(type, "Double")) return new KlassExpr(Universe::doubleKlassObj(), p, n);
00153 if (0 == strcmp(type, "Float")) return new KlassExpr(Universe::doubleKlassObj(), p, n);
00154 if (0 == strcmp(type, "Symbol")) return new KlassExpr(Universe::symbolKlassObj(), p, n);
00155 if (0 == strcmp(type, "Boolean")) {
00156
00157 Expr* t = new ConstantExpr(Universe::trueObj(), p, NULL);
00158 Expr* f = new ConstantExpr(Universe::falseObj(), p, NULL);
00159 return new MergeExpr(t, f, p, NULL);
00160 }
00161
00162
00163
00164
00165
00166 return NULL;
00167 }
00168
00169
00170 Expr* primitive_desc::parameter_klass(int index, PReg* p, Node* n) const {
00171 return convertToKlass(parameter_type(index), p, n);
00172 }
00173
00174
00175 Expr* primitive_desc::return_klass(PReg* p, Node* n) const {
00176 return convertToKlass(return_type(), p, n);
00177 }
00178
00179
00180 void primitive_desc::error(char* msg) {
00181 print();
00182 ::error(msg);
00183 }
00184
00185 void primitive_desc::verify() {
00186 bool ok = true;
00187 if (can_invoke_delta()) {
00188 if (!can_scavenge()) error("canInvokeDelta implies canScavenge");
00189 if (!can_walk_stack()) error("canInvokeDelta implies can_walk_stack");
00190 if (can_be_constant_folded()) error("canInvokeDelta implies !canbeConstantFolded");
00191 if (!can_perform_NLR()) error("canInvokeDelta implies canPerformNLR");
00192 }
00193 if (can_be_constant_folded()) {
00194 if (can_perform_NLR()) error("canbeConstantFolded implies !canPerformNLR");
00195 }
00196 if (group() == BlockPrimitive) {
00197 if (!can_walk_stack()) error("blocks must have can_walk_stack");
00198 }
00199 }
00200
00201 int primitive_desc::compare(char* str, int len) {
00202 int src_len = strlen(name());
00203 int sign = strncmp(name(), str, min(src_len, len));
00204 if (sign != 0 || src_len == len) return sign;
00205 return src_len < len ? -1 : 1;
00206 }
00207
00208 primitive_desc* primitives::lookup(char* s, int len) {
00209 int first = 0;
00210 int last = size_of_primitive_table;
00211
00212 primitive_desc* element;
00213 do {
00214 int middle = first + (last - first)/2;
00215 element = primitive_table[middle];
00216 int sign = element->compare(s, len);
00217 if (sign == -1) first = middle + 1;
00218 else if (sign == 1) last = middle - 1;
00219 else return element;
00220 } while (first < last);
00221
00222 assert(first == last, "check for one element");
00223 element = primitive_table[first];
00224
00225 return element->compare(s, len) == 0 ? element : NULL;
00226 }
00227
00228
00229 primitive_desc* primitives::lookup(fntype fn) {
00230 for (int index = 0; index < size_of_primitive_table; index++) {
00231 primitive_desc* e = primitive_table[index];
00232 if (e->fn() == fn) return e;
00233 }
00234 return NULL;
00235 }
00236
00237
00238 void primitives::lookup_and_patch() {
00239
00240 frame f = DeltaProcess::active()->last_frame();
00241 CodeIterator it(f.hp());
00242 oop* selector_addr = it.aligned_oop(1);
00243
00244 symbolOop sel = symbolOop(*selector_addr);
00245 assert(sel->is_symbol(), "symbol expected");
00246
00247 primitive_desc* pdesc = primitives::lookup(sel);
00248 if (pdesc != NULL && !pdesc->is_internal()) {
00249
00250 *f.hp() = u_char(Bytecodes::primitive_call_code_for(Bytecodes::Code(*f.hp())));
00251 *selector_addr = oop(pdesc->fn());
00252 } else {
00253
00254 it.advance();
00255 f.set_hp(it.hp());
00256
00257 { ResourceMark rm;
00258
00259 std->print("primitive lookup error\n");
00260 sel->print_value(); std->print(" not found\n");
00261 }
00262 if (DeltaProcess::active()->is_scheduler()) {
00263 ResourceMark rm;
00264 DeltaProcess::active()->trace_stack();
00265 fatal("primitive lookup error in scheduler");
00266 } else {
00267 DeltaProcess::active()->suspend(primitive_lookup_error);
00268 }
00269 ShouldNotReachHere();
00270 }
00271 }
00272
00273
00274 void prim_init() {
00275 primitives::initialize();
00276 primitive_desc* prev = NULL;
00277 for (int index = 0; index < size_of_primitive_table; index++) {
00278 primitive_desc* e = primitive_table[index];
00279 e->verify();
00280 if (prev) {
00281 guarantee(strcmp(prev->name(), e->name()) == -1, "primitive table not sorted");
00282 }
00283 }
00284 primitives::clear_counters();
00285 }
00286
00287
00288 void primitives::clear_counters() {
00289 behaviorPrimitives::number_of_calls = 0;
00290 byteArrayPrimitives::number_of_calls = 0;
00291 callBackPrimitives::number_of_calls = 0;
00292 doubleByteArrayPrimitives::number_of_calls = 0;
00293 debugPrimitives::number_of_calls = 0;
00294 doubleOopPrimitives::number_of_calls = 0;
00295 methodOopPrimitives::number_of_calls = 0;
00296 mixinOopPrimitives::number_of_calls = 0;
00297 objArrayPrimitives::number_of_calls = 0;
00298 oopPrimitives::number_of_calls = 0;
00299 processOopPrimitives::number_of_calls = 0;
00300 proxyOopPrimitives::number_of_calls = 0;
00301 smiOopPrimitives::number_of_calls = 0;
00302 systemPrimitives::number_of_calls = 0;
00303 }
00304
00305
00306 static void print_calls(char* name, int inc, int* total) {
00307 if (inc > 0) {
00308 lprintf(" %s:\t%6d\n", name, inc);
00309 *total = *total + inc;
00310 }
00311 }
00312
00313
00314 void primitives::print_counters() {
00315 int total = 0;
00316 lprintf("Primitive call counters:\n");
00317 print_calls("Behavoir", behaviorPrimitives::number_of_calls, &total);
00318 print_calls("byteArray", byteArrayPrimitives::number_of_calls, &total);
00319 print_calls("callBack", callBackPrimitives::number_of_calls, &total);
00320 print_calls("doubelByteArray", doubleByteArrayPrimitives::number_of_calls, &total);
00321 print_calls("debug", debugPrimitives::number_of_calls, &total);
00322 print_calls("double", doubleOopPrimitives::number_of_calls, &total);
00323 print_calls("method", methodOopPrimitives::number_of_calls, &total);
00324 print_calls("mixin", mixinOopPrimitives::number_of_calls, &total);
00325 print_calls("objArray", objArrayPrimitives::number_of_calls, &total);
00326 print_calls("oop", oopPrimitives::number_of_calls, &total);
00327 print_calls("process", processOopPrimitives::number_of_calls, &total);
00328 print_calls("proxy", proxyOopPrimitives::number_of_calls, &total);
00329 print_calls("smi", smiOopPrimitives::number_of_calls, &total);
00330 print_calls("system", systemPrimitives::number_of_calls, &total);
00331 lprintf("Total:\t%6d\n", total);
00332
00333 }
00334
00335 primitive_desc* InterpretedPrim_Cache::pdesc() const {
00336 CodeIterator c(hp());
00337 switch (c.code()) {
00338 case Bytecodes::prim_call:
00339 case Bytecodes::prim_call_failure:
00340 case Bytecodes::prim_call_self:
00341 case Bytecodes::prim_call_self_failure:
00342 return primitives::lookup((fntype) c.word_at(1));
00343
00344 case Bytecodes::prim_call_lookup:
00345 case Bytecodes::prim_call_failure_lookup:
00346 case Bytecodes::prim_call_self_lookup:
00347 case Bytecodes::prim_call_self_failure_lookup:
00348 return primitives::lookup(symbolOop(c.oop_at(1)));
00349
00350 default: fatal("Wrong bytecode");
00351 }
00352 return NULL;
00353 }
00354
00355 bool InterpretedPrim_Cache::has_receiver() const {
00356 CodeIterator c(hp());
00357 switch (c.code()) {
00358 case Bytecodes::prim_call_self:
00359 case Bytecodes::prim_call_self_failure:
00360 case Bytecodes::prim_call_self_lookup:
00361 case Bytecodes::prim_call_self_failure_lookup:
00362 return true;
00363
00364 case Bytecodes::prim_call:
00365 case Bytecodes::prim_call_failure:
00366 case Bytecodes::prim_call_lookup:
00367 case Bytecodes::prim_call_failure_lookup:
00368 return false;
00369
00370 default: fatal("Wrong bytecode");
00371 }
00372 return false;
00373 }
00374
00375 symbolOop InterpretedPrim_Cache::name() const {
00376 CodeIterator c(hp());
00377 switch (c.code()) {
00378 case Bytecodes::prim_call:
00379 case Bytecodes::prim_call_failure:
00380 case Bytecodes::prim_call_self:
00381 case Bytecodes::prim_call_self_failure:
00382 return primitives::lookup((fntype) c.word_at(1))->selector();
00383
00384 case Bytecodes::prim_call_lookup:
00385 case Bytecodes::prim_call_failure_lookup:
00386 case Bytecodes::prim_call_self_lookup:
00387 case Bytecodes::prim_call_self_failure_lookup:
00388 return symbolOop(c.oop_at(1));
00389
00390 default: fatal("Wrong bytecode");
00391 }
00392 return NULL;
00393 }
00394
00395 int InterpretedPrim_Cache::number_of_parameters() const {
00396 int result = name()->number_of_arguments()
00397 + (has_receiver() ? 1 : 0)
00398 - (has_failure_code() ? 1 : 0);
00399 assert(pdesc() == NULL || pdesc()->number_of_parameters() == result, "checking result");
00400 return result;
00401 }
00402
00403 bool InterpretedPrim_Cache::has_failure_code() const {
00404 CodeIterator c(hp());
00405 switch (c.code()) {
00406 case Bytecodes::prim_call_failure:
00407 case Bytecodes::prim_call_failure_lookup:
00408 case Bytecodes::prim_call_self_failure:
00409 case Bytecodes::prim_call_self_failure_lookup:
00410 return true;
00411
00412 case Bytecodes::prim_call:
00413 case Bytecodes::prim_call_lookup:
00414 case Bytecodes::prim_call_self_lookup:
00415 case Bytecodes::prim_call_self:
00416 return false;
00417
00418 default: fatal("Wrong bytecode");
00419 }
00420 return false;
00421 }
00422
00423 primitive_desc* primitives::_new0;
00424 primitive_desc* primitives::_new1;
00425 primitive_desc* primitives::_new2;
00426 primitive_desc* primitives::_new3;
00427 primitive_desc* primitives::_new4;
00428 primitive_desc* primitives::_new5;
00429 primitive_desc* primitives::_new6;
00430 primitive_desc* primitives::_new7;
00431 primitive_desc* primitives::_new8;
00432 primitive_desc* primitives::_new9;
00433 primitive_desc* primitives::_equal;
00434 primitive_desc* primitives::_not_equal;
00435 primitive_desc* primitives::_block_allocate;
00436 primitive_desc* primitives::_block_allocate0;
00437 primitive_desc* primitives::_block_allocate1;
00438 primitive_desc* primitives::_block_allocate2;
00439 primitive_desc* primitives::_context_allocate;
00440 primitive_desc* primitives::_context_allocate0;
00441 primitive_desc* primitives::_context_allocate1;
00442 primitive_desc* primitives::_context_allocate2;
00443
00444 primitive_desc* primitives::verified_lookup(char* selector) {
00445 primitive_desc* result = lookup(selector);
00446 if (result == NULL) {
00447 err->print_cr("Verified primitive lookup failed");
00448 err->print_cr(" selector = %s", selector);
00449 fatal("aborted");
00450 }
00451 return result;
00452 }
00453
00454 void primitives::initialize() {
00455 _new0 = verified_lookup("primitiveNew0");
00456 _new1 = verified_lookup("primitiveNew1");
00457 _new2 = verified_lookup("primitiveNew2");
00458 _new3 = verified_lookup("primitiveNew3");
00459 _new4 = verified_lookup("primitiveNew4");
00460 _new5 = verified_lookup("primitiveNew5");
00461 _new6 = verified_lookup("primitiveNew6");
00462 _new7 = verified_lookup("primitiveNew7");
00463 _new8 = verified_lookup("primitiveNew8");
00464 _new9 = verified_lookup("primitiveNew9");
00465
00466 _equal = verified_lookup("primitiveEqual:");
00467 _not_equal = verified_lookup("primitiveNotEqual:");
00468
00469 _block_allocate = verified_lookup("primitiveCompiledBlockAllocate:");
00470 _block_allocate0 = verified_lookup("primitiveCompiledBlockAllocate0");
00471 _block_allocate1 = verified_lookup("primitiveCompiledBlockAllocate1");
00472 _block_allocate2 = verified_lookup("primitiveCompiledBlockAllocate2");
00473 _context_allocate = verified_lookup("primitiveCompiledContextAllocate:");
00474 _context_allocate0 = verified_lookup("primitiveCompiledContextAllocate0");
00475 _context_allocate1 = verified_lookup("primitiveCompiledContextAllocate1");
00476 _context_allocate2 = verified_lookup("primitiveCompiledContextAllocate2");
00477 }