diff --git a/make/linux/adlc_updater b/make/linux/adlc_updater index 6a97b79931dd7138ff2eeecf54b49a67744730a6..b54f783d6eec6073d943ec2e8fe45df0d8b2d4bb 100644 --- a/make/linux/adlc_updater +++ b/make/linux/adlc_updater @@ -7,5 +7,13 @@ # # adlc-updater # -[ -f $3/$1 ] && cmp -s $2/$1 $3/$1 || \ -( [ -f $3/$1 ]; echo Updating $3/$1 ; touch $2/made-change ; mv $2/$1 $3/$1 ) +fix_lines() { + # repair bare #line directives in $1 to refer to $2 + awk < $1 > $1+ ' + /^#line 999999$/ {print "#line " (NR+1) " \"" F2 "\""; next} + {print} + ' F2=$2 + mv $1+ $1 +} +[ -f $3/$1 ] && (fix_lines $2/$1 $3/$1; cmp -s $2/$1 $3/$1) || \ +( [ -f $3/$1 ] && echo Updating $3/$1 ; touch $2/made-change ; mv $2/$1 $3/$1 ) diff --git a/make/linux/makefiles/adlc.make b/make/linux/makefiles/adlc.make index 5349f5bd323fd920a2c240f7e70115d72875df16..5e48fed156775203c7b806b296c2ed791994ad45 100644 --- a/make/linux/makefiles/adlc.make +++ b/make/linux/makefiles/adlc.make @@ -54,10 +54,12 @@ VPATH += $(Src_Dirs_V:%=%:) Src_Dirs_I = ${Src_Dirs} $(GENERATED) INCLUDES += $(Src_Dirs_I:%=-I%) -# Force assertions on. -SYSDEFS += -DASSERT +# set flags for adlc compilation CPPFLAGS = $(SYSDEFS) $(INCLUDES) +# Force assertions on. +CPPFLAGS += -DASSERT + # CFLAGS_WARN holds compiler options to suppress/enable warnings. # Suppress warnings (for now) CFLAGS_WARN = -w @@ -125,7 +127,15 @@ $(GENERATEDFILES): refresh_adfiles # Note that product files are updated via "mv", which is atomic. TEMPDIR := $(OUTDIR)/mktmp$(shell echo $$$$) -ADLCFLAGS = -q -T +# Pass -D flags into ADLC. +ADLCFLAGS += $(SYSDEFS) + +# Note "+="; it is a hook so flags.make can add more flags, like -g or -DFOO. +ADLCFLAGS += -q -T + +# Normally, debugging is done directly on the ad_*.cpp files. +# But -g will put #line directives in those files pointing back to .ad. +#ADLCFLAGS += -g ifdef LP64 ADLCFLAGS += -D_LP64 @@ -140,6 +150,8 @@ endif # ADLC_UPDATER_DIRECTORY = $(GAMMADIR)/make/$(OS) ADLC_UPDATER = adlc_updater +$(ADLC_UPDATER): $(ADLC_UPDATER_DIRECTORY)/$(ADLC_UPDATER) + $(QUIETLY) cp $< $@; chmod +x $@ # This action refreshes all generated adlc files simultaneously. # The way it works is this: @@ -149,9 +161,8 @@ ADLC_UPDATER = adlc_updater # 4) call $(ADLC_UPDATER) on each generated adlc file. It will selectively update changed or missing files. # 5) If we actually updated any files, echo a notice. # -refresh_adfiles: $(EXEC) $(SOURCE.AD) +refresh_adfiles: $(EXEC) $(SOURCE.AD) $(ADLC_UPDATER) @rm -rf $(TEMPDIR); mkdir $(TEMPDIR) - $(QUIETLY) [ -f $(ADLC_UPDATER) ] || ( cp $(ADLC_UPDATER_DIRECTORY)/$(ADLC_UPDATER) . ; chmod +x $(ADLC_UPDATER) ) $(QUIETLY) $(EXEC) $(ADLCFLAGS) $(SOURCE.AD) \ -c$(TEMPDIR)/ad_$(Platform_arch_model).cpp -h$(TEMPDIR)/ad_$(Platform_arch_model).hpp -a$(TEMPDIR)/dfa_$(Platform_arch_model).cpp -v$(TEMPDIR)/adGlobals_$(Platform_arch_model).hpp \ || { rm -rf $(TEMPDIR); exit 1; } @@ -174,7 +185,15 @@ refresh_adfiles: $(EXEC) $(SOURCE.AD) # ######################################################################### $(SOURCE.AD): $(SOURCES.AD) - $(QUIETLY) cat $(SOURCES.AD) > $(SOURCE.AD) + $(QUIETLY) $(PROCESS_AD_FILES) $(SOURCES.AD) > $(SOURCE.AD) + +#PROCESS_AD_FILES = cat +# Pass through #line directives, in case user enables -g option above: +PROCESS_AD_FILES = awk '{ \ + if (CUR_FN != FILENAME) { CUR_FN=FILENAME; NR_BASE=NR-1; need_lineno=1 } \ + if (need_lineno && $$0 !~ /\/\//) \ + { print "\n\n\#line " (NR-NR_BASE) " \"" FILENAME "\""; need_lineno=0 }; \ + print }' $(OUTDIR)/%.o: %.cpp @echo Compiling $< diff --git a/make/solaris/adlc_updater b/make/solaris/adlc_updater index 6a97b79931dd7138ff2eeecf54b49a67744730a6..b54f783d6eec6073d943ec2e8fe45df0d8b2d4bb 100644 --- a/make/solaris/adlc_updater +++ b/make/solaris/adlc_updater @@ -7,5 +7,13 @@ # # adlc-updater # -[ -f $3/$1 ] && cmp -s $2/$1 $3/$1 || \ -( [ -f $3/$1 ]; echo Updating $3/$1 ; touch $2/made-change ; mv $2/$1 $3/$1 ) +fix_lines() { + # repair bare #line directives in $1 to refer to $2 + awk < $1 > $1+ ' + /^#line 999999$/ {print "#line " (NR+1) " \"" F2 "\""; next} + {print} + ' F2=$2 + mv $1+ $1 +} +[ -f $3/$1 ] && (fix_lines $2/$1 $3/$1; cmp -s $2/$1 $3/$1) || \ +( [ -f $3/$1 ] && echo Updating $3/$1 ; touch $2/made-change ; mv $2/$1 $3/$1 ) diff --git a/make/solaris/makefiles/adlc.make b/make/solaris/makefiles/adlc.make index f746d77494d8da824c59b531041592d30fb1028d..2d1a87a20b4e891d329d39880aaed468b2f58ddf 100644 --- a/make/solaris/makefiles/adlc.make +++ b/make/solaris/makefiles/adlc.make @@ -54,10 +54,12 @@ VPATH += $(Src_Dirs_V:%=%:) Src_Dirs_I = ${Src_Dirs} $(GENERATED) INCLUDES += $(Src_Dirs_I:%=-I%) -# Force assertions on. -SYSDEFS += -DASSERT +# set flags for adlc compilation CPPFLAGS = $(SYSDEFS) $(INCLUDES) +# Force assertions on. +CPPFLAGS += -DASSERT + ifndef USE_GCC # We need libCstd.so for adlc CFLAGS += -library=Cstd -g @@ -141,7 +143,15 @@ $(GENERATEDFILES): refresh_adfiles # Note that product files are updated via "mv", which is atomic. TEMPDIR := $(OUTDIR)/mktmp$(shell echo $$$$) -ADLCFLAGS = -q -T +# Pass -D flags into ADLC. +ADLCFLAGS += $(SYSDEFS) + +# Note "+="; it is a hook so flags.make can add more flags, like -g or -DFOO. +ADLCFLAGS += -q -T + +# Normally, debugging is done directly on the ad_*.cpp files. +# But -g will put #line directives in those files pointing back to .ad. +#ADLCFLAGS += -g ifdef LP64 ADLCFLAGS += -D_LP64 @@ -156,6 +166,8 @@ endif # ADLC_UPDATER_DIRECTORY = $(GAMMADIR)/make/$(OS) ADLC_UPDATER = adlc_updater +$(ADLC_UPDATER): $(ADLC_UPDATER_DIRECTORY)/$(ADLC_UPDATER) + $(QUIETLY) cp $< $@; chmod +x $@ # This action refreshes all generated adlc files simultaneously. # The way it works is this: @@ -165,9 +177,8 @@ ADLC_UPDATER = adlc_updater # 4) call $(ADLC_UPDATER) on each generated adlc file. It will selectively update changed or missing files. # 5) If we actually updated any files, echo a notice. # -refresh_adfiles: $(EXEC) $(SOURCE.AD) +refresh_adfiles: $(EXEC) $(SOURCE.AD) $(ADLC_UPDATER) @rm -rf $(TEMPDIR); mkdir $(TEMPDIR) - $(QUIETLY) [ -f $(ADLC_UPDATER) ] || ( cp $(ADLC_UPDATER_DIRECTORY)/$(ADLC_UPDATER) . ; chmod +x $(ADLC_UPDATER) ) $(QUIETLY) $(EXEC) $(ADLCFLAGS) $(SOURCE.AD) \ -c$(TEMPDIR)/ad_$(Platform_arch_model).cpp -h$(TEMPDIR)/ad_$(Platform_arch_model).hpp -a$(TEMPDIR)/dfa_$(Platform_arch_model).cpp -v$(TEMPDIR)/adGlobals_$(Platform_arch_model).hpp \ || { rm -rf $(TEMPDIR); exit 1; } @@ -190,7 +201,15 @@ refresh_adfiles: $(EXEC) $(SOURCE.AD) # ######################################################################### $(SOURCE.AD): $(SOURCES.AD) - $(QUIETLY) cat $(SOURCES.AD) > $(SOURCE.AD) + $(QUIETLY) $(PROCESS_AD_FILES) $(SOURCES.AD) > $(SOURCE.AD) + +#PROCESS_AD_FILES = cat +# Pass through #line directives, in case user enables -g option above: +PROCESS_AD_FILES = awk '{ \ + if (CUR_FN != FILENAME) { CUR_FN=FILENAME; NR_BASE=NR-1; need_lineno=1 } \ + if (need_lineno && $$0 !~ /\/\//) \ + { print "\n\n\#line " (NR-NR_BASE) " \"" FILENAME "\""; need_lineno=0 }; \ + print }' $(OUTDIR)/%.o: %.cpp @echo Compiling $< diff --git a/src/share/vm/adlc/adlparse.cpp b/src/share/vm/adlc/adlparse.cpp index c266df104c8021bc6385c02582f8c833fd63a32f..cc02b5d3177409f60f93120f4b83d8e11e1773c3 100644 --- a/src/share/vm/adlc/adlparse.cpp +++ b/src/share/vm/adlc/adlparse.cpp @@ -108,6 +108,7 @@ void ADLParser::parse() { else if (!strcmp(ident, "pipeline")) pipe_parse(); else if (!strcmp(ident, "definitions")) definitions_parse(); else if (!strcmp(ident, "peephole")) peep_parse(); + else if (!strcmp(ident, "#line")) preproc_line(); else if (!strcmp(ident, "#define")) preproc_define(); else if (!strcmp(ident, "#undef")) preproc_undef(); else { @@ -786,9 +787,11 @@ void ADLParser::reg_parse(void) { parse_err(SYNERR, "missing identifier inside register block.\n"); return; } - if (strcmp(token,"reg_def")==0) { reg_def_parse(); } - if (strcmp(token,"reg_class")==0) { reg_class_parse(); } - if (strcmp(token,"alloc_class")==0) { alloc_class_parse(); } + if (strcmp(token,"reg_def")==0) { reg_def_parse(); } + else if (strcmp(token,"reg_class")==0) { reg_class_parse(); } + else if (strcmp(token,"alloc_class")==0) { alloc_class_parse(); } + else if (strcmp(token,"#define")==0) { preproc_define(); } + else { parse_err(SYNERR, "bad token %s inside register block.\n", token); break; } skipws(); } } @@ -903,11 +906,7 @@ void ADLParser::enc_class_parse_block(EncClass* encoding, char* ec_name) { skipws_no_preproc(); // Skip leading whitespace // Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block if (_AD._adlocation_debug) { - const char* file = _AD._ADL_file._name; - int line = linenum(); - char* location = (char *)malloc(strlen(file) + 100); - sprintf(location, "#line %d \"%s\"\n", line, file); - encoding->add_code(location); + encoding->add_code(get_line_string()); } // Collect the parts of the encode description @@ -948,6 +947,10 @@ void ADLParser::enc_class_parse_block(EncClass* encoding, char* ec_name) { skipws(); + if (_AD._adlocation_debug) { + encoding->add_code(end_line_marker()); + } + // Debug Stuff if (_AD._adl_debug > 1) fprintf(stderr,"EncodingClass Form: %s\n", ec_name); } @@ -2349,7 +2352,11 @@ void ADLParser::reg_class_parse(void) { return; } RegDef *regDef = _AD._register->getRegDef(rname); - reg_class->addReg(regDef); // add regDef to regClass + if (!regDef) { + parse_err(SEMERR, "unknown identifier %s inside reg_class list.\n", rname); + } else { + reg_class->addReg(regDef); // add regDef to regClass + } // Check for ',' and position to next token. skipws(); @@ -2746,7 +2753,8 @@ Predicate *ADLParser::pred_parse(void) { char *rule = NULL; // String representation of predicate skipws(); // Skip leading whitespace - if ( (rule = get_paren_expr("pred expression")) == NULL ) { + int line = linenum(); + if ( (rule = get_paren_expr("pred expression", true)) == NULL ) { parse_err(SYNERR, "incorrect or missing expression for 'predicate'\n"); return NULL; } @@ -3407,7 +3415,12 @@ FormatRule* ADLParser::format_parse(void) { // Check if there is a string to pass through to output char *start = _ptr; // Record start of the next string while ((_curchar != '$') && (_curchar != '"') && (_curchar != '%') && (_curchar != '\n')) { - if (_curchar == '\\') next_char(); // superquote + if (_curchar == '\\') { + next_char(); // superquote + if ((_curchar == '$') || (_curchar == '%')) + // hack to avoid % escapes and warnings about undefined \ escapes + *(_ptr-1) = _curchar; + } if (_curchar == '\n') parse_err(SYNERR, "newline in string"); // unimplemented! next_char(); } @@ -3942,8 +3955,7 @@ char* ADLParser::find_cpp_block(const char* description) { next_char(); // Skip block delimiter skipws_no_preproc(); // Skip leading whitespace cppBlock = _ptr; // Point to start of expression - const char* file = _AD._ADL_file._name; - int line = linenum(); + int line = linenum(); next = _ptr + 1; while(((_curchar != '%') || (*next != '}')) && (_curchar != '\0')) { next_char_or_line(); @@ -3958,15 +3970,16 @@ char* ADLParser::find_cpp_block(const char* description) { _curchar = *_ptr; // Maintain invariant // Prepend location descriptor, for debugging. - char* location = (char *)malloc(strlen(file) + 100); - *location = '\0'; - if (_AD._adlocation_debug) - sprintf(location, "#line %d \"%s\"\n", line, file); - char* result = (char *)malloc(strlen(location) + strlen(cppBlock) + 1); - strcpy(result, location); - strcat(result, cppBlock); - cppBlock = result; - free(location); + if (_AD._adlocation_debug) { + char* location = get_line_string(line); + char* end_loc = end_line_marker(); + char* result = (char *)malloc(strlen(location) + strlen(cppBlock) + strlen(end_loc) + 1); + strcpy(result, location); + strcat(result, cppBlock); + strcat(result, end_loc); + cppBlock = result; + free(location); + } } return cppBlock; @@ -4036,13 +4049,26 @@ char* ADLParser::get_expr(const char *desc, const char *stop_chars) { // Helper function around get_expr // Sets _curchar to '(' so that get_paren_expr will search for a matching ')' -char *ADLParser::get_paren_expr(const char *description) { +char *ADLParser::get_paren_expr(const char *description, bool include_location) { + int line = linenum(); if (_curchar != '(') // Escape if not valid starting position return NULL; next_char(); // Skip the required initial paren. char *token2 = get_expr(description, ")"); if (_curchar == ')') next_char(); // Skip required final paren. + int junk = 0; + if (include_location && _AD._adlocation_debug && !is_int_token(token2, junk)) { + // Prepend location descriptor, for debugging. + char* location = get_line_string(line); + char* end_loc = end_line_marker(); + char* result = (char *)malloc(strlen(location) + strlen(token2) + strlen(end_loc) + 1); + strcpy(result, location); + strcat(result, token2); + strcat(result, end_loc); + token2 = result; + free(location); + } return token2; } @@ -4082,10 +4108,16 @@ char *ADLParser::get_ident_common(bool do_preproc) { if (do_preproc && start != NULL) { const char* def = _AD.get_preproc_def(start); if (def != NULL && strcmp(def, start)) { - const char* def2 = _AD.get_preproc_def(def); - if (def2 != NULL && strcmp(def2, def)) { - parse_err(SYNERR, "unimplemented: using %s defined as %s => %s", - start, def, def2); + const char* def1 = def; + const char* def2 = _AD.get_preproc_def(def1); + // implement up to 2 levels of #define + if (def2 != NULL && strcmp(def2, def1)) { + def = def2; + const char* def3 = _AD.get_preproc_def(def2); + if (def3 != NULL && strcmp(def3, def2) && strcmp(def3, def1)) { + parse_err(SYNERR, "unimplemented: using %s defined as %s => %s => %s", + start, def1, def2, def3); + } } start = strdup(def); } @@ -4431,6 +4463,35 @@ void ADLParser::get_effectlist(FormDict &effects, FormDict &operands) { } +//-------------------------------preproc_line---------------------------------- +// A "#line" keyword has been seen, so parse the rest of the line. +void ADLParser::preproc_line(void) { + int line = get_int(); + skipws_no_preproc(); + const char* file = NULL; + if (_curchar == '"') { + next_char(); // Move past the initial '"' + file = _ptr; + while (true) { + if (_curchar == '\n') { + parse_err(SYNERR, "missing '\"' at end of #line directive"); + return; + } + if (_curchar == '"') { + *_ptr = '\0'; // Terminate the string + next_char(); + skipws_no_preproc(); + break; + } + next_char(); + } + } + ensure_end_of_line(); + if (file != NULL) + _AD._ADL_file._name = file; + _buf.set_linenum(line); +} + //------------------------------preproc_define--------------------------------- // A "#define" keyword has been seen, so parse the rest of the line. void ADLParser::preproc_define(void) { @@ -4494,6 +4555,7 @@ void ADLParser::parse_err(int flag, const char *fmt, ...) { // A preprocessor directive has been encountered. Be sure it has fallen at // the begining of a line, or else report an error. void ADLParser::ensure_start_of_line(void) { + if (_curchar == '\n') { next_line(); return; } assert( _ptr >= _curline && _ptr < _curline+strlen(_curline), "Must be able to find which line we are in" ); @@ -4662,6 +4724,7 @@ char ADLParser::cur_char() { //---------------------------next_char----------------------------------------- void ADLParser::next_char() { + if (_curchar == '\n') parse_err(WARN, "must call next_line!"); _curchar = *++_ptr; // if ( _curchar == '\n' ) { // next_line(); @@ -4682,6 +4745,18 @@ void ADLParser::next_char_or_line() { //---------------------------next_line----------------------------------------- void ADLParser::next_line() { _curline = _buf.get_line(); + _curchar = ' '; +} + +//------------------------get_line_string-------------------------------------- +// Prepended location descriptor, for debugging. +// Must return a malloced string (that can be freed if desired). +char* ADLParser::get_line_string(int linenum) { + const char* file = _AD._ADL_file._name; + int line = linenum ? linenum : this->linenum(); + char* location = (char *)malloc(strlen(file) + 100); + sprintf(location, "\n#line %d \"%s\"\n", line, file); + return location; } //-------------------------is_literal_constant--------------------------------- @@ -4722,6 +4797,66 @@ bool ADLParser::is_int_token(const char* token, int& intval) { return true; } +static const char* skip_expr_ws(const char* str) { + const char * cp = str; + while (cp[0]) { + if (cp[0] <= ' ') { + ++cp; + } else if (cp[0] == '#') { + ++cp; + while (cp[0] == ' ') ++cp; + assert(0 == strncmp(cp, "line", 4), "must be a #line directive"); + const char* eol = strchr(cp, '\n'); + assert(eol != NULL, "must find end of line"); + if (eol == NULL) eol = cp + strlen(cp); + cp = eol; + } else { + break; + } + } + return cp; +} + +//-----------------------equivalent_expressions-------------------------------- +bool ADLParser::equivalent_expressions(const char* str1, const char* str2) { + if (str1 == str2) + return true; + else if (str1 == NULL || str2 == NULL) + return false; + const char* cp1 = str1; + const char* cp2 = str2; + char in_quote = '\0'; + while (cp1[0] && cp2[0]) { + if (!in_quote) { + // skip spaces and/or cpp directives + const char* cp1a = skip_expr_ws(cp1); + const char* cp2a = skip_expr_ws(cp2); + if (cp1a > cp1 && cp2a > cp2) { + cp1 = cp1a; cp2 = cp2a; + continue; + } + if (cp1a > cp1 || cp2a > cp2) break; // fail + } + // match one non-space char + if (cp1[0] != cp2[0]) break; // fail + char ch = cp1[0]; + cp1++; cp2++; + // watch for quotes + if (in_quote && ch == '\\') { + if (cp1[0] != cp2[0]) break; // fail + if (!cp1[0]) break; + cp1++; cp2++; + } + if (in_quote && ch == in_quote) { + in_quote = '\0'; + } else if (!in_quote && (ch == '"' || ch == '\'')) { + in_quote = ch; + } + } + return (!cp1[0] && !cp2[0]); +} + + //-------------------------------trim------------------------------------------ void ADLParser::trim(char* &token) { while (*token <= ' ') token++; diff --git a/src/share/vm/adlc/adlparse.hpp b/src/share/vm/adlc/adlparse.hpp index 42329ac279e7bfda9454bc1cdb28e7be8fdaf23b..22aa772d0e9317030140689b6959794f7fe00e0f 100644 --- a/src/share/vm/adlc/adlparse.hpp +++ b/src/share/vm/adlc/adlparse.hpp @@ -93,6 +93,7 @@ protected: void pipe_parse(void); // Parse pipeline section void definitions_parse(void); // Parse definitions section void peep_parse(void); // Parse peephole rule definitions + void preproc_line(void); // Parse a #line statement void preproc_define(void); // Parse a #define statement void preproc_undef(void); // Parse an #undef statement @@ -226,7 +227,7 @@ protected: void get_effectlist(FormDict &effects, FormDict &operands); // Parse effect-operand pairs // Return the contents of a parenthesized expression. // Requires initial '(' and consumes final ')', which is replaced by '\0'. - char *get_paren_expr(const char *description); + char *get_paren_expr(const char *description, bool include_location = false); // Return expression up to next stop-char, which terminator replaces. // Does not require initial '('. Does not consume final stop-char. // Final stop-char is left in _curchar, but is also is replaced by '\0'. @@ -234,6 +235,11 @@ protected: char *find_cpp_block(const char *description); // Parse a C++ code block // Issue parser error message & go to EOL void parse_err(int flag, const char *fmt, ...); + // Create a location marker for this file and line. + char *get_line_string(int linenum = 0); + // Return a location marker which tells the C preprocessor to + // forget the previous location marker. (Requires awk postprocessing.) + char *end_line_marker() { return (char*)"\n#line 999999\n"; } // Return pointer to current character inline char cur_char(void); @@ -268,5 +274,6 @@ public: static bool is_literal_constant(const char *hex_string); static bool is_hex_digit(char digit); static bool is_int_token(const char* token, int& intval); + static bool equivalent_expressions(const char* str1, const char* str2); static void trim(char* &token); // trim leading & trailing spaces }; diff --git a/src/share/vm/adlc/archDesc.cpp b/src/share/vm/adlc/archDesc.cpp index 9702fb47730f7aed210c0d537e4c6c258a108d53..a73ad76da23263e5a857a36f7e3746ab0332560b 100644 --- a/src/share/vm/adlc/archDesc.cpp +++ b/src/share/vm/adlc/archDesc.cpp @@ -140,7 +140,7 @@ bool MatchList::search(const char *opc, const char *res, const char *lch, if ((rch == _rchild) || (rch && _rchild && !strcmp(rch, _rchild))) { char * predStr = get_pred(); char * prStr = pr?pr->_pred:NULL; - if ((prStr == predStr) || (prStr && predStr && !strcmp(prStr, predStr))) { + if (ADLParser::equivalent_expressions(prStr, predStr)) { return true; } } diff --git a/src/share/vm/adlc/dfa.cpp b/src/share/vm/adlc/dfa.cpp index 36d56062cfda80ee9baf1cabb4d61d9e7a7810fe..1075c9da77414ef02f3027a5d4ab5d760001c74d 100644 --- a/src/share/vm/adlc/dfa.cpp +++ b/src/share/vm/adlc/dfa.cpp @@ -458,7 +458,7 @@ void ArchDesc::buildDFA(FILE* fp) { class dfa_shared_preds { - enum { count = 2 }; + enum { count = 4 }; static bool _found[count]; static const char* _type [count]; @@ -479,12 +479,15 @@ class dfa_shared_preds { char c = *prev; switch( c ) { case ' ': + case '\n': return dfa_shared_preds::valid_loc(pred, prev); case '!': case '(': case '<': case '=': return true; + case '"': // such as: #line 10 "myfile.ad"\n mypredicate + return true; case '|': if( prev != pred && *(prev-1) == '|' ) return true; case '&': @@ -564,10 +567,14 @@ public: } }; // shared predicates, _var and _pred entry should be the same length -bool dfa_shared_preds::_found[dfa_shared_preds::count] = { false, false }; -const char* dfa_shared_preds::_type[dfa_shared_preds::count] = { "int", "bool" }; -const char* dfa_shared_preds::_var [dfa_shared_preds::count] = { "_n_get_int__", "Compile__current____select_24_bit_instr__" }; -const char* dfa_shared_preds::_pred[dfa_shared_preds::count] = { "n->get_int()", "Compile::current()->select_24_bit_instr()" }; +bool dfa_shared_preds::_found[dfa_shared_preds::count] + = { false, false, false, false }; +const char* dfa_shared_preds::_type[dfa_shared_preds::count] + = { "int", "jlong", "intptr_t", "bool" }; +const char* dfa_shared_preds::_var [dfa_shared_preds::count] + = { "_n_get_int__", "_n_get_long__", "_n_get_intptr_t__", "Compile__current____select_24_bit_instr__" }; +const char* dfa_shared_preds::_pred[dfa_shared_preds::count] + = { "n->get_int()", "n->get_long()", "n->get_intptr_t()", "Compile::current()->select_24_bit_instr()" }; void ArchDesc::gen_dfa_state_body(FILE* fp, Dict &minimize, ProductionState &status, Dict &operands_chained_from, int i) { diff --git a/src/share/vm/adlc/filebuff.hpp b/src/share/vm/adlc/filebuff.hpp index c36fdbaf3faddc12b38fa52e28f0408d397deaf1..4c69bacee3947e31227d4ee5d12284c5abe08f05 100644 --- a/src/share/vm/adlc/filebuff.hpp +++ b/src/share/vm/adlc/filebuff.hpp @@ -68,6 +68,7 @@ class FileBuff { // and increments bufeol and filepos to point at the end of that line. char *get_line(void); int linenum() const { return _linenum; } + void set_linenum(int line) { _linenum = line; } // This converts a pointer into the buffer to a file offset. It only works // when the pointer is valid (i.e. just obtained from getline()). diff --git a/src/share/vm/adlc/formssel.cpp b/src/share/vm/adlc/formssel.cpp index fb91d83d2f6ccc126113d8d085587e5ee693a1c6..65b511bcdb1d5a7fd866df7df369efa4efaa91e5 100644 --- a/src/share/vm/adlc/formssel.cpp +++ b/src/share/vm/adlc/formssel.cpp @@ -1102,10 +1102,7 @@ bool equivalent_predicates( const InstructForm *instr1, const InstructForm *inst } if( pred1 != NULL && pred2 != NULL ) { // compare the predicates - const char *str1 = pred1->_pred; - const char *str2 = pred2->_pred; - if( (str1 == NULL && str2 == NULL) - || (str1 != NULL && str2 != NULL && strcmp(str1,str2) == 0) ) { + if (ADLParser::equivalent_expressions(pred1->_pred, pred2->_pred)) { return true; } } diff --git a/src/share/vm/classfile/classFileParser.cpp b/src/share/vm/classfile/classFileParser.cpp index 45d0147fa7d591f2e0610d4055f07092fb311fb5..703217f9255305c4678ab0fd96062833c71f73f1 100644 --- a/src/share/vm/classfile/classFileParser.cpp +++ b/src/share/vm/classfile/classFileParser.cpp @@ -581,7 +581,8 @@ objArrayHandle ClassFileParser::parse_interfaces(constantPoolHandle cp, interf = KlassHandle(THREAD, k); vmtimer->resume(); - cp->klass_at_put(interface_index, interf()); // eagerly resolve + if (LinkWellKnownClasses) // my super type is well known to me + cp->klass_at_put(interface_index, interf()); // eagerly resolve } if (!Klass::cast(interf())->is_interface()) { @@ -2699,7 +2700,8 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name, CHECK_(nullHandle)); KlassHandle kh (THREAD, k); super_klass = instanceKlassHandle(THREAD, kh()); - cp->klass_at_put(super_class_index, super_klass()); // eagerly resolve + if (LinkWellKnownClasses) // my super class is well known to me + cp->klass_at_put(super_class_index, super_klass()); // eagerly resolve } if (super_klass.not_null()) { if (super_klass->is_interface()) { @@ -3128,7 +3130,8 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name, this_klass->set_method_ordering(method_ordering()); this_klass->set_initial_method_idnum(methods->length()); this_klass->set_name(cp->klass_name_at(this_class_index)); - cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve + if (LinkWellKnownClasses) // I am well known to myself + cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve this_klass->set_protection_domain(protection_domain()); this_klass->set_fields_annotations(fields_annotations()); this_klass->set_methods_annotations(methods_annotations()); diff --git a/src/share/vm/runtime/globals.hpp b/src/share/vm/runtime/globals.hpp index 5d08a653bd54ba5c776f2a7e84decdc86ed54d50..ab707929340a5246f08bae1bf71d75559fbe367b 100644 --- a/src/share/vm/runtime/globals.hpp +++ b/src/share/vm/runtime/globals.hpp @@ -818,7 +818,7 @@ class CommandLineFlags { product(bool, ClassUnloading, true, \ "Do unloading of classes") \ \ - diagnostic(bool, LinkWellKnownClasses, true, \ + diagnostic(bool, LinkWellKnownClasses, false, \ "Resolve a well known class as soon as its name is seen") \ \ develop(bool, DisableStartThread, false, \