@@ -215,379 +215,3 @@ fn add_substr(&dest: ~[u8], src: ~[u8]) {
215
215
dest += src;
216
216
}
217
217
218
- fn shape_of ( ccx : @crate_ctxt , t : ty:: t ) -> ~[ u8 ] {
219
- match ty:: get ( t) . sty {
220
- ty:: ty_nil | ty:: ty_bool | ty:: ty_uint( ast:: ty_u8) |
221
- ty:: ty_bot => ~[ shape_u8] ,
222
- ty:: ty_int( ast:: ty_i) => ~[ s_int ( ccx. tcx ) ] ,
223
- ty:: ty_float( ast:: ty_f) => ~[ s_float ( ccx. tcx ) ] ,
224
- ty:: ty_uint( ast:: ty_u) | ty:: ty_ptr( _) => ~[ s_uint ( ccx. tcx ) ] ,
225
- ty:: ty_type => ~[ s_tydesc ( ccx. tcx ) ] ,
226
- ty:: ty_int( ast:: ty_i8) => ~[ shape_i8] ,
227
- ty:: ty_uint( ast:: ty_u16) => ~[ shape_u16] ,
228
- ty:: ty_int( ast:: ty_i16) => ~[ shape_i16] ,
229
- ty:: ty_uint( ast:: ty_u32) => ~[ shape_u32] ,
230
- ty:: ty_int( ast:: ty_i32) | ty:: ty_int( ast:: ty_char) => ~[ shape_i32] ,
231
- ty:: ty_uint( ast:: ty_u64) => ~[ shape_u64] ,
232
- ty:: ty_int( ast:: ty_i64) => ~[ shape_i64] ,
233
- ty:: ty_float( ast:: ty_f32) => ~[ shape_f32] ,
234
- ty:: ty_float( ast:: ty_f64) => ~[ shape_f64] ,
235
- ty:: ty_estr( ty:: vstore_uniq) => {
236
- shape_of ( ccx, tvec:: expand_boxed_vec_ty ( ccx. tcx , t) )
237
- }
238
- ty:: ty_enum( did, substs) => {
239
- match enum_kind ( ccx, did) {
240
- tk_unit => ~[ s_variant_enum_t ( ccx. tcx ) ] ,
241
- tk_enum => ~[ s_variant_enum_t ( ccx. tcx ) ] ,
242
- tk_newtype | tk_complex => {
243
- let mut s = ~[ shape_enum] , id;
244
- let nom_id = mk_nominal_id ( ccx. tcx , did,
245
- None , substs. tps ) ;
246
- match ccx. shape_cx . tag_id_to_index . find ( nom_id) {
247
- None => {
248
- id = ccx. shape_cx . next_tag_id ;
249
- ccx. shape_cx . tag_id_to_index . insert ( nom_id, id) ;
250
- ccx. shape_cx . tag_order . push ( { did: did,
251
- substs: substs} ) ;
252
- ccx. shape_cx . next_tag_id += 1u16 ;
253
- }
254
- Some ( existing_id) => id = existing_id,
255
- }
256
- add_u16 ( s, id as u16 ) ;
257
-
258
- s
259
- }
260
- }
261
- }
262
- ty:: ty_estr( ty:: vstore_box) |
263
- ty:: ty_evec( _, ty:: vstore_box) |
264
- ty:: ty_box( _) | ty:: ty_opaque_box => ~[ shape_box] ,
265
- ty:: ty_uniq( mt) => {
266
- let mut s = ~[ shape_uniq] ;
267
- add_substr ( s, shape_of ( ccx, mt. ty ) ) ;
268
- s
269
- }
270
- ty:: ty_unboxed_vec( mt) => {
271
- let mut s = ~[ shape_unboxed_vec] ;
272
- add_bool ( s, ty:: type_is_pod ( ccx. tcx , mt. ty ) ) ;
273
- add_substr ( s, shape_of ( ccx, mt. ty ) ) ;
274
- s
275
- }
276
- ty:: ty_evec( _, ty:: vstore_uniq) => {
277
- shape_of ( ccx, tvec:: expand_boxed_vec_ty ( ccx. tcx , t) )
278
- }
279
-
280
- ty:: ty_estr( ty:: vstore_fixed( n) ) => {
281
- let mut s = ~[ shape_fixedvec] ;
282
- let u8_t = ty:: mk_mach_uint ( ccx. tcx , ast:: ty_u8) ;
283
- assert ( n + 1 u) <= 0xffff u;
284
- add_u16 ( s, ( n + 1 u) as u16 ) ;
285
- add_bool ( s, true ) ;
286
- add_substr ( s, shape_of ( ccx, u8_t) ) ;
287
- s
288
- }
289
-
290
- ty:: ty_evec( mt, ty:: vstore_fixed( n) ) => {
291
- let mut s = ~[ shape_fixedvec] ;
292
- assert n <= 0xffff u;
293
- add_u16 ( s, n as u16 ) ;
294
- add_bool ( s, ty:: type_is_pod ( ccx. tcx , mt. ty ) ) ;
295
- add_substr ( s, shape_of ( ccx, mt. ty ) ) ;
296
- s
297
- }
298
-
299
- ty:: ty_estr( ty:: vstore_slice( _) ) => {
300
- let mut s = ~[ shape_slice] ;
301
- let u8_t = ty:: mk_mach_uint ( ccx. tcx , ast:: ty_u8) ;
302
- add_bool ( s, true ) ; // is_pod
303
- add_bool ( s, true ) ; // is_str
304
- add_substr ( s, shape_of ( ccx, u8_t) ) ;
305
- s
306
- }
307
-
308
- ty:: ty_evec( mt, ty:: vstore_slice( _) ) => {
309
- let mut s = ~[ shape_slice] ;
310
- add_bool ( s, ty:: type_is_pod ( ccx. tcx , mt. ty ) ) ;
311
- add_bool ( s, false ) ; // is_str
312
- add_substr ( s, shape_of ( ccx, mt. ty ) ) ;
313
- s
314
- }
315
-
316
- ty:: ty_rec( fields) => {
317
- let mut s = ~[ shape_struct] , sub = ~[ ] ;
318
- for vec:: each( fields) |f| {
319
- sub += shape_of ( ccx, f. mt . ty ) ;
320
- }
321
- add_substr ( s, sub) ;
322
- s
323
- }
324
- ty:: ty_tup( elts) => {
325
- let mut s = ~[ shape_struct] , sub = ~[ ] ;
326
- for vec:: each( elts) |elt| {
327
- sub += shape_of ( ccx, * elt) ;
328
- }
329
- add_substr ( s, sub) ;
330
- s
331
- }
332
- ty:: ty_trait( _, _, _) => ~[ shape_box_fn] ,
333
- ty:: ty_class( did, ref substs) => {
334
- // same as records, unless there's a dtor
335
- let tps = substs. tps ;
336
- let m_dtor_did = ty:: ty_dtor ( ccx. tcx , did) ;
337
- let mut s = if m_dtor_did. is_some ( ) {
338
- ~[ shape_res]
339
- }
340
- else { ~[ shape_struct] } , sub = ~[ ] ;
341
- do m_dtor_did. iter |dtor_did| {
342
- let ri = @{ did: dtor_did, parent_id: Some ( did) , tps: tps} ;
343
- let id = ccx. shape_cx . resources . intern ( ri) ;
344
- add_u16 ( s, id as u16 ) ;
345
- } ;
346
- for ty:: class_items_as_mutable_fields( ccx. tcx, did,
347
- substs) . each |f| {
348
- sub += shape_of ( ccx, f. mt . ty ) ;
349
- }
350
- add_substr ( s, sub) ;
351
- s
352
- }
353
- ty:: ty_rptr( _, mt) => {
354
- let mut s = ~[ shape_rptr] ;
355
- add_substr ( s, shape_of ( ccx, mt. ty ) ) ;
356
- s
357
- }
358
- ty:: ty_param( * ) => {
359
- ccx. tcx . sess . bug ( ~"non-monomorphized type parameter") ;
360
- }
361
- ty:: ty_fn( ref fn_ty) => {
362
- match fn_ty. meta . proto {
363
- ty:: proto_vstore( ty:: vstore_box) => ~[ shape_box_fn] ,
364
- ty:: proto_vstore( ty:: vstore_uniq) => ~[ shape_uniq_fn] ,
365
- ty:: proto_vstore( ty:: vstore_slice( _) ) => ~[ shape_stack_fn] ,
366
- ty:: proto_bare => ~[ shape_bare_fn] ,
367
- ty:: proto_vstore( ty:: vstore_fixed( _) ) =>
368
- fail ~"fixed vstore is impossible",
369
- }
370
- }
371
- ty:: ty_opaque_closure_ptr( _) => ~[ shape_opaque_closure_ptr] ,
372
- ty:: ty_infer( _) | ty:: ty_self => {
373
- ccx. sess . bug ( ~"shape_of: unexpected type struct found")
374
- }
375
- }
376
- }
377
-
378
- fn shape_of_variant ( ccx : @crate_ctxt , v : ty:: variant_info ) -> ~[ u8 ] {
379
- let mut s = ~[ ] ;
380
- for vec:: each( v. args) |t| { s += shape_of ( ccx, * t) ; }
381
- return s;
382
- }
383
-
384
- fn gen_enum_shapes ( ccx : @crate_ctxt ) -> ValueRef {
385
- // Loop over all the enum variants and write their shapes into a
386
- // data buffer. As we do this, it's possible for us to discover
387
- // new enums, so we must do this first.
388
- let mut data = ~[ ] ;
389
- let mut offsets = ~[ ] ;
390
- let mut i = 0 u;
391
- let mut enum_variants = ~[ ] ;
392
- while i < ccx. shape_cx . tag_order . len ( ) {
393
- let { did, substs} = ccx. shape_cx . tag_order [ i] ;
394
- let variants = @ty:: substd_enum_variants ( ccx. tcx , did, & substs) ;
395
- for vec:: each( * variants) |v| {
396
- offsets += ~[ vec:: len ( data) as u16 ] ;
397
-
398
- let variant_shape = shape_of_variant ( ccx, * v) ;
399
- add_substr ( data, variant_shape) ;
400
-
401
- let zname = str:: to_bytes ( ccx. sess . str_of ( v. name ) ) + ~[ 0u8 ] ;
402
- add_substr ( data, zname) ;
403
- }
404
- enum_variants += ~[ variants] ;
405
- i += 1 u;
406
- }
407
-
408
- // Now calculate the sizes of the header space (which contains offsets to
409
- // info records for each enum) and the info space (which contains offsets
410
- // to each variant shape). As we do so, build up the header.
411
-
412
- let mut header = ~[ ] ;
413
- let mut inf = ~[ ] ;
414
- let header_sz = 2u16 * ccx. shape_cx . next_tag_id ;
415
- let data_sz = vec:: len ( data) as u16 ;
416
-
417
- let mut inf_sz = 0u16 ;
418
- for enum_variants. each |variants| {
419
- let num_variants = vec:: len ( * * variants) as u16 ;
420
- add_u16 ( header, header_sz + inf_sz) ;
421
- inf_sz += 2u16 * ( num_variants + 2u16 ) + 3u16 ;
422
- }
423
-
424
- // Construct the info tables, which contain offsets to the shape of each
425
- // variant. Also construct the largest-variant table for each enum, which
426
- // contains the variants that the size-of operation needs to look at.
427
-
428
- let mut lv_table = ~[ ] ;
429
- let mut i = 0 u;
430
- for enum_variants. each |variants| {
431
- add_u16( inf, vec:: len( * * variants) as u16 ) ;
432
-
433
- // Construct the largest-variants table.
434
- add_u16 ( inf,
435
- header_sz + inf_sz + data_sz + ( vec:: len ( lv_table) as u16 ) ) ;
436
-
437
- let lv = largest_variants ( ccx, * variants) ;
438
- add_u16 ( lv_table, vec:: len ( lv) as u16 ) ;
439
- for vec:: each( lv) |v| { add_u16 ( lv_table, * v as u16 ) ; }
440
-
441
- // Determine whether the enum has dynamic size.
442
- assert !variants. any ( |v| v. args . any ( |t| ty:: type_has_params ( t) ) ) ;
443
-
444
- // If we can, write in the static size and alignment of the enum.
445
- // Otherwise, write a placeholder.
446
- let size_align = compute_static_enum_size ( ccx, lv, * variants) ;
447
-
448
- // Write in the static size and alignment of the enum.
449
- add_u16 ( inf, size_align. size ) ;
450
- inf += ~[ size_align. align ] ;
451
-
452
- // Now write in the offset of each variant.
453
- for variants. each |_v| {
454
- add_u16( inf, header_sz + inf_sz + offsets[ i] ) ;
455
- i += 1 u;
456
- }
457
- }
458
-
459
- assert ( i == vec:: len ( offsets) ) ;
460
- assert ( header_sz == vec:: len ( header) as u16 ) ;
461
- assert ( inf_sz == vec:: len ( inf) as u16 ) ;
462
- assert ( data_sz == vec:: len ( data) as u16 ) ;
463
-
464
- header += inf;
465
- header += data;
466
- header += lv_table;
467
-
468
- return mk_global ( ccx, ~"tag_shapes", C_bytes ( header) , true ) ;
469
-
470
- /* tjc: Not annotating FIXMEs in this module because of #1498 */
471
- fn largest_variants ( ccx : @crate_ctxt ,
472
- variants : @~[ ty:: variant_info ] ) -> ~[ uint ] {
473
- // Compute the minimum and maximum size and alignment for each
474
- // variant.
475
- //
476
- // NB: We could do better here; e.g. we know that any
477
- // variant that contains (T,T) must be as least as large as
478
- // any variant that contains just T.
479
- let mut ranges = ~[ ] ;
480
- for vec:: each( * variants) |variant| {
481
- let mut bounded = true ;
482
- let mut min_size = 0 u, min_align = 0 u;
483
- for vec:: each( variant. args) |elem_t| {
484
- if ty:: type_has_params ( * elem_t) {
485
- // NB: We could do better here; this causes us to
486
- // conservatively assume that (int, T) has minimum size 0,
487
- // when in fact it has minimum size sizeof(int).
488
- bounded = false ;
489
- } else {
490
- let llty = type_of:: type_of ( ccx, * elem_t) ;
491
- min_size += llsize_of_real ( ccx, llty) ;
492
- min_align += llalign_of_pref ( ccx, llty) ;
493
- }
494
- }
495
-
496
- ranges +=
497
- ~[ { size : { min : min_size, bounded : bounded} ,
498
- align : { min : min_align, bounded : bounded} } ] ;
499
- }
500
-
501
- // Initialize the candidate set to contain all variants.
502
- let mut candidates = ~[ mut] ;
503
- for vec:: each( * variants) |_v| { candidates += ~[ mut true ] ; }
504
-
505
- // Do a pairwise comparison among all variants still in the
506
- // candidate set. Throw out any variant that we know has size
507
- // and alignment at least as small as some other variant.
508
- let mut i = 0 u;
509
- while i < vec:: len ( ranges) - 1 u {
510
- if candidates[ i] {
511
- let mut j = i + 1 u;
512
- while j < vec:: len ( ranges) {
513
- if candidates[ j] {
514
- if ranges[ i] . size . bounded &&
515
- ranges[ i] . align . bounded &&
516
- ranges[ j] . size . bounded &&
517
- ranges[ j] . align . bounded {
518
- if ranges[ i] . size . min >= ranges[ j] . size . min &&
519
- ranges[ i] . align . min >= ranges[ j] . align . min {
520
- // Throw out j.
521
- candidates[ j] = false ;
522
- } else if ranges[ j] . size . min >=
523
- ranges[ i] . size . min &&
524
- ranges[ j] . align . min >=
525
- ranges[ j] . align . min {
526
- // Throw out i.
527
- candidates[ i] = false ;
528
- }
529
- }
530
- }
531
- j += 1 u;
532
- }
533
- }
534
- i += 1 u;
535
- }
536
-
537
- // Return the resulting set.
538
- let mut result = ~[ ] ;
539
- let mut i = 0 u;
540
- while i < vec:: len ( candidates) {
541
- if candidates[ i] { vec:: push ( result, i) ; }
542
- i += 1 u;
543
- }
544
- return result;
545
- }
546
-
547
- fn compute_static_enum_size ( ccx : @crate_ctxt , largest_variants : ~[ uint ] ,
548
- variants : @~[ ty:: variant_info ] )
549
- -> size_align {
550
- let mut max_size = 0u16 ;
551
- let mut max_align = 1u8 ;
552
- for vec:: each( largest_variants) |vid| {
553
- // We increment a "virtual data pointer" to compute the size.
554
- let mut lltys = ~[ ] ;
555
- for vec:: each( variants[ * vid] . args) |typ| {
556
- lltys += ~[ type_of:: type_of ( ccx, * typ) ] ;
557
- }
558
-
559
- let llty = trans:: common:: T_struct ( lltys) ;
560
- let dp = llsize_of_real ( ccx, llty) as u16 ;
561
- let variant_align = llalign_of_pref ( ccx, llty) as u8 ;
562
-
563
- if max_size < dp { max_size = dp; }
564
- if max_align < variant_align { max_align = variant_align; }
565
- }
566
-
567
- // Add space for the enum if applicable.
568
- // FIXME (issue #792): This is wrong. If the enum starts with an
569
- // 8 byte aligned quantity, we don't align it.
570
- if vec:: len ( * variants) > 1 u {
571
- let variant_t = T_enum_discrim ( ccx) ;
572
- max_size += llsize_of_real ( ccx, variant_t) as u16 ;
573
- let align = llalign_of_pref ( ccx, variant_t) as u8 ;
574
- if max_align < align { max_align = align; }
575
- }
576
-
577
- return { size: max_size, align: max_align} ;
578
- }
579
- }
580
-
581
- fn gen_resource_shapes ( ccx : @crate_ctxt ) -> ValueRef {
582
- let mut dtors = ~[ ] ;
583
- let len = ccx. shape_cx . resources . len ( ) ;
584
- for uint:: range( 0 u, len) |i| {
585
- let ri = ccx. shape_cx . resources . get ( i) ;
586
- for ri. tps. each( ) |s| { assert !ty:: type_has_params( * s) ; }
587
- do ri. parent_id. iter |id| {
588
- dtors += ~[ trans:: base:: get_res_dtor ( ccx, ri. did , id, ri. tps ) ] ;
589
- }
590
- }
591
- return mk_global ( ccx, ~"resource_shapes", C_struct ( dtors) , true ) ;
592
- }
593
-
0 commit comments