|
Java example source code file (SDE.c)
The SDE.c Java example source code/* * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ #include <setjmp.h> #include "util.h" #include "SDE.h" #ifdef __APPLE__ /* use setjmp/longjmp versions that do not save/restore the signal mask */ #define setjmp _setjmp #define longjmp _longjmp #endif /** * This SourceDebugExtension code does not * allow concurrent translation - due to caching method. * A separate thread setting the default stratum ID * is, however, fine. */ #define INIT_SIZE_FILE 10 #define INIT_SIZE_LINE 100 #define INIT_SIZE_STRATUM 3 #define BASE_STRATUM_NAME "Java" #define null NULL #define true JNI_TRUE #define false JNI_FALSE #define String char * #define private static typedef struct { int fileId; String sourceName; String sourcePath; // do not read - use accessor int isConverted; } FileTableRecord; typedef struct { int jplsStart; int jplsEnd; int jplsLineInc; int njplsStart; int njplsEnd; int fileId; } LineTableRecord; typedef struct { String id; int fileIndex; int lineIndex; } StratumTableRecord; /* back-end wide value for default stratum */ private String globalDefaultStratumId = null; /* reference type default */ private String defaultStratumId = null; private jclass cachedClass = NULL; private FileTableRecord* fileTable; private LineTableRecord* lineTable; private StratumTableRecord* stratumTable; private int fileTableSize; private int lineTableSize; private int stratumTableSize; private int fileIndex; private int lineIndex; private int stratumIndex = 0; private int currentFileId; private int defaultStratumIndex; private int baseStratumIndex; private char* sdePos; private char* jplsFilename = null; private char* NullString = null; /* mangled in parse, cannot be parsed. Must be kept. */ private String sourceDebugExtension; private jboolean sourceMapIsValid; private jmp_buf jmp_buf_env; private int stratumTableIndex(String stratumId); private int stiLineTableIndex(int sti, int jplsLine); private int stiLineNumber(int sti, int lti, int jplsLine); private void decode(void); private void ignoreWhite(void); private jboolean isValid(void); private void loadDebugInfo(JNIEnv *env, jclass clazz) { if (!isSameObject(env, clazz, cachedClass)) { /* Not the same - swap out the info */ /* Delete existing info */ if ( cachedClass != null ) { tossGlobalRef(env, &cachedClass); cachedClass = null; } if ( sourceDebugExtension!=null ) { jvmtiDeallocate(sourceDebugExtension); } sourceDebugExtension = null; /* Init info */ lineTable = null; fileTable = null; stratumTable = null; lineTableSize = 0; fileTableSize = 0; stratumTableSize = 0; fileIndex = 0; lineIndex = 0; stratumIndex = 0; currentFileId = 0; defaultStratumId = null; defaultStratumIndex = -1; baseStratumIndex = -2; /* so as not to match -1 above */ sourceMapIsValid = false; if (getSourceDebugExtension(clazz, &sourceDebugExtension) == JVMTI_ERROR_NONE) { sdePos = sourceDebugExtension; if (setjmp(jmp_buf_env) == 0) { /* this is the initial (non-error) case, do parse */ decode(); } } cachedClass = null; saveGlobalRef(env, clazz, &cachedClass); } } /* Return 1 if match, 0 if no match */ private int patternMatch(char *classname, const char *pattern) { int pattLen; int compLen; char *start; int offset; if (pattern == NULL || classname == NULL) { return 0; } pattLen = (int)strlen(pattern); if ((pattern[0] != '*') && (pattern[pattLen-1] != '*')) { return strcmp(pattern, classname) == 0; } compLen = pattLen - 1; offset = (int)strlen(classname) - compLen; if (offset < 0) { return 0; } if (pattern[0] == '*') { pattern++; start = classname + offset; } else { start = classname; } return strncmp(pattern, start, compLen) == 0; } /** * Return 1 if p1 is a SourceName for stratum sti, * else, return 0. */ private int searchOneSourceName(int sti, char *p1) { int fileIndexStart = stratumTable[sti].fileIndex; /* one past end */ int fileIndexEnd = stratumTable[sti+1].fileIndex; int ii; for (ii = fileIndexStart; ii < fileIndexEnd; ++ii) { if (patternMatch(fileTable[ii].sourceName, p1)) { return 1; } } return 0; } /** * Return 1 if p1 is a SourceName for any stratum * else, return 0. */ int searchAllSourceNames(JNIEnv *env, jclass clazz, char *p1) { int ii; loadDebugInfo(env, clazz); if (!isValid()) { return 0; /* no SDE or not SourceMap */ } for (ii = 0; ii < stratumIndex - 1; ++ii) { if (searchOneSourceName(ii, p1) == 1) { return 1; } } return 0; } /** * Convert a line number table, as returned by the JVMTI * function GetLineNumberTable, to one for another stratum. * Conversion is by overwrite. * Actual line numbers are not returned - just a unique * number (file ID in top 16 bits, line number in * bottom 16 bits) - this is all stepping needs. */ void convertLineNumberTable(JNIEnv *env, jclass clazz, jint *entryCountPtr, jvmtiLineNumberEntry **tablePtr) { jvmtiLineNumberEntry *fromEntry = *tablePtr; jvmtiLineNumberEntry *toEntry = *tablePtr; int cnt = *entryCountPtr; int lastLn = 0; int sti; loadDebugInfo(env, clazz); if (!isValid()) { return; /* no SDE or not SourceMap - return unchanged */ } sti = stratumTableIndex(globalDefaultStratumId); if (sti == baseStratumIndex) { return; /* Java stratum - return unchanged */ } LOG_MISC(("SDE is re-ordering the line table")); for (; cnt-->0; ++fromEntry) { int jplsLine = fromEntry->line_number; int lti = stiLineTableIndex(sti, jplsLine); if (lti >= 0) { int fileId = lineTable[lti].fileId; int ln = stiLineNumber(sti, lti, jplsLine); ln += (fileId << 16); /* create line hash */ if (ln != lastLn) { lastLn = ln; toEntry->start_location = fromEntry->start_location; toEntry->line_number = ln; ++toEntry; } } } /*LINTED*/ *entryCountPtr = (int)(toEntry - *tablePtr); } /** * Set back-end wide default stratum ID . */ void setGlobalStratumId(char *id) { globalDefaultStratumId = id; } private void syntax(String msg) { char buf[200]; (void)snprintf(buf, sizeof(buf), "bad SourceDebugExtension syntax - position %d - %s\n", /*LINTED*/ (int)(sdePos-sourceDebugExtension), msg); JDI_ASSERT_FAILED(buf); longjmp(jmp_buf_env, 1); /* abort parse */ } private char sdePeek(void) { if (*sdePos == 0) { syntax("unexpected EOF"); } return *sdePos; } private char sdeRead(void) { if (*sdePos == 0) { syntax("unexpected EOF"); } return *sdePos++; } private void sdeAdvance(void) { sdePos++; } private void assureLineTableSize(void) { if (lineIndex >= lineTableSize) { size_t allocSize; LineTableRecord* new_lineTable; int new_lineTableSize; new_lineTableSize = lineTableSize == 0? INIT_SIZE_LINE : lineTableSize * 2; allocSize = new_lineTableSize * (int)sizeof(LineTableRecord); new_lineTable = jvmtiAllocate((jint)allocSize); if ( new_lineTable == NULL ) { EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY, "SDE line table"); } if ( lineTable!=NULL ) { (void)memcpy(new_lineTable, lineTable, lineTableSize * (int)sizeof(LineTableRecord)); jvmtiDeallocate(lineTable); } lineTable = new_lineTable; lineTableSize = new_lineTableSize; } } private void assureFileTableSize(void) { if (fileIndex >= fileTableSize) { size_t allocSize; FileTableRecord* new_fileTable; int new_fileTableSize; new_fileTableSize = fileTableSize == 0? INIT_SIZE_FILE : fileTableSize * 2; allocSize = new_fileTableSize * (int)sizeof(FileTableRecord); new_fileTable = jvmtiAllocate((jint)allocSize); if ( new_fileTable == NULL ) { EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY, "SDE file table"); } if ( fileTable!=NULL ) { (void)memcpy(new_fileTable, fileTable, fileTableSize * (int)sizeof(FileTableRecord)); jvmtiDeallocate(fileTable); } fileTable = new_fileTable; fileTableSize = new_fileTableSize; } } private void assureStratumTableSize(void) { if (stratumIndex >= stratumTableSize) { size_t allocSize; StratumTableRecord* new_stratumTable; int new_stratumTableSize; new_stratumTableSize = stratumTableSize == 0? INIT_SIZE_STRATUM : stratumTableSize * 2; allocSize = new_stratumTableSize * (int)sizeof(StratumTableRecord); new_stratumTable = jvmtiAllocate((jint)allocSize); if ( new_stratumTable == NULL ) { EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY, "SDE stratum table"); } if ( stratumTable!=NULL ) { (void)memcpy(new_stratumTable, stratumTable, stratumTableSize * (int)sizeof(StratumTableRecord)); jvmtiDeallocate(stratumTable); } stratumTable = new_stratumTable; stratumTableSize = new_stratumTableSize; } } private String readLine(void) { char *initialPos; char ch; ignoreWhite(); initialPos = sdePos; while (((ch = *sdePos) != '\n') && (ch != '\r')) { if (ch == 0) { syntax("unexpected EOF"); } ++sdePos; } *sdePos++ = 0; /* null terminate string - mangles SDE */ /* check for CR LF */ if ((ch == '\r') && (*sdePos == '\n')) { ++sdePos; } ignoreWhite(); /* leading white */ return initialPos; } private int defaultStratumTableIndex(void) { if ((defaultStratumIndex == -1) && (defaultStratumId != null)) { defaultStratumIndex = stratumTableIndex(defaultStratumId); } return defaultStratumIndex; } private int stratumTableIndex(String stratumId) { int i; if (stratumId == null) { return defaultStratumTableIndex(); } for (i = 0; i < (stratumIndex-1); ++i) { if (strcmp(stratumTable[i].id, stratumId) == 0) { return i; } } return defaultStratumTableIndex(); } /***************************** * below functions/methods are written to compile under either Java or C * * Needed support functions: * sdePeek() * sdeRead() * sdeAdvance() * readLine() * assureLineTableSize() * assureFileTableSize() * assureStratumTableSize() * syntax(String) * * stratumTableIndex(String) * * Needed support variables: * lineTable * lineIndex * fileTable * fileIndex * currentFileId * * Needed types: * String * * Needed constants: * NullString */ private void ignoreWhite(void) { char ch; while (((ch = sdePeek()) == ' ') || (ch == '\t')) { sdeAdvance(); } } private void ignoreLine(void) { char ch; do { ch = sdeRead(); } while ((ch != '\n') && (ch != '\r')); /* check for CR LF */ if ((ch == '\r') && (sdePeek() == '\n')) { sdeAdvance(); } ignoreWhite(); /* leading white */ } private int readNumber(void) { int value = 0; char ch; ignoreWhite(); while (((ch = sdePeek()) >= '0') && (ch <= '9')) { sdeAdvance(); value = (value * 10) + ch - '0'; } ignoreWhite(); return value; } private void storeFile(int fileId, String sourceName, String sourcePath) { assureFileTableSize(); fileTable[fileIndex].fileId = fileId; fileTable[fileIndex].sourceName = sourceName; fileTable[fileIndex].sourcePath = sourcePath; ++fileIndex; } private void fileLine(void) { int hasAbsolute = 0; /* acts as boolean */ int fileId; String sourceName; String sourcePath = null; /* is there an absolute filename? */ if (sdePeek() == '+') { sdeAdvance(); hasAbsolute = 1; } fileId = readNumber(); sourceName = readLine(); if (hasAbsolute == 1) { sourcePath = readLine(); } storeFile(fileId, sourceName, sourcePath); } private void storeLine(int jplsStart, int jplsEnd, int jplsLineInc, int njplsStart, int njplsEnd, int fileId) { assureLineTableSize(); lineTable[lineIndex].jplsStart = jplsStart; lineTable[lineIndex].jplsEnd = jplsEnd; lineTable[lineIndex].jplsLineInc = jplsLineInc; lineTable[lineIndex].njplsStart = njplsStart; lineTable[lineIndex].njplsEnd = njplsEnd; lineTable[lineIndex].fileId = fileId; ++lineIndex; } /** * Parse line translation info. Syntax is * <NJ-start-line> [ # Other Java examples (source code examples)Here is a short list of links related to this Java SDE.c source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.