src/share/vm/adlc/adlparse.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6961690 Cdiff src/share/vm/adlc/adlparse.cpp

src/share/vm/adlc/adlparse.cpp

Print this page
rev 1838 : 6961690: load oops from constant table on SPARC
Summary: oops should be loaded from the constant table of an nmethod instead of materializing them with a long code sequence.
Reviewed-by:

*** 1,7 **** /* ! * Copyright (c) 1997, 2009, 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. --- 1,7 ---- /* ! * Copyright (c) 1997, 2010, 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.
*** 214,225 **** } } else if (!strcmp(ident, "encode")) { parse_err(SYNERR, "Instructions specify ins_encode, not encode\n"); } ! else if (!strcmp(ident, "ins_encode")) ! instr->_insencode = ins_encode_parse(*instr); else if (!strcmp(ident, "opcode")) instr->_opcode = opcode_parse(instr); else if (!strcmp(ident, "size")) instr->_size = size_parse(instr); else if (!strcmp(ident, "effect")) effect_parse(instr); else if (!strcmp(ident, "expand")) instr->_exprule = expand_parse(instr); else if (!strcmp(ident, "rewrite")) instr->_rewrule = rewrite_parse(); --- 214,224 ---- } } else if (!strcmp(ident, "encode")) { parse_err(SYNERR, "Instructions specify ins_encode, not encode\n"); } ! else if (!strcmp(ident, "ins_encode")) ins_encode_parse(*instr); else if (!strcmp(ident, "opcode")) instr->_opcode = opcode_parse(instr); else if (!strcmp(ident, "size")) instr->_size = size_parse(instr); else if (!strcmp(ident, "effect")) effect_parse(instr); else if (!strcmp(ident, "expand")) instr->_exprule = expand_parse(instr); else if (!strcmp(ident, "rewrite")) instr->_rewrule = rewrite_parse();
*** 933,945 **** } // (2) // If we are at a replacement variable, // copy it and record in EncClass ! if ( _curchar == '$' ) { // Found replacement Variable ! char *rep_var = get_rep_var_ident_dup(); // Add flag to _strings list indicating we should check _rep_vars encoding->add_rep_var(rep_var); } } // end while part of format description next_char(); // Skip '%' --- 932,944 ---- } // (2) // If we are at a replacement variable, // copy it and record in EncClass ! if (_curchar == '$') { // Found replacement Variable ! char* rep_var = get_rep_var_ident_dup(); // Add flag to _strings list indicating we should check _rep_vars encoding->add_rep_var(rep_var); } } // end while part of format description next_char(); // Skip '%'
*** 2772,2822 **** } //------------------------------ins_encode_parse_block------------------------- // Parse the block form of ins_encode. See ins_encode_parse for more details ! InsEncode *ADLParser::ins_encode_parse_block(InstructForm &inst) { // Create a new encoding name based on the name of the instruction // definition, which should be unique. ! const char * prefix = "__enc_"; ! char* ec_name = (char*)malloc(strlen(inst._ident) + strlen(prefix) + 1); sprintf(ec_name, "%s%s", prefix, inst._ident); assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist"); ! EncClass *encoding = _AD._encode->add_EncClass(ec_name); encoding->_linenum = linenum(); // synthesize the arguments list for the enc_class from the // arguments to the instruct definition. ! const char * param = NULL; inst._parameters.reset(); while ((param = inst._parameters.iter()) != NULL) { ! OperandForm *opForm = (OperandForm*)inst._localNames[param]; encoding->add_parameter(opForm->_ident, param); } ! // Add the prologue to create the MacroAssembler ! encoding->add_code("\n" ! " // Define a MacroAssembler instance for use by the encoding. The\n" ! " // name is chosen to match the __ idiom used for assembly in other\n" ! " // parts of hotspot and assumes the existence of the standard\n" ! " // #define __ _masm.\n" ! " MacroAssembler _masm(&cbuf);\n"); // Parse the following %{ }% block ! enc_class_parse_block(encoding, ec_name); // Build an encoding rule which invokes the encoding rule we just // created, passing all arguments that we received. ! InsEncode *encrule = new InsEncode(); // Encode class for instruction ! NameAndList *params = encrule->add_encode(ec_name); inst._parameters.reset(); while ((param = inst._parameters.iter()) != NULL) { params->add_entry(param); } ! return encrule; } //------------------------------ins_encode_parse------------------------------- // Encode rules have the form --- 2771,2896 ---- } //------------------------------ins_encode_parse_block------------------------- // Parse the block form of ins_encode. See ins_encode_parse for more details ! void ADLParser::ins_encode_parse_block(InstructForm& inst) { // Create a new encoding name based on the name of the instruction // definition, which should be unique. ! const char* prefix = "__ins_encode_"; ! char* ec_name = (char*) malloc(strlen(inst._ident) + strlen(prefix) + 1); sprintf(ec_name, "%s%s", prefix, inst._ident); assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist"); ! EncClass* encoding = _AD._encode->add_EncClass(ec_name); encoding->_linenum = linenum(); // synthesize the arguments list for the enc_class from the // arguments to the instruct definition. ! const char* param = NULL; inst._parameters.reset(); while ((param = inst._parameters.iter()) != NULL) { ! OperandForm* opForm = (OperandForm*) inst._localNames[param]; encoding->add_parameter(opForm->_ident, param); } ! // Define a MacroAssembler instance for use by the encoding. The ! // name is chosen to match the __ idiom used for assembly in other ! // parts of hotspot and assumes the existence of the standard ! // #define __ _masm. ! encoding->add_code(" MacroAssembler _masm(&cbuf);\n"); // Parse the following %{ }% block ! ins_encode_parse_block_impl(inst, encoding, ec_name); // Build an encoding rule which invokes the encoding rule we just // created, passing all arguments that we received. ! InsEncode* encrule = new InsEncode(); // Encode class for instruction ! NameAndList* params = encrule->add_encode(ec_name); inst._parameters.reset(); while ((param = inst._parameters.iter()) != NULL) { params->add_entry(param); } ! // Set encode class of this instruction. ! inst._insencode = encrule; ! } ! ! ! void ADLParser::ins_encode_parse_block_impl(InstructForm& inst, 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) { ! encoding->add_code(get_line_string()); ! } ! ! // Collect the parts of the encode description ! // (1) strings that are passed through to output ! // (2) replacement/substitution variable, preceeded by a '$' ! while ((_curchar != '%') && (*(_ptr+1) != '}')) { ! ! // (1) ! // Check if there is a string to pass through to output ! char *start = _ptr; // Record start of the next string ! while ((_curchar != '$') && ((_curchar != '%') || (*(_ptr+1) != '}')) ) { ! // If at the start of a comment, skip past it ! if( (_curchar == '/') && ((*(_ptr+1) == '/') || (*(_ptr+1) == '*')) ) { ! skipws_no_preproc(); ! } else { ! // ELSE advance to the next character, or start of the next line ! next_char_or_line(); ! } ! } ! // If a string was found, terminate it and record in EncClass ! if (start != _ptr) { ! *_ptr = '\0'; // Terminate the string ! encoding->add_code(start); ! } ! ! // (2) ! // If we are at a replacement variable, ! // copy it and record in EncClass ! if (_curchar == '$') { ! // Found replacement Variable ! char* rep_var = get_rep_var_ident_dup(); ! ! // Add flag to _strings list indicating we should check _rep_vars ! encoding->add_rep_var(rep_var); ! ! skipws(); ! ! // Check if this instruct is a MachConstantNode. ! if (strcmp(rep_var, "constanttablebase") == 0) { ! // This instruct is a MachConstantNode. ! inst.set_is_mach_constant(true); ! ! if (_curchar == '(') { ! parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument (only constantaddress and constantoffset)", ec_name); ! return; ! } ! } ! else if ((strcmp(rep_var, "constantaddress") == 0) || ! (strcmp(rep_var, "constantoffset") == 0)) { ! // This instruct is a MachConstantNode. ! inst.set_is_mach_constant(true); ! ! // If the constant keyword has an argument, parse it. ! if (_curchar == '(') constant_parse(inst); ! } ! } ! } // end while part of format description ! next_char(); // Skip '%' ! next_char(); // Skip '}' ! ! 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); } //------------------------------ins_encode_parse------------------------------- // Encode rules have the form
*** 2836,2861 **** // // MacroAssembler masm(&cbuf);\n"); // // making it more compact to take advantage of the MacroAssembler and // placing the assembly closer to it's use by instructions. ! InsEncode *ADLParser::ins_encode_parse(InstructForm &inst) { // Parse encode class name skipws(); // Skip whitespace if (_curchar != '(') { // Check for ins_encode %{ form if ((_curchar == '%') && (*(_ptr+1) == '{')) { next_char(); // Skip '%' next_char(); // Skip '{' // Parse the block form of ins_encode ! return ins_encode_parse_block(inst); } parse_err(SYNERR, "missing '%%{' or '(' in ins_encode definition\n"); ! return NULL; } next_char(); // move past '(' skipws(); InsEncode *encrule = new InsEncode(); // Encode class for instruction --- 2910,2936 ---- // // MacroAssembler masm(&cbuf);\n"); // // making it more compact to take advantage of the MacroAssembler and // placing the assembly closer to it's use by instructions. ! void ADLParser::ins_encode_parse(InstructForm& inst) { // Parse encode class name skipws(); // Skip whitespace if (_curchar != '(') { // Check for ins_encode %{ form if ((_curchar == '%') && (*(_ptr+1) == '{')) { next_char(); // Skip '%' next_char(); // Skip '{' // Parse the block form of ins_encode ! ins_encode_parse_block(inst); ! return; } parse_err(SYNERR, "missing '%%{' or '(' in ins_encode definition\n"); ! return; } next_char(); // move past '(' skipws(); InsEncode *encrule = new InsEncode(); // Encode class for instruction
*** 2864,2874 **** // identifier is optional. while (_curchar != ')') { ec_name = get_ident(); if (ec_name == NULL) { parse_err(SYNERR, "Invalid encode class name after 'ins_encode('.\n"); ! return NULL; } // Check that encoding is defined in the encode section EncClass *encode_class = _AD._encode->encClass(ec_name); if (encode_class == NULL) { // Like to defer checking these till later... --- 2939,2949 ---- // identifier is optional. while (_curchar != ')') { ec_name = get_ident(); if (ec_name == NULL) { parse_err(SYNERR, "Invalid encode class name after 'ins_encode('.\n"); ! return; } // Check that encoding is defined in the encode section EncClass *encode_class = _AD._encode->encClass(ec_name); if (encode_class == NULL) { // Like to defer checking these till later...
*** 2896,2906 **** if ( (inst._localNames[param] == NULL) && !ADLParser::is_literal_constant(param) && (Opcode::as_opcode_type(param) == Opcode::NOT_AN_OPCODE) && ((_AD._register == NULL ) || (_AD._register->getRegDef(param) == NULL)) ) { parse_err(SYNERR, "Using non-locally defined parameter %s for encoding %s.\n", param, ec_name); ! return NULL; } params->add_entry(param); skipws(); if (_curchar == ',' ) { --- 2971,2981 ---- if ( (inst._localNames[param] == NULL) && !ADLParser::is_literal_constant(param) && (Opcode::as_opcode_type(param) == Opcode::NOT_AN_OPCODE) && ((_AD._register == NULL ) || (_AD._register->getRegDef(param) == NULL)) ) { parse_err(SYNERR, "Using non-locally defined parameter %s for encoding %s.\n", param, ec_name); ! return; } params->add_entry(param); skipws(); if (_curchar == ',' ) {
*** 2913,2935 **** } else { // Only ',' or ')' are valid after a parameter name parse_err(SYNERR, "expected ',' or ')' after parameter %s.\n", ec_name); ! return NULL; } } else { skipws(); // Did not find a parameter if (_curchar == ',') { parse_err(SYNERR, "Expected encode parameter before ',' in encoding %s.\n", ec_name); ! return NULL; } if (_curchar != ')') { parse_err(SYNERR, "Expected ')' after encode parameters.\n"); ! return NULL; } } } // WHILE loop collecting parameters next_char(); // move past ')' at end of parameters } // done with parameter list for encoding --- 2988,3010 ---- } else { // Only ',' or ')' are valid after a parameter name parse_err(SYNERR, "expected ',' or ')' after parameter %s.\n", ec_name); ! return; } } else { skipws(); // Did not find a parameter if (_curchar == ',') { parse_err(SYNERR, "Expected encode parameter before ',' in encoding %s.\n", ec_name); ! return; } if (_curchar != ')') { parse_err(SYNERR, "Expected ')' after encode parameters.\n"); ! return; } } } // WHILE loop collecting parameters next_char(); // move past ')' at end of parameters } // done with parameter list for encoding
*** 2942,2952 **** skipws(); } else if ( _curchar != ')' ) { // If not a ',' then only a ')' is allowed parse_err(SYNERR, "Expected ')' after encoding %s.\n", ec_name); ! return NULL; } // Check for ',' separating parameters // if ( _curchar != ',' && _curchar != ')' ) { // parse_err(SYNERR, "expected ',' or ')' after encode method inside ins_encode.\n"); --- 3017,3027 ---- skipws(); } else if ( _curchar != ')' ) { // If not a ',' then only a ')' is allowed parse_err(SYNERR, "Expected ')' after encoding %s.\n", ec_name); ! return; } // Check for ',' separating parameters // if ( _curchar != ',' && _curchar != ')' ) { // parse_err(SYNERR, "expected ',' or ')' after encode method inside ins_encode.\n");
*** 2954,2979 **** // } } // done parsing ins_encode methods and their parameters if (_curchar != ')') { parse_err(SYNERR, "Missing ')' at end of ins_encode description.\n"); ! return NULL; } next_char(); // move past ')' skipws(); // Skip leading whitespace if ( _curchar != ';' ) { parse_err(SYNERR, "Missing ';' at end of ins_encode.\n"); ! return NULL; } next_char(); // move past ';' skipws(); // be friendly to oper_parse() // Debug Stuff if (_AD._adl_debug > 1) fprintf(stderr,"Instruction Encode: %s\n", ec_name); ! return encrule; } //------------------------------size_parse----------------------------------- char* ADLParser::size_parse(InstructForm *instr) { --- 3029,3160 ---- // } } // done parsing ins_encode methods and their parameters if (_curchar != ')') { parse_err(SYNERR, "Missing ')' at end of ins_encode description.\n"); ! return; } next_char(); // move past ')' skipws(); // Skip leading whitespace if ( _curchar != ';' ) { parse_err(SYNERR, "Missing ';' at end of ins_encode.\n"); ! return; } next_char(); // move past ';' skipws(); // be friendly to oper_parse() // Debug Stuff if (_AD._adl_debug > 1) fprintf(stderr,"Instruction Encode: %s\n", ec_name); ! // Set encode class of this instruction. ! inst._insencode = encrule; ! } ! ! ! //------------------------------constant_parse--------------------------------- ! // Parse a constant expression. ! void ADLParser::constant_parse(InstructForm& inst) { ! // Create a new encoding name based on the name of the instruction ! // definition, which should be unique. ! const char* prefix = "__constant_"; ! char* ec_name = (char*) malloc(strlen(inst._ident) + strlen(prefix) + 1); ! sprintf(ec_name, "%s%s", prefix, inst._ident); ! ! assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist"); ! EncClass* encoding = _AD._encode->add_EncClass(ec_name); ! encoding->_linenum = linenum(); ! ! // synthesize the arguments list for the enc_class from the ! // arguments to the instruct definition. ! const char* param = NULL; ! inst._parameters.reset(); ! while ((param = inst._parameters.iter()) != NULL) { ! OperandForm* opForm = (OperandForm*) inst._localNames[param]; ! encoding->add_parameter(opForm->_ident, param); ! } ! ! // Parse the following ( ) expression. ! constant_parse_expression(encoding, ec_name); ! ! // Build an encoding rule which invokes the encoding rule we just ! // created, passing all arguments that we received. ! InsEncode* encrule = new InsEncode(); // Encode class for instruction ! NameAndList* params = encrule->add_encode(ec_name); ! inst._parameters.reset(); ! while ((param = inst._parameters.iter()) != NULL) { ! params->add_entry(param); ! } ! ! // Set encode class of this instruction. ! inst._constant = encrule; ! } ! ! ! //------------------------------constant_parse_expression---------------------- ! void ADLParser::constant_parse_expression(EncClass* encoding, char* ec_name) { ! skipws(); ! ! // Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block ! if (_AD._adlocation_debug) { ! encoding->add_code(get_line_string()); ! } ! ! // Start code line. ! encoding->add_code(" add_to_constant_table"); ! ! // Parse everything in ( ) expression. ! encoding->add_code("("); ! next_char(); // Skip '(' ! int parens_depth = 1; ! ! // Collect the parts of the constant expression. ! // (1) strings that are passed through to output ! // (2) replacement/substitution variable, preceeded by a '$' ! while (parens_depth > 0) { ! if (_curchar == '(') { ! parens_depth++; ! encoding->add_code("("); ! next_char(); ! } ! else if (_curchar == ')') { ! parens_depth--; ! encoding->add_code(")"); ! next_char(); ! } ! else { ! // (1) ! // Check if there is a string to pass through to output ! char *start = _ptr; // Record start of the next string ! while ((_curchar != '$') && (_curchar != '(') && (_curchar != ')')) { ! next_char(); ! } ! // If a string was found, terminate it and record in EncClass ! if (start != _ptr) { ! *_ptr = '\0'; // Terminate the string ! encoding->add_code(start); ! } ! ! // (2) ! // If we are at a replacement variable, copy it and record in EncClass. ! if (_curchar == '$') { ! // Found replacement Variable ! char* rep_var = get_rep_var_ident_dup(); ! encoding->add_rep_var(rep_var); ! } ! } ! } ! ! // Finish code line. ! encoding->add_code(";"); ! ! 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); } //------------------------------size_parse----------------------------------- char* ADLParser::size_parse(InstructForm *instr) {
src/share/vm/adlc/adlparse.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File