3
3
import com .genexus .ModelContext ;
4
4
5
5
import java .io .*;
6
- import java .nio . channels . FileChannel ;
6
+ import java .util . Date ;
7
7
import java .util .HashSet ;
8
8
import java .util .UUID ;
9
- import java .util .Date ;
10
9
import java .util .concurrent .*;
11
10
import java .util .concurrent .atomic .AtomicInteger ;
12
11
@@ -37,7 +36,7 @@ public static GXDebugManager getInstance()
37
36
return instance ;
38
37
}
39
38
40
- private static int BUFFER_INITIAL_SIZE = 16383 ;
39
+ private static final int BUFFER_INITIAL_SIZE = 16383 ;
41
40
private static final long TICKS_NOT_SET = Long .MAX_VALUE ;
42
41
private static final long TICKS_NOT_NEEDED = 0 ;
43
42
private static String fileName = "gxperf.gxd" ;
@@ -54,7 +53,7 @@ private GXDebugManager()
54
53
}
55
54
sessionGuid = UUID .randomUUID ();
56
55
lastSId = new AtomicInteger ();
57
- executorService = new ThreadPoolExecutor (0 , 1 , 5 , TimeUnit .MINUTES , new SynchronousQueue <Runnable > ());
56
+ executorService = new ThreadPoolExecutor (0 , 1 , 5 , TimeUnit .MINUTES , new SynchronousQueue <>(), Executors . defaultThreadFactory (), new ThreadPoolExecutor . CallerRunsPolicy ());
58
57
pushSystem (GXDebugMsgCode .INITIALIZE .toByteInt (), new Date ());
59
58
}
60
59
@@ -88,11 +87,11 @@ private int newSId()
88
87
89
88
private GXDebugItem [] current , next , toSave ;
90
89
private boolean saving = false ;
91
- private int dbgIndex = 0 ;
90
+ private volatile int dbgIndex = 0 ;
92
91
private final Object saveLock = new Object ();
93
92
private final Object mSaveLock = new Object ();
94
- private final ConcurrentHashMap <String , GXDebugInfo > parentTable = new ConcurrentHashMap <String , GXDebugInfo >();
95
- private final HashSet <IntPair > pgmInfoTable = new HashSet <IntPair >();
93
+ private final ConcurrentHashMap <String , GXDebugInfo > parentTable = new ConcurrentHashMap <>();
94
+ private final HashSet <IntPair > pgmInfoTable = new HashSet <>();
96
95
97
96
private static ExecutorService executorService ;
98
97
@@ -119,13 +118,13 @@ protected GXDebugItem pushRange(GXDebugInfo dbgInfo, int lineNro, int colNro, in
119
118
else return mPush (dbgInfo , GXDebugMsgType .PGM_TRACE_RANGE , lineNro , lineNro2 , null );
120
119
}
121
120
122
- private GXDebugItem mPush (GXDebugInfo dbgInfo , GXDebugMsgType msgType , int arg1 , int arg2 , Object argObj )
121
+ private GXDebugItem mPush (GXDebugInfo dbgInfo , GXDebugMsgType msgType , int arg1 , int arg2 , Object argObj )
123
122
{
124
123
synchronized (saveLock )
125
124
{
126
125
if (toSave != null )
127
126
{
128
- save (toSave );
127
+ save (toSave , - 1 , true );
129
128
toSave = null ;
130
129
}
131
130
GXDebugItem currentItem = current [dbgIndex ];
@@ -183,13 +182,9 @@ private GXDebugItem mPush(GXDebugInfo dbgInfo, GXDebugMsgType msgType, int arg1,
183
182
184
183
}
185
184
186
- private void save (GXDebugItem [] toSave )
187
- {
188
- save (toSave , -1 , true );
189
- }
190
-
191
185
private void save (GXDebugItem [] toSave , int saveTop , boolean saveInThread )
192
186
{
187
+ // This method always runs inside the critical section defined by saveLock
193
188
int saveCount = 0 ;
194
189
if (saveTop == -1 )
195
190
{
@@ -237,15 +232,16 @@ else if(saveTop == 0)
237
232
final GXDebugItem [] mToSave = toSave ;
238
233
final int mSaveTop = saveTop ;
239
234
final int mSaveCount = saveCount ;
240
- executorService .execute (new Runnable (){ public void run (){ mSave (mToSave , mSaveTop , mSaveCount );}} );
235
+ executorService .execute (() -> mSave (mToSave , mSaveTop , mSaveCount ));
241
236
}
242
237
else mSave (toSave , saveTop , saveCount );
243
- }
238
+ }
244
239
245
240
protected void onExit (GXDebugInfo dbgInfo )
246
241
{
247
242
pushSystem (GXDebugMsgCode .EXIT .toByteInt ());
248
243
save ();
244
+ executorService .shutdown ();
249
245
}
250
246
251
247
protected void onCleanup (GXDebugInfo dbgInfo )
@@ -270,7 +266,7 @@ private void save()
270
266
{
271
267
if (toSave != null )
272
268
{
273
- save (toSave );
269
+ save (toSave , - 1 , true );
274
270
toSave = null ;
275
271
}
276
272
save (current , dbgIndex , false );
@@ -288,7 +284,7 @@ private void clearDebugItem(GXDebugItem dbgItem)
288
284
289
285
private void mSave (GXDebugItem [] data , int saveTop , int saveCount )
290
286
{
291
- synchronized (mSaveLock )
287
+ synchronized (mSaveLock )
292
288
{
293
289
// Obtengo chunk a grabar
294
290
int idx = 0 ;
@@ -302,65 +298,66 @@ private void mSave(GXDebugItem [] data, int saveTop, int saveCount)
302
298
for (; idx < saveTop ; idx ++)
303
299
{
304
300
GXDebugItem dbgItem = data [idx ];
305
- switch (dbgItem .msgType )
306
- {
307
- case SYSTEM :
308
- {
309
- stream .writeByte ((dbgItem .msgType .toByteInt () | (GXDebugMsgCode .valueOf (dbgItem .arg1 ).toByteInt ())));
310
- switch (GXDebugMsgCode .valueOf (dbgItem .arg1 ))
311
- {
312
- case INITIALIZE :
313
- stream .writeLong (ToTicks ((Date ) dbgItem .argObj ));
314
- break ;
315
- case OBJ_CLEANUP :
316
- stream .writeVLUInt ((Integer ) dbgItem .argObj );
317
- break ;
318
- case EXIT :
301
+ switch (dbgItem .msgType )
302
+ {
303
+ case SYSTEM :
304
+ {
305
+ stream .writeByte ((dbgItem .msgType .toByteInt () | (GXDebugMsgCode .valueOf (dbgItem .arg1 ).toByteInt ())));
306
+ switch (GXDebugMsgCode .valueOf (dbgItem .arg1 ))
307
+ {
308
+ case INITIALIZE :
309
+ stream .writeLong (ToTicks ((Date ) dbgItem .argObj ));
310
+ break ;
311
+ case OBJ_CLEANUP :
312
+ stream .writeVLUInt ((Integer ) dbgItem .argObj );
313
+ break ;
314
+ case EXIT :
315
+ break ;
319
316
case PGM_INFO :
320
- Object [] info = (Object [])dbgItem .argObj ;
321
- stream .writeVLUInt (((IntPair )info [0 ]).left );
322
- stream .writeVLUInt (((IntPair )info [0 ]).right );
323
- stream .writeVLUInt (((PgmInfo )info [1 ]).dbgLines );
324
- stream .writeInt (((PgmInfo )info [1 ]).hash );
325
- break ;
326
- default :
327
- throw new IllegalArgumentException (String .format ("Invalid DbgItem: %s" , dbgItem ));
328
- }
329
- }
330
- break ;
331
- case PGM_TRACE :
332
- {
333
- stream .writePgmTrace (dbgItem .dbgInfo .sId , dbgItem .arg1 , dbgItem .arg2 , dbgItem .ticks );
334
- }
335
- break ;
317
+ Object [] info = (Object []) dbgItem .argObj ;
318
+ stream .writeVLUInt (((IntPair ) info [0 ]).left );
319
+ stream .writeVLUInt (((IntPair ) info [0 ]).right );
320
+ stream .writeVLUInt (((PgmInfo ) info [1 ]).dbgLines );
321
+ stream .writeInt (((PgmInfo ) info [1 ]).hash );
322
+ break ;
323
+ default :
324
+ throw new IllegalArgumentException (String .format ("Invalid DbgItem: %s" , dbgItem ));
325
+ }
326
+ }
327
+ break ;
328
+ case PGM_TRACE :
329
+ {
330
+ stream .writePgmTrace (dbgItem .dbgInfo .sId , dbgItem .arg1 , dbgItem .arg2 , dbgItem .ticks );
331
+ }
332
+ break ;
336
333
case PGM_TRACE_RANGE :
337
334
case PGM_TRACE_RANGE_WITH_COLS :
338
335
{
339
336
stream .writeByte (dbgItem .msgType .toByteInt ());
340
337
stream .writeVLUInt (dbgItem .dbgInfo .sId );
341
338
stream .writeVLUInt (dbgItem .arg1 );
342
339
stream .writeVLUInt (dbgItem .arg2 );
343
- if (dbgItem .msgType == GXDebugMsgType .PGM_TRACE_RANGE_WITH_COLS )
340
+ if (dbgItem .msgType == GXDebugMsgType .PGM_TRACE_RANGE_WITH_COLS )
344
341
{
345
- stream .writeVLUInt (((IntPair )dbgItem .argObj ).left );
346
- stream .writeVLUInt (((IntPair )dbgItem .argObj ).right );
342
+ stream .writeVLUInt (((IntPair ) dbgItem .argObj ).left );
343
+ stream .writeVLUInt (((IntPair ) dbgItem .argObj ).right );
347
344
}
348
345
}
349
346
break ;
350
- case REGISTER_PGM :
351
- {
352
- stream .writeByte (dbgItem .msgType .toByteInt ());
353
- stream .writeVLUInt (dbgItem .dbgInfo .sId );
354
- stream .writeVLUInt (dbgItem .arg1 );
355
- stream .writeVLUInt (((IntPair ) dbgItem .argObj ).left );
356
- stream .writeVLUInt (((IntPair ) dbgItem .argObj ).right );
357
- }
358
- break ;
359
- case SKIP :
360
- continue ;
361
- }
362
- clearDebugItem (dbgItem );
363
- }
347
+ case REGISTER_PGM :
348
+ {
349
+ stream .writeByte (dbgItem .msgType .toByteInt ());
350
+ stream .writeVLUInt (dbgItem .dbgInfo .sId );
351
+ stream .writeVLUInt (dbgItem .arg1 );
352
+ stream .writeVLUInt (((IntPair ) dbgItem .argObj ).left );
353
+ stream .writeVLUInt (((IntPair ) dbgItem .argObj ).right );
354
+ }
355
+ break ;
356
+ case SKIP :
357
+ continue ;
358
+ }
359
+ clearDebugItem (dbgItem );
360
+ }
364
361
} finally
365
362
{
366
363
if (stream != null )
@@ -460,7 +457,7 @@ private int toByteInt()
460
457
}
461
458
462
459
463
- class GXDebugItem
460
+ static class GXDebugItem
464
461
{
465
462
GXDebugInfo dbgInfo ;
466
463
int arg1 ;
@@ -478,7 +475,7 @@ public String toString()
478
475
private String toStringTicks (){ return (msgType == GXDebugMsgType .PGM_TRACE ? String .format (" elapsed:%d" , ticks ) : "" ); }
479
476
}
480
477
481
- class IntPair
478
+ static class IntPair
482
479
{
483
480
final int left ;
484
481
final int right ;
@@ -505,7 +502,7 @@ public boolean equals(Object o)
505
502
506
503
}
507
504
508
- class PgmInfo
505
+ static class PgmInfo
509
506
{
510
507
final int dbgLines ;
511
508
final long hash ;
@@ -552,7 +549,7 @@ public final void restart()
552
549
553
550
static class GXDebugStream extends FilterOutputStream
554
551
{
555
- class ESCAPE
552
+ static class ESCAPE
556
553
{
557
554
static final byte PROLOG = 0 ;
558
555
static final byte EPILOG = 1 ;
@@ -565,15 +562,12 @@ class ESCAPE
565
562
566
563
static GXDebugStream getStream (String fileName ) throws IOException
567
564
{
568
- try (FileOutputStream stream = new FileOutputStream (fileName , true )){
569
- return new GXDebugStream (new BufferedOutputStream (stream ), stream .getChannel ());
570
- }
565
+ return new GXDebugStream (fileName );
571
566
}
572
567
573
- private GXDebugStream (OutputStream stream , FileChannel channel ) throws IOException
568
+ private GXDebugStream (String fileName ) throws IOException
574
569
{
575
- this (stream );
576
- channel .lock ();
570
+ this (new BufferedOutputStream (new FileOutputStream (fileName , true )));
577
571
}
578
572
579
573
GXDebugStream (OutputStream stream )
@@ -588,8 +582,8 @@ private GXDebugStream(OutputStream stream, FileChannel channel) throws IOExcepti
588
582
public void close () throws IOException
589
583
{
590
584
writeEpilog ();
591
- super .close ();
592
- }
585
+ super .close ();
586
+ }
593
587
594
588
private void writeProlog (short version ) throws IOException
595
589
{
@@ -610,7 +604,11 @@ public void write(byte[] data) throws IOException
610
604
611
605
void writeRaw (byte [] data , int from , int length ) throws IOException
612
606
{
613
- super .write (data , from , length );
607
+ if ((from | length | (data .length - (length + from )) | (from + length )) < 0 )
608
+ throw new IndexOutOfBoundsException ();
609
+
610
+ while (length -- > 0 )
611
+ writeRaw (data [from ++]);
614
612
}
615
613
616
614
void writeRaw (byte value ) throws IOException
@@ -625,16 +623,17 @@ public void write(byte[] data, int offset, int count) throws IOException
625
623
writeByte (data [offset ++]);
626
624
}
627
625
628
- private int last , lastLast ;
626
+ private volatile int last , lastLast ;
629
627
630
628
@ Override
631
- public void write (int value )throws IOException
629
+ public void write (int value ) throws IOException
632
630
{
633
631
writeByte (value );
634
632
}
635
633
636
634
void writeByte (int value ) throws IOException
637
635
{
636
+ value &= 0xFF ;
638
637
super .write (value );
639
638
if (value == 0xFF &&
640
639
value == last &&
@@ -703,7 +702,7 @@ void writeInt(long value) throws IOException
703
702
}
704
703
}
705
704
706
- private int LastSId , LastLine1 ;
705
+ private volatile int LastSId , LastLine1 ;
707
706
708
707
void writePgmTrace (int SId , int line1 , int col , long ticks ) throws IOException
709
708
{
0 commit comments