33import com .genexus .ModelContext ;
44
55import java .io .*;
6- import java .nio . channels . FileChannel ;
6+ import java .util . Date ;
77import java .util .HashSet ;
88import java .util .UUID ;
9- import java .util .Date ;
109import java .util .concurrent .*;
1110import java .util .concurrent .atomic .AtomicInteger ;
1211
@@ -37,7 +36,7 @@ public static GXDebugManager getInstance()
3736 return instance ;
3837 }
3938
40- private static int BUFFER_INITIAL_SIZE = 16383 ;
39+ private static final int BUFFER_INITIAL_SIZE = 16383 ;
4140 private static final long TICKS_NOT_SET = Long .MAX_VALUE ;
4241 private static final long TICKS_NOT_NEEDED = 0 ;
4342 private static String fileName = "gxperf.gxd" ;
@@ -54,7 +53,7 @@ private GXDebugManager()
5453 }
5554 sessionGuid = UUID .randomUUID ();
5655 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 ());
5857 pushSystem (GXDebugMsgCode .INITIALIZE .toByteInt (), new Date ());
5958 }
6059
@@ -88,11 +87,11 @@ private int newSId()
8887
8988 private GXDebugItem [] current , next , toSave ;
9089 private boolean saving = false ;
91- private int dbgIndex = 0 ;
90+ private volatile int dbgIndex = 0 ;
9291 private final Object saveLock = new Object ();
9392 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 <>();
9695
9796 private static ExecutorService executorService ;
9897
@@ -119,13 +118,13 @@ protected GXDebugItem pushRange(GXDebugInfo dbgInfo, int lineNro, int colNro, in
119118 else return mPush (dbgInfo , GXDebugMsgType .PGM_TRACE_RANGE , lineNro , lineNro2 , null );
120119 }
121120
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 )
123122 {
124123 synchronized (saveLock )
125124 {
126125 if (toSave != null )
127126 {
128- save (toSave );
127+ save (toSave , - 1 , true );
129128 toSave = null ;
130129 }
131130 GXDebugItem currentItem = current [dbgIndex ];
@@ -183,13 +182,9 @@ private GXDebugItem mPush(GXDebugInfo dbgInfo, GXDebugMsgType msgType, int arg1,
183182
184183 }
185184
186- private void save (GXDebugItem [] toSave )
187- {
188- save (toSave , -1 , true );
189- }
190-
191185 private void save (GXDebugItem [] toSave , int saveTop , boolean saveInThread )
192186 {
187+ // This method always runs inside the critical section defined by saveLock
193188 int saveCount = 0 ;
194189 if (saveTop == -1 )
195190 {
@@ -237,15 +232,16 @@ else if(saveTop == 0)
237232 final GXDebugItem [] mToSave = toSave ;
238233 final int mSaveTop = saveTop ;
239234 final int mSaveCount = saveCount ;
240- executorService .execute (new Runnable (){ public void run (){ mSave (mToSave , mSaveTop , mSaveCount );}} );
235+ executorService .execute (() -> mSave (mToSave , mSaveTop , mSaveCount ));
241236 }
242237 else mSave (toSave , saveTop , saveCount );
243- }
238+ }
244239
245240 protected void onExit (GXDebugInfo dbgInfo )
246241 {
247242 pushSystem (GXDebugMsgCode .EXIT .toByteInt ());
248243 save ();
244+ executorService .shutdown ();
249245 }
250246
251247 protected void onCleanup (GXDebugInfo dbgInfo )
@@ -270,7 +266,7 @@ private void save()
270266 {
271267 if (toSave != null )
272268 {
273- save (toSave );
269+ save (toSave , - 1 , true );
274270 toSave = null ;
275271 }
276272 save (current , dbgIndex , false );
@@ -288,7 +284,7 @@ private void clearDebugItem(GXDebugItem dbgItem)
288284
289285 private void mSave (GXDebugItem [] data , int saveTop , int saveCount )
290286 {
291- synchronized (mSaveLock )
287+ synchronized (mSaveLock )
292288 {
293289 // Obtengo chunk a grabar
294290 int idx = 0 ;
@@ -302,65 +298,66 @@ private void mSave(GXDebugItem [] data, int saveTop, int saveCount)
302298 for (; idx < saveTop ; idx ++)
303299 {
304300 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 ;
319316 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 ;
336333 case PGM_TRACE_RANGE :
337334 case PGM_TRACE_RANGE_WITH_COLS :
338335 {
339336 stream .writeByte (dbgItem .msgType .toByteInt ());
340337 stream .writeVLUInt (dbgItem .dbgInfo .sId );
341338 stream .writeVLUInt (dbgItem .arg1 );
342339 stream .writeVLUInt (dbgItem .arg2 );
343- if (dbgItem .msgType == GXDebugMsgType .PGM_TRACE_RANGE_WITH_COLS )
340+ if (dbgItem .msgType == GXDebugMsgType .PGM_TRACE_RANGE_WITH_COLS )
344341 {
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 );
347344 }
348345 }
349346 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+ }
364361 } finally
365362 {
366363 if (stream != null )
@@ -460,7 +457,7 @@ private int toByteInt()
460457 }
461458
462459
463- class GXDebugItem
460+ static class GXDebugItem
464461 {
465462 GXDebugInfo dbgInfo ;
466463 int arg1 ;
@@ -478,7 +475,7 @@ public String toString()
478475 private String toStringTicks (){ return (msgType == GXDebugMsgType .PGM_TRACE ? String .format (" elapsed:%d" , ticks ) : "" ); }
479476 }
480477
481- class IntPair
478+ static class IntPair
482479 {
483480 final int left ;
484481 final int right ;
@@ -505,7 +502,7 @@ public boolean equals(Object o)
505502
506503 }
507504
508- class PgmInfo
505+ static class PgmInfo
509506 {
510507 final int dbgLines ;
511508 final long hash ;
@@ -552,7 +549,7 @@ public final void restart()
552549
553550 static class GXDebugStream extends FilterOutputStream
554551 {
555- class ESCAPE
552+ static class ESCAPE
556553 {
557554 static final byte PROLOG = 0 ;
558555 static final byte EPILOG = 1 ;
@@ -565,15 +562,12 @@ class ESCAPE
565562
566563 static GXDebugStream getStream (String fileName ) throws IOException
567564 {
568- try (FileOutputStream stream = new FileOutputStream (fileName , true )){
569- return new GXDebugStream (new BufferedOutputStream (stream ), stream .getChannel ());
570- }
565+ return new GXDebugStream (fileName );
571566 }
572567
573- private GXDebugStream (OutputStream stream , FileChannel channel ) throws IOException
568+ private GXDebugStream (String fileName ) throws IOException
574569 {
575- this (stream );
576- channel .lock ();
570+ this (new BufferedOutputStream (new FileOutputStream (fileName , true )));
577571 }
578572
579573 GXDebugStream (OutputStream stream )
@@ -588,8 +582,8 @@ private GXDebugStream(OutputStream stream, FileChannel channel) throws IOExcepti
588582 public void close () throws IOException
589583 {
590584 writeEpilog ();
591- super .close ();
592- }
585+ super .close ();
586+ }
593587
594588 private void writeProlog (short version ) throws IOException
595589 {
@@ -610,7 +604,11 @@ public void write(byte[] data) throws IOException
610604
611605 void writeRaw (byte [] data , int from , int length ) throws IOException
612606 {
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 ++]);
614612 }
615613
616614 void writeRaw (byte value ) throws IOException
@@ -625,16 +623,17 @@ public void write(byte[] data, int offset, int count) throws IOException
625623 writeByte (data [offset ++]);
626624 }
627625
628- private int last , lastLast ;
626+ private volatile int last , lastLast ;
629627
630628 @ Override
631- public void write (int value )throws IOException
629+ public void write (int value ) throws IOException
632630 {
633631 writeByte (value );
634632 }
635633
636634 void writeByte (int value ) throws IOException
637635 {
636+ value &= 0xFF ;
638637 super .write (value );
639638 if (value == 0xFF &&
640639 value == last &&
@@ -703,7 +702,7 @@ void writeInt(long value) throws IOException
703702 }
704703 }
705704
706- private int LastSId , LastLine1 ;
705+ private volatile int LastSId , LastLine1 ;
707706
708707 void writePgmTrace (int SId , int line1 , int col , long ticks ) throws IOException
709708 {
0 commit comments