Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/back/SDE.c
38765 views
1
/*
2
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
#include <setjmp.h>
27
28
#include "util.h"
29
#include "SDE.h"
30
31
#ifdef __APPLE__
32
/* use setjmp/longjmp versions that do not save/restore the signal mask */
33
#define setjmp _setjmp
34
#define longjmp _longjmp
35
#endif
36
37
/**
38
* This SourceDebugExtension code does not
39
* allow concurrent translation - due to caching method.
40
* A separate thread setting the default stratum ID
41
* is, however, fine.
42
*/
43
44
#define INIT_SIZE_FILE 10
45
#define INIT_SIZE_LINE 100
46
#define INIT_SIZE_STRATUM 3
47
48
#define BASE_STRATUM_NAME "Java"
49
50
#define null NULL
51
#define true JNI_TRUE
52
#define false JNI_FALSE
53
#define String char *
54
#define private static
55
56
typedef struct {
57
int fileId;
58
String sourceName;
59
String sourcePath; // do not read - use accessor
60
int isConverted;
61
} FileTableRecord;
62
63
typedef struct {
64
int jplsStart;
65
int jplsEnd;
66
int jplsLineInc;
67
int njplsStart;
68
int njplsEnd;
69
int fileId;
70
} LineTableRecord;
71
72
typedef struct {
73
String id;
74
int fileIndex;
75
int lineIndex;
76
} StratumTableRecord;
77
78
/* back-end wide value for default stratum */
79
private String globalDefaultStratumId = null;
80
81
/* reference type default */
82
private String defaultStratumId = null;
83
84
private jclass cachedClass = NULL;
85
86
private FileTableRecord* fileTable;
87
private LineTableRecord* lineTable;
88
private StratumTableRecord* stratumTable;
89
90
private int fileTableSize;
91
private int lineTableSize;
92
private int stratumTableSize;
93
94
private int fileIndex;
95
private int lineIndex;
96
private int stratumIndex = 0;
97
private int currentFileId;
98
99
private int defaultStratumIndex;
100
private int baseStratumIndex;
101
private char* sdePos;
102
103
private char* jplsFilename = null;
104
private char* NullString = null;
105
106
/* mangled in parse, cannot be parsed. Must be kept. */
107
private String sourceDebugExtension;
108
109
private jboolean sourceMapIsValid;
110
111
private jmp_buf jmp_buf_env;
112
113
private int stratumTableIndex(String stratumId);
114
private int stiLineTableIndex(int sti, int jplsLine);
115
private int stiLineNumber(int sti, int lti, int jplsLine);
116
private void decode(void);
117
private void ignoreWhite(void);
118
private jboolean isValid(void);
119
120
private void
121
loadDebugInfo(JNIEnv *env, jclass clazz) {
122
123
if (!isSameObject(env, clazz, cachedClass)) {
124
/* Not the same - swap out the info */
125
126
/* Delete existing info */
127
if ( cachedClass != null ) {
128
tossGlobalRef(env, &cachedClass);
129
cachedClass = null;
130
}
131
if ( sourceDebugExtension!=null ) {
132
jvmtiDeallocate(sourceDebugExtension);
133
}
134
sourceDebugExtension = null;
135
136
/* Init info */
137
lineTable = null;
138
fileTable = null;
139
stratumTable = null;
140
lineTableSize = 0;
141
fileTableSize = 0;
142
stratumTableSize = 0;
143
fileIndex = 0;
144
lineIndex = 0;
145
stratumIndex = 0;
146
currentFileId = 0;
147
defaultStratumId = null;
148
defaultStratumIndex = -1;
149
baseStratumIndex = -2; /* so as not to match -1 above */
150
sourceMapIsValid = false;
151
152
if (getSourceDebugExtension(clazz, &sourceDebugExtension) ==
153
JVMTI_ERROR_NONE) {
154
sdePos = sourceDebugExtension;
155
if (setjmp(jmp_buf_env) == 0) {
156
/* this is the initial (non-error) case, do parse */
157
decode();
158
}
159
}
160
161
cachedClass = null;
162
saveGlobalRef(env, clazz, &cachedClass);
163
}
164
}
165
166
/* Return 1 if match, 0 if no match */
167
private int
168
patternMatch(char *classname, const char *pattern) {
169
int pattLen;
170
int compLen;
171
char *start;
172
int offset;
173
174
if (pattern == NULL || classname == NULL) {
175
return 0;
176
}
177
pattLen = (int)strlen(pattern);
178
179
if ((pattern[0] != '*') && (pattern[pattLen-1] != '*')) {
180
return strcmp(pattern, classname) == 0;
181
}
182
183
compLen = pattLen - 1;
184
offset = (int)strlen(classname) - compLen;
185
if (offset < 0) {
186
return 0;
187
}
188
if (pattern[0] == '*') {
189
pattern++;
190
start = classname + offset;
191
} else {
192
start = classname;
193
}
194
return strncmp(pattern, start, compLen) == 0;
195
}
196
197
/**
198
* Return 1 if p1 is a SourceName for stratum sti,
199
* else, return 0.
200
*/
201
private int
202
searchOneSourceName(int sti, char *p1) {
203
int fileIndexStart = stratumTable[sti].fileIndex;
204
/* one past end */
205
int fileIndexEnd = stratumTable[sti+1].fileIndex;
206
int ii;
207
for (ii = fileIndexStart; ii < fileIndexEnd; ++ii) {
208
if (patternMatch(fileTable[ii].sourceName, p1)) {
209
return 1;
210
}
211
}
212
return 0;
213
}
214
215
/**
216
* Return 1 if p1 is a SourceName for any stratum
217
* else, return 0.
218
*/
219
int searchAllSourceNames(JNIEnv *env,
220
jclass clazz,
221
char *p1) {
222
int ii;
223
loadDebugInfo(env, clazz);
224
if (!isValid()) {
225
return 0; /* no SDE or not SourceMap */
226
}
227
228
for (ii = 0; ii < stratumIndex - 1; ++ii) {
229
if (searchOneSourceName(ii, p1) == 1) {
230
return 1;
231
}
232
}
233
return 0;
234
}
235
236
/**
237
* Convert a line number table, as returned by the JVMTI
238
* function GetLineNumberTable, to one for another stratum.
239
* Conversion is by overwrite.
240
* Actual line numbers are not returned - just a unique
241
* number (file ID in top 16 bits, line number in
242
* bottom 16 bits) - this is all stepping needs.
243
*/
244
void
245
convertLineNumberTable(JNIEnv *env, jclass clazz,
246
jint *entryCountPtr,
247
jvmtiLineNumberEntry **tablePtr) {
248
jvmtiLineNumberEntry *fromEntry = *tablePtr;
249
jvmtiLineNumberEntry *toEntry = *tablePtr;
250
int cnt = *entryCountPtr;
251
int lastLn = 0;
252
int sti;
253
254
loadDebugInfo(env, clazz);
255
if (!isValid()) {
256
return; /* no SDE or not SourceMap - return unchanged */
257
}
258
sti = stratumTableIndex(globalDefaultStratumId);
259
if (sti == baseStratumIndex) {
260
return; /* Java stratum - return unchanged */
261
}
262
LOG_MISC(("SDE is re-ordering the line table"));
263
for (; cnt-->0; ++fromEntry) {
264
int jplsLine = fromEntry->line_number;
265
int lti = stiLineTableIndex(sti, jplsLine);
266
if (lti >= 0) {
267
int fileId = lineTable[lti].fileId;
268
int ln = stiLineNumber(sti, lti, jplsLine);
269
ln += (fileId << 16); /* create line hash */
270
if (ln != lastLn) {
271
lastLn = ln;
272
toEntry->start_location = fromEntry->start_location;
273
toEntry->line_number = ln;
274
++toEntry;
275
}
276
}
277
}
278
/*LINTED*/
279
*entryCountPtr = (int)(toEntry - *tablePtr);
280
}
281
282
/**
283
* Set back-end wide default stratum ID .
284
*/
285
void
286
setGlobalStratumId(char *id) {
287
globalDefaultStratumId = id;
288
}
289
290
291
private void syntax(String msg) {
292
char buf[200];
293
(void)snprintf(buf, sizeof(buf),
294
"bad SourceDebugExtension syntax - position %d - %s\n",
295
/*LINTED*/
296
(int)(sdePos-sourceDebugExtension),
297
msg);
298
JDI_ASSERT_FAILED(buf);
299
300
longjmp(jmp_buf_env, 1); /* abort parse */
301
}
302
303
private char sdePeek(void) {
304
if (*sdePos == 0) {
305
syntax("unexpected EOF");
306
}
307
return *sdePos;
308
}
309
310
private char sdeRead(void) {
311
if (*sdePos == 0) {
312
syntax("unexpected EOF");
313
}
314
return *sdePos++;
315
}
316
317
private void sdeAdvance(void) {
318
sdePos++;
319
}
320
321
private void assureLineTableSize(void) {
322
if (lineIndex >= lineTableSize) {
323
size_t allocSize;
324
LineTableRecord* new_lineTable;
325
int new_lineTableSize;
326
327
new_lineTableSize = lineTableSize == 0?
328
INIT_SIZE_LINE :
329
lineTableSize * 2;
330
allocSize = new_lineTableSize * (int)sizeof(LineTableRecord);
331
new_lineTable = jvmtiAllocate((jint)allocSize);
332
if ( new_lineTable == NULL ) {
333
EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY, "SDE line table");
334
}
335
if ( lineTable!=NULL ) {
336
(void)memcpy(new_lineTable, lineTable,
337
lineTableSize * (int)sizeof(LineTableRecord));
338
jvmtiDeallocate(lineTable);
339
}
340
lineTable = new_lineTable;
341
lineTableSize = new_lineTableSize;
342
}
343
}
344
345
private void assureFileTableSize(void) {
346
if (fileIndex >= fileTableSize) {
347
size_t allocSize;
348
FileTableRecord* new_fileTable;
349
int new_fileTableSize;
350
351
new_fileTableSize = fileTableSize == 0?
352
INIT_SIZE_FILE :
353
fileTableSize * 2;
354
allocSize = new_fileTableSize * (int)sizeof(FileTableRecord);
355
new_fileTable = jvmtiAllocate((jint)allocSize);
356
if ( new_fileTable == NULL ) {
357
EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY, "SDE file table");
358
}
359
if ( fileTable!=NULL ) {
360
(void)memcpy(new_fileTable, fileTable,
361
fileTableSize * (int)sizeof(FileTableRecord));
362
jvmtiDeallocate(fileTable);
363
}
364
fileTable = new_fileTable;
365
fileTableSize = new_fileTableSize;
366
}
367
}
368
369
private void assureStratumTableSize(void) {
370
if (stratumIndex >= stratumTableSize) {
371
size_t allocSize;
372
StratumTableRecord* new_stratumTable;
373
int new_stratumTableSize;
374
375
new_stratumTableSize = stratumTableSize == 0?
376
INIT_SIZE_STRATUM :
377
stratumTableSize * 2;
378
allocSize = new_stratumTableSize * (int)sizeof(StratumTableRecord);
379
new_stratumTable = jvmtiAllocate((jint)allocSize);
380
if ( new_stratumTable == NULL ) {
381
EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY, "SDE stratum table");
382
}
383
if ( stratumTable!=NULL ) {
384
(void)memcpy(new_stratumTable, stratumTable,
385
stratumTableSize * (int)sizeof(StratumTableRecord));
386
jvmtiDeallocate(stratumTable);
387
}
388
stratumTable = new_stratumTable;
389
stratumTableSize = new_stratumTableSize;
390
}
391
}
392
393
private String readLine(void) {
394
char *initialPos;
395
char ch;
396
397
ignoreWhite();
398
initialPos = sdePos;
399
while (((ch = *sdePos) != '\n') && (ch != '\r')) {
400
if (ch == 0) {
401
syntax("unexpected EOF");
402
}
403
++sdePos;
404
}
405
*sdePos++ = 0; /* null terminate string - mangles SDE */
406
407
/* check for CR LF */
408
if ((ch == '\r') && (*sdePos == '\n')) {
409
++sdePos;
410
}
411
ignoreWhite(); /* leading white */
412
return initialPos;
413
}
414
415
private int defaultStratumTableIndex(void) {
416
if ((defaultStratumIndex == -1) && (defaultStratumId != null)) {
417
defaultStratumIndex =
418
stratumTableIndex(defaultStratumId);
419
}
420
return defaultStratumIndex;
421
}
422
423
private int stratumTableIndex(String stratumId) {
424
int i;
425
426
if (stratumId == null) {
427
return defaultStratumTableIndex();
428
}
429
for (i = 0; i < (stratumIndex-1); ++i) {
430
if (strcmp(stratumTable[i].id, stratumId) == 0) {
431
return i;
432
}
433
}
434
return defaultStratumTableIndex();
435
}
436
437
438
/*****************************
439
* below functions/methods are written to compile under either Java or C
440
*
441
* Needed support functions:
442
* sdePeek()
443
* sdeRead()
444
* sdeAdvance()
445
* readLine()
446
* assureLineTableSize()
447
* assureFileTableSize()
448
* assureStratumTableSize()
449
* syntax(String)
450
*
451
* stratumTableIndex(String)
452
*
453
* Needed support variables:
454
* lineTable
455
* lineIndex
456
* fileTable
457
* fileIndex
458
* currentFileId
459
*
460
* Needed types:
461
* String
462
*
463
* Needed constants:
464
* NullString
465
*/
466
467
private void ignoreWhite(void) {
468
char ch;
469
470
while (((ch = sdePeek()) == ' ') || (ch == '\t')) {
471
sdeAdvance();
472
}
473
}
474
475
private void ignoreLine(void) {
476
char ch;
477
478
do {
479
ch = sdeRead();
480
} while ((ch != '\n') && (ch != '\r'));
481
482
/* check for CR LF */
483
if ((ch == '\r') && (sdePeek() == '\n')) {
484
sdeAdvance();
485
}
486
ignoreWhite(); /* leading white */
487
}
488
489
private int readNumber(void) {
490
int value = 0;
491
char ch;
492
493
ignoreWhite();
494
while (((ch = sdePeek()) >= '0') && (ch <= '9')) {
495
sdeAdvance();
496
value = (value * 10) + ch - '0';
497
}
498
ignoreWhite();
499
return value;
500
}
501
502
private void storeFile(int fileId, String sourceName, String sourcePath) {
503
assureFileTableSize();
504
fileTable[fileIndex].fileId = fileId;
505
fileTable[fileIndex].sourceName = sourceName;
506
fileTable[fileIndex].sourcePath = sourcePath;
507
++fileIndex;
508
}
509
510
private void fileLine(void) {
511
int hasAbsolute = 0; /* acts as boolean */
512
int fileId;
513
String sourceName;
514
String sourcePath = null;
515
516
/* is there an absolute filename? */
517
if (sdePeek() == '+') {
518
sdeAdvance();
519
hasAbsolute = 1;
520
}
521
fileId = readNumber();
522
sourceName = readLine();
523
if (hasAbsolute == 1) {
524
sourcePath = readLine();
525
}
526
storeFile(fileId, sourceName, sourcePath);
527
}
528
529
private void storeLine(int jplsStart, int jplsEnd, int jplsLineInc,
530
int njplsStart, int njplsEnd, int fileId) {
531
assureLineTableSize();
532
lineTable[lineIndex].jplsStart = jplsStart;
533
lineTable[lineIndex].jplsEnd = jplsEnd;
534
lineTable[lineIndex].jplsLineInc = jplsLineInc;
535
lineTable[lineIndex].njplsStart = njplsStart;
536
lineTable[lineIndex].njplsEnd = njplsEnd;
537
lineTable[lineIndex].fileId = fileId;
538
++lineIndex;
539
}
540
541
/**
542
* Parse line translation info. Syntax is
543
* <NJ-start-line> [ # <file-id> ] [ , <line-count> ] :
544
* <J-start-line> [ , <line-increment> ] CR
545
*/
546
private void lineLine(void) {
547
int lineCount = 1;
548
int lineIncrement = 1;
549
int njplsStart;
550
int jplsStart;
551
552
njplsStart = readNumber();
553
554
/* is there a fileID? */
555
if (sdePeek() == '#') {
556
sdeAdvance();
557
currentFileId = readNumber();
558
}
559
560
/* is there a line count? */
561
if (sdePeek() == ',') {
562
sdeAdvance();
563
lineCount = readNumber();
564
}
565
566
if (sdeRead() != ':') {
567
syntax("expected ':'");
568
}
569
jplsStart = readNumber();
570
if (sdePeek() == ',') {
571
sdeAdvance();
572
lineIncrement = readNumber();
573
}
574
ignoreLine(); /* flush the rest */
575
576
storeLine(jplsStart,
577
jplsStart + (lineCount * lineIncrement) -1,
578
lineIncrement,
579
njplsStart,
580
njplsStart + lineCount -1,
581
currentFileId);
582
}
583
584
/**
585
* Until the next stratum section, everything after this
586
* is in stratumId - so, store the current indicies.
587
*/
588
private void storeStratum(String stratumId) {
589
/* remove redundant strata */
590
if (stratumIndex > 0) {
591
if ((stratumTable[stratumIndex-1].fileIndex
592
== fileIndex) &&
593
(stratumTable[stratumIndex-1].lineIndex
594
== lineIndex)) {
595
/* nothing changed overwrite it */
596
--stratumIndex;
597
}
598
}
599
/* store the results */
600
assureStratumTableSize();
601
stratumTable[stratumIndex].id = stratumId;
602
stratumTable[stratumIndex].fileIndex = fileIndex;
603
stratumTable[stratumIndex].lineIndex = lineIndex;
604
++stratumIndex;
605
currentFileId = 0;
606
}
607
608
/**
609
* The beginning of a stratum's info
610
*/
611
private void stratumSection(void) {
612
storeStratum(readLine());
613
}
614
615
private void fileSection(void) {
616
ignoreLine();
617
while (sdePeek() != '*') {
618
fileLine();
619
}
620
}
621
622
private void lineSection(void) {
623
ignoreLine();
624
while (sdePeek() != '*') {
625
lineLine();
626
}
627
}
628
629
/**
630
* Ignore a section we don't know about.
631
*/
632
private void ignoreSection(void) {
633
ignoreLine();
634
while (sdePeek() != '*') {
635
ignoreLine();
636
}
637
}
638
639
/**
640
* A base "Java" stratum is always available, though
641
* it is not in the SourceDebugExtension.
642
* Create the base stratum.
643
*/
644
private void createJavaStratum(void) {
645
baseStratumIndex = stratumIndex;
646
storeStratum(BASE_STRATUM_NAME);
647
storeFile(1, jplsFilename, NullString);
648
/* JPL line numbers cannot exceed 65535 */
649
storeLine(1, 65536, 1, 1, 65536, 1);
650
storeStratum("Aux"); /* in case they don't declare */
651
}
652
653
/**
654
* Decode a SourceDebugExtension which is in SourceMap format.
655
* This is the entry point into the recursive descent parser.
656
*/
657
private void decode(void) {
658
/* check for "SMAP" - allow EOF if not ours */
659
if (strlen(sourceDebugExtension) <= 4 ||
660
(sdeRead() != 'S') ||
661
(sdeRead() != 'M') ||
662
(sdeRead() != 'A') ||
663
(sdeRead() != 'P')) {
664
return; /* not our info */
665
}
666
ignoreLine(); /* flush the rest */
667
jplsFilename = readLine();
668
defaultStratumId = readLine();
669
createJavaStratum();
670
while (true) {
671
if (sdeRead() != '*') {
672
syntax("expected '*'");
673
}
674
switch (sdeRead()) {
675
case 'S':
676
stratumSection();
677
break;
678
case 'F':
679
fileSection();
680
break;
681
case 'L':
682
lineSection();
683
break;
684
case 'E':
685
/* set end points */
686
storeStratum("*terminator*");
687
sourceMapIsValid = true;
688
return;
689
default:
690
ignoreSection();
691
}
692
}
693
}
694
695
/***************** query functions ***********************/
696
697
private int stiLineTableIndex(int sti, int jplsLine) {
698
int i;
699
int lineIndexStart;
700
int lineIndexEnd;
701
702
lineIndexStart = stratumTable[sti].lineIndex;
703
/* one past end */
704
lineIndexEnd = stratumTable[sti+1].lineIndex;
705
for (i = lineIndexStart; i < lineIndexEnd; ++i) {
706
if ((jplsLine >= lineTable[i].jplsStart) &&
707
(jplsLine <= lineTable[i].jplsEnd)) {
708
return i;
709
}
710
}
711
return -1;
712
}
713
714
private int stiLineNumber(int sti, int lti, int jplsLine) {
715
return lineTable[lti].njplsStart +
716
(((jplsLine - lineTable[lti].jplsStart) /
717
lineTable[lti].jplsLineInc));
718
}
719
720
private int fileTableIndex(int sti, int fileId) {
721
int i;
722
int fileIndexStart = stratumTable[sti].fileIndex;
723
/* one past end */
724
int fileIndexEnd = stratumTable[sti+1].fileIndex;
725
for (i = fileIndexStart; i < fileIndexEnd; ++i) {
726
if (fileTable[i].fileId == fileId) {
727
return i;
728
}
729
}
730
return -1;
731
}
732
733
private int stiFileTableIndex(int sti, int lti) {
734
return fileTableIndex(sti, lineTable[lti].fileId);
735
}
736
737
private jboolean isValid(void) {
738
return sourceMapIsValid;
739
}
740
741