14
14
#include "ujit_core.h"
15
15
#include "ujit_hooks.inc"
16
16
17
+ VALUE cUjitBlock ;
18
+
19
+ extern st_table * version_tbl ;
20
+ extern codeblock_t * cb ;
21
+
22
+ static const rb_data_type_t ujit_block_type = {
23
+ "UJIT/Block" ,
24
+ {0 , 0 , 0 , },
25
+ 0 , 0 , RUBY_TYPED_FREE_IMMEDIATELY
26
+ };
27
+
17
28
bool rb_ujit_enabled ;
18
29
19
30
// Hash table of encoded instructions
@@ -288,6 +299,87 @@ rb_ujit_compile_iseq(const rb_iseq_t *iseq)
288
299
#endif
289
300
}
290
301
302
+ struct ujit_block_itr {
303
+ const rb_iseq_t * iseq ;
304
+ VALUE list ;
305
+ };
306
+
307
+ static int
308
+ iseqw_ujit_collect_blocks (st_data_t key , st_data_t value , st_data_t argp )
309
+ {
310
+ block_t * block = (block_t * )value ;
311
+ struct ujit_block_itr * itr = (struct ujit_block_itr * )argp ;
312
+
313
+ if (block -> blockid .iseq == itr -> iseq ) {
314
+ VALUE rb_block = TypedData_Wrap_Struct (cUjitBlock , & ujit_block_type , block );
315
+ rb_ary_push (itr -> list , rb_block );
316
+ }
317
+ return ST_CONTINUE ;
318
+ }
319
+
320
+ /* Get a list of the UJIT blocks associated with `rb_iseq` */
321
+ static VALUE
322
+ ujit_blocks_for (VALUE mod , VALUE rb_iseq )
323
+ {
324
+ const rb_iseq_t * iseq = rb_iseqw_to_iseq (rb_iseq );
325
+ st_table * vt = (st_table * )version_tbl ;
326
+ struct ujit_block_itr itr ;
327
+ itr .iseq = iseq ;
328
+ itr .list = rb_ary_new ();
329
+
330
+ rb_st_foreach (vt , iseqw_ujit_collect_blocks , (st_data_t )& itr );
331
+
332
+ return itr .list ;
333
+ }
334
+
335
+ static VALUE
336
+ ujit_insert (VALUE mod , VALUE iseq )
337
+ {
338
+ rb_ujit_compile_iseq (rb_iseqw_to_iseq (iseq ));
339
+ return iseq ;
340
+ }
341
+
342
+ /* Get the address of the UJIT::Block */
343
+ static VALUE
344
+ block_address (VALUE self )
345
+ {
346
+ block_t * block ;
347
+ TypedData_Get_Struct (self , block_t , & ujit_block_type , block );
348
+ return LONG2NUM ((intptr_t )block );
349
+ }
350
+
351
+ /* Get the machine code for UJIT::Block as a binary string */
352
+ static VALUE
353
+ block_code (VALUE self )
354
+ {
355
+ block_t * block ;
356
+ TypedData_Get_Struct (self , block_t , & ujit_block_type , block );
357
+
358
+ return rb_str_new (cb -> mem_block + block -> start_pos , block -> end_pos - block -> start_pos );
359
+ }
360
+
361
+ /* Get the start index in the Instruction Sequence that corresponds to this
362
+ * UJIT::Block */
363
+ static VALUE
364
+ iseq_start_index (VALUE self )
365
+ {
366
+ block_t * block ;
367
+ TypedData_Get_Struct (self , block_t , & ujit_block_type , block );
368
+
369
+ return INT2NUM (block -> blockid .idx );
370
+ }
371
+
372
+ /* Get the end index in the Instruction Sequence that corresponds to this
373
+ * UJIT::Block */
374
+ static VALUE
375
+ iseq_end_index (VALUE self )
376
+ {
377
+ block_t * block ;
378
+ TypedData_Get_Struct (self , block_t , & ujit_block_type , block );
379
+
380
+ return INT2NUM (block -> end_idx );
381
+ }
382
+
291
383
void
292
384
rb_ujit_init (void )
293
385
{
@@ -301,6 +393,16 @@ rb_ujit_init(void)
301
393
ujit_init_core ();
302
394
ujit_init_codegen ();
303
395
396
+ VALUE mUjit = rb_define_module ("UJIT" );
397
+ rb_define_module_function (mUjit , "install_entry" , ujit_insert , 1 );
398
+ rb_define_module_function (mUjit , "blocks_for" , ujit_blocks_for , 1 );
399
+
400
+ cUjitBlock = rb_define_class_under (mUjit , "Block" , rb_cObject );
401
+ rb_define_method (cUjitBlock , "address" , block_address , 0 );
402
+ rb_define_method (cUjitBlock , "code" , block_code , 0 );
403
+ rb_define_method (cUjitBlock , "iseq_start_index" , iseq_start_index , 0 );
404
+ rb_define_method (cUjitBlock , "iseq_end_index" , iseq_end_index , 0 );
405
+
304
406
// Initialize the GC hooks
305
407
method_lookup_dependency = st_init_numtable ();
306
408
struct ujit_root_struct * root ;
0 commit comments