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