89
90
91 // For debugging purposes:
92 // To force FullGCALot inside a runtime function, add the following two lines
93 //
94 // Universe::release_fullgc_alot_dummy();
95 // MarkSweep::invoke(0, "Debugging");
96 //
97 // At command line specify the parameters: -XX:+FullGCALot -XX:FullGCALotStart=100000000
98
99
100
101
102 // Compiled code entry points
103 address OptoRuntime::_new_instance_Java = NULL;
104 address OptoRuntime::_new_array_Java = NULL;
105 address OptoRuntime::_multianewarray2_Java = NULL;
106 address OptoRuntime::_multianewarray3_Java = NULL;
107 address OptoRuntime::_multianewarray4_Java = NULL;
108 address OptoRuntime::_multianewarray5_Java = NULL;
109 address OptoRuntime::_g1_wb_pre_Java = NULL;
110 address OptoRuntime::_g1_wb_post_Java = NULL;
111 address OptoRuntime::_vtable_must_compile_Java = NULL;
112 address OptoRuntime::_complete_monitor_locking_Java = NULL;
113 address OptoRuntime::_rethrow_Java = NULL;
114
115 address OptoRuntime::_slow_arraycopy_Java = NULL;
116 address OptoRuntime::_register_finalizer_Java = NULL;
117
118 # ifdef ENABLE_ZAP_DEAD_LOCALS
119 address OptoRuntime::_zap_dead_Java_locals_Java = NULL;
120 address OptoRuntime::_zap_dead_native_locals_Java = NULL;
121 # endif
122
123 ExceptionBlob* OptoRuntime::_exception_blob;
124
125 // This should be called in an assertion at the start of OptoRuntime routines
126 // which are entered from compiled code (all of them)
127 #ifndef PRODUCT
128 static bool check_compiled_frame(JavaThread* thread) {
137 #endif
138
139
140 #define gen(env, var, type_func_gen, c_func, fancy_jump, pass_tls, save_arg_regs, return_pc) \
141 var = generate_stub(env, type_func_gen, CAST_FROM_FN_PTR(address, c_func), #var, fancy_jump, pass_tls, save_arg_regs, return_pc)
142
143 void OptoRuntime::generate(ciEnv* env) {
144
145 generate_exception_blob();
146
147 // Note: tls: Means fetching the return oop out of the thread-local storage
148 //
149 // variable/name type-function-gen , runtime method ,fncy_jp, tls,save_args,retpc
150 // -------------------------------------------------------------------------------------------------------------------------------
151 gen(env, _new_instance_Java , new_instance_Type , new_instance_C , 0 , true , false, false);
152 gen(env, _new_array_Java , new_array_Type , new_array_C , 0 , true , false, false);
153 gen(env, _multianewarray2_Java , multianewarray2_Type , multianewarray2_C , 0 , true , false, false);
154 gen(env, _multianewarray3_Java , multianewarray3_Type , multianewarray3_C , 0 , true , false, false);
155 gen(env, _multianewarray4_Java , multianewarray4_Type , multianewarray4_C , 0 , true , false, false);
156 gen(env, _multianewarray5_Java , multianewarray5_Type , multianewarray5_C , 0 , true , false, false);
157 gen(env, _g1_wb_pre_Java , g1_wb_pre_Type , SharedRuntime::g1_wb_pre , 0 , false, false, false);
158 gen(env, _g1_wb_post_Java , g1_wb_post_Type , SharedRuntime::g1_wb_post , 0 , false, false, false);
159 gen(env, _complete_monitor_locking_Java , complete_monitor_enter_Type , SharedRuntime::complete_monitor_locking_C , 0 , false, false, false);
160 gen(env, _rethrow_Java , rethrow_Type , rethrow_C , 2 , true , false, true );
161
162 gen(env, _slow_arraycopy_Java , slow_arraycopy_Type , SharedRuntime::slow_arraycopy_C , 0 , false, false, false);
163 gen(env, _register_finalizer_Java , register_finalizer_Type , register_finalizer , 0 , false, false, false);
164
165 # ifdef ENABLE_ZAP_DEAD_LOCALS
166 gen(env, _zap_dead_Java_locals_Java , zap_dead_locals_Type , zap_dead_Java_locals_C , 0 , false, true , false );
167 gen(env, _zap_dead_native_locals_Java , zap_dead_locals_Type , zap_dead_native_locals_C , 0 , false, true , false );
168 # endif
169
170 }
171
172 #undef gen
173
174
175 // Helper method to do generation of RunTimeStub's
176 address OptoRuntime::generate_stub( ciEnv* env,
357 JRT_END
358
359 // multianewarray for 5 dimensions
360 JRT_ENTRY(void, OptoRuntime::multianewarray5_C(klassOopDesc* elem_type, int len1, int len2, int len3, int len4, int len5, JavaThread *thread))
361 #ifndef PRODUCT
362 SharedRuntime::_multi5_ctr++; // multianewarray for 1 dimension
363 #endif
364 assert(check_compiled_frame(thread), "incorrect caller");
365 assert(oop(elem_type)->is_klass(), "not a class");
366 jint dims[5];
367 dims[0] = len1;
368 dims[1] = len2;
369 dims[2] = len3;
370 dims[3] = len4;
371 dims[4] = len5;
372 oop obj = arrayKlass::cast(elem_type)->multi_allocate(5, dims, THREAD);
373 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION);
374 thread->set_vm_result(obj);
375 JRT_END
376
377 const TypeFunc *OptoRuntime::new_instance_Type() {
378 // create input type (domain)
379 const Type **fields = TypeTuple::fields(1);
380 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated
381 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
382
383 // create result type (range)
384 fields = TypeTuple::fields(1);
385 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
386
387 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
388
389 return TypeFunc::make(domain, range);
390 }
391
392
393 const TypeFunc *OptoRuntime::athrow_Type() {
394 // create input type (domain)
395 const Type **fields = TypeTuple::fields(1);
396 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated
437
438 return TypeFunc::make(domain, range);
439 }
440
441 const TypeFunc *OptoRuntime::multianewarray2_Type() {
442 return multianewarray_Type(2);
443 }
444
445 const TypeFunc *OptoRuntime::multianewarray3_Type() {
446 return multianewarray_Type(3);
447 }
448
449 const TypeFunc *OptoRuntime::multianewarray4_Type() {
450 return multianewarray_Type(4);
451 }
452
453 const TypeFunc *OptoRuntime::multianewarray5_Type() {
454 return multianewarray_Type(5);
455 }
456
457 const TypeFunc *OptoRuntime::g1_wb_pre_Type() {
458 const Type **fields = TypeTuple::fields(2);
459 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value
460 fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL; // thread
461 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
462
463 // create result type (range)
464 fields = TypeTuple::fields(0);
465 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
466
467 return TypeFunc::make(domain, range);
468 }
469
470 const TypeFunc *OptoRuntime::g1_wb_post_Type() {
471
472 const Type **fields = TypeTuple::fields(2);
473 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Card addr
474 fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL; // thread
475 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
476
|
89
90
91 // For debugging purposes:
92 // To force FullGCALot inside a runtime function, add the following two lines
93 //
94 // Universe::release_fullgc_alot_dummy();
95 // MarkSweep::invoke(0, "Debugging");
96 //
97 // At command line specify the parameters: -XX:+FullGCALot -XX:FullGCALotStart=100000000
98
99
100
101
102 // Compiled code entry points
103 address OptoRuntime::_new_instance_Java = NULL;
104 address OptoRuntime::_new_array_Java = NULL;
105 address OptoRuntime::_multianewarray2_Java = NULL;
106 address OptoRuntime::_multianewarray3_Java = NULL;
107 address OptoRuntime::_multianewarray4_Java = NULL;
108 address OptoRuntime::_multianewarray5_Java = NULL;
109 address OptoRuntime::_multianewarrayN_Java = NULL;
110 address OptoRuntime::_g1_wb_pre_Java = NULL;
111 address OptoRuntime::_g1_wb_post_Java = NULL;
112 address OptoRuntime::_vtable_must_compile_Java = NULL;
113 address OptoRuntime::_complete_monitor_locking_Java = NULL;
114 address OptoRuntime::_rethrow_Java = NULL;
115
116 address OptoRuntime::_slow_arraycopy_Java = NULL;
117 address OptoRuntime::_register_finalizer_Java = NULL;
118
119 # ifdef ENABLE_ZAP_DEAD_LOCALS
120 address OptoRuntime::_zap_dead_Java_locals_Java = NULL;
121 address OptoRuntime::_zap_dead_native_locals_Java = NULL;
122 # endif
123
124 ExceptionBlob* OptoRuntime::_exception_blob;
125
126 // This should be called in an assertion at the start of OptoRuntime routines
127 // which are entered from compiled code (all of them)
128 #ifndef PRODUCT
129 static bool check_compiled_frame(JavaThread* thread) {
138 #endif
139
140
141 #define gen(env, var, type_func_gen, c_func, fancy_jump, pass_tls, save_arg_regs, return_pc) \
142 var = generate_stub(env, type_func_gen, CAST_FROM_FN_PTR(address, c_func), #var, fancy_jump, pass_tls, save_arg_regs, return_pc)
143
144 void OptoRuntime::generate(ciEnv* env) {
145
146 generate_exception_blob();
147
148 // Note: tls: Means fetching the return oop out of the thread-local storage
149 //
150 // variable/name type-function-gen , runtime method ,fncy_jp, tls,save_args,retpc
151 // -------------------------------------------------------------------------------------------------------------------------------
152 gen(env, _new_instance_Java , new_instance_Type , new_instance_C , 0 , true , false, false);
153 gen(env, _new_array_Java , new_array_Type , new_array_C , 0 , true , false, false);
154 gen(env, _multianewarray2_Java , multianewarray2_Type , multianewarray2_C , 0 , true , false, false);
155 gen(env, _multianewarray3_Java , multianewarray3_Type , multianewarray3_C , 0 , true , false, false);
156 gen(env, _multianewarray4_Java , multianewarray4_Type , multianewarray4_C , 0 , true , false, false);
157 gen(env, _multianewarray5_Java , multianewarray5_Type , multianewarray5_C , 0 , true , false, false);
158 gen(env, _multianewarrayN_Java , multianewarrayN_Type , multianewarrayN_C , 0 , true , false, false);
159 gen(env, _g1_wb_pre_Java , g1_wb_pre_Type , SharedRuntime::g1_wb_pre , 0 , false, false, false);
160 gen(env, _g1_wb_post_Java , g1_wb_post_Type , SharedRuntime::g1_wb_post , 0 , false, false, false);
161 gen(env, _complete_monitor_locking_Java , complete_monitor_enter_Type , SharedRuntime::complete_monitor_locking_C , 0 , false, false, false);
162 gen(env, _rethrow_Java , rethrow_Type , rethrow_C , 2 , true , false, true );
163
164 gen(env, _slow_arraycopy_Java , slow_arraycopy_Type , SharedRuntime::slow_arraycopy_C , 0 , false, false, false);
165 gen(env, _register_finalizer_Java , register_finalizer_Type , register_finalizer , 0 , false, false, false);
166
167 # ifdef ENABLE_ZAP_DEAD_LOCALS
168 gen(env, _zap_dead_Java_locals_Java , zap_dead_locals_Type , zap_dead_Java_locals_C , 0 , false, true , false );
169 gen(env, _zap_dead_native_locals_Java , zap_dead_locals_Type , zap_dead_native_locals_C , 0 , false, true , false );
170 # endif
171
172 }
173
174 #undef gen
175
176
177 // Helper method to do generation of RunTimeStub's
178 address OptoRuntime::generate_stub( ciEnv* env,
359 JRT_END
360
361 // multianewarray for 5 dimensions
362 JRT_ENTRY(void, OptoRuntime::multianewarray5_C(klassOopDesc* elem_type, int len1, int len2, int len3, int len4, int len5, JavaThread *thread))
363 #ifndef PRODUCT
364 SharedRuntime::_multi5_ctr++; // multianewarray for 1 dimension
365 #endif
366 assert(check_compiled_frame(thread), "incorrect caller");
367 assert(oop(elem_type)->is_klass(), "not a class");
368 jint dims[5];
369 dims[0] = len1;
370 dims[1] = len2;
371 dims[2] = len3;
372 dims[3] = len4;
373 dims[4] = len5;
374 oop obj = arrayKlass::cast(elem_type)->multi_allocate(5, dims, THREAD);
375 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION);
376 thread->set_vm_result(obj);
377 JRT_END
378
379 JRT_ENTRY(void, OptoRuntime::multianewarrayN_C(klassOopDesc* elem_type, arrayOopDesc* dims, JavaThread *thread))
380 assert(check_compiled_frame(thread), "incorrect caller");
381 assert(oop(elem_type)->is_klass(), "not a class");
382 assert(oop(dims)->is_array(), "not an array");
383
384 ResourceMark rm;
385 jint len = dims->length();
386 assert(len > 0, "Dimensions array should contain data");
387 jint *j_dims = (jint*)dims->base(T_INT);
388 jint *c_dims = NEW_RESOURCE_ARRAY(jint, len);
389 memcpy(c_dims, j_dims, sizeof(jint)*len);
390
391 oop obj = arrayKlass::cast(elem_type)->multi_allocate(len, c_dims, THREAD);
392 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION);
393 thread->set_vm_result(obj);
394 JRT_END
395
396
397 const TypeFunc *OptoRuntime::new_instance_Type() {
398 // create input type (domain)
399 const Type **fields = TypeTuple::fields(1);
400 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated
401 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
402
403 // create result type (range)
404 fields = TypeTuple::fields(1);
405 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
406
407 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
408
409 return TypeFunc::make(domain, range);
410 }
411
412
413 const TypeFunc *OptoRuntime::athrow_Type() {
414 // create input type (domain)
415 const Type **fields = TypeTuple::fields(1);
416 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated
457
458 return TypeFunc::make(domain, range);
459 }
460
461 const TypeFunc *OptoRuntime::multianewarray2_Type() {
462 return multianewarray_Type(2);
463 }
464
465 const TypeFunc *OptoRuntime::multianewarray3_Type() {
466 return multianewarray_Type(3);
467 }
468
469 const TypeFunc *OptoRuntime::multianewarray4_Type() {
470 return multianewarray_Type(4);
471 }
472
473 const TypeFunc *OptoRuntime::multianewarray5_Type() {
474 return multianewarray_Type(5);
475 }
476
477 const TypeFunc *OptoRuntime::multianewarrayN_Type() {
478 // create input type (domain)
479 const Type **fields = TypeTuple::fields(2);
480 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // element klass
481 fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // array of dim sizes
482 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
483
484 // create result type (range)
485 fields = TypeTuple::fields(1);
486 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
487 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
488
489 return TypeFunc::make(domain, range);
490 }
491
492 const TypeFunc *OptoRuntime::g1_wb_pre_Type() {
493 const Type **fields = TypeTuple::fields(2);
494 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value
495 fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL; // thread
496 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
497
498 // create result type (range)
499 fields = TypeTuple::fields(0);
500 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
501
502 return TypeFunc::make(domain, range);
503 }
504
505 const TypeFunc *OptoRuntime::g1_wb_post_Type() {
506
507 const Type **fields = TypeTuple::fields(2);
508 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Card addr
509 fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL; // thread
510 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
511
|