--- /dev/null 2019-11-19 22:05:02.069813242 -0800 +++ new/src/hotspot/convert_flags.tcl 2020-04-05 21:35:44.535949920 -0700 @@ -0,0 +1,685 @@ +set file [lindex $argv 0] +set macro [lindex $argv 1] + +if {[info exists env(FINAL_PATCH)]} { + set changed 0 + catch { + exec bash -c "hg status . | grep ." >@ stdout 2>@ stdout + # If the above command exited with 0 status, that means some + # files have (possibly) changed + set changed 1 + } + if {$changed} { + puts "Some files have changed -- FINAL_PATCH aborted" + exit 1 + } +} + +proc append_orig {varname line} { + upvar $varname orig + if {[string first TEMP_CONVERSION $line] < 0} { + append orig $line\n + } +} + +proc flags_header_file {file} { + if {![regsub {[.]hpp$} $file {.flags.hpp} file]} { + puts "Not a proper input header file $file" + exit 1 + } + return $file +} + +proc keep_orig_flags_macro {} { + global env + if {[info exists env(FINAL_PATCH)] || [info exists env(QUICK_TEST)]} { + return 0 + } else { + return 1 + } +} + +proc temp_mark {} { + set mark "" + if {[keep_orig_flags_macro]} { + set mark " // TEMP_CONVERSION" + } + return $mark +} + +proc move_file {src dst} { + if {[catch {exec cmp -s $src $dst}]} { + # the files differ + puts "update $dst" + file rename -force $src $dst + } else { + puts "(same) $dst" + file delete $src + } +} + +proc doit {file macro ifdef common} { + global copyright all_names env + + foreach n {all_decl all_defn lp64_decl lp64_defn flagcond} { + global $n + catch {unset $n} + } + set all_names {} + + set orig "" + set out "" + set fd [open $file] + while {![eof $fd]} { + set line [gets $fd] + if {[string first "\#define $macro\(" $line] >= 0} { + + set flagfile [flags_header_file $file] + set insert "" + append insert "#include \"[file tail $flagfile]\"[temp_mark]\n" + + set macro "" + if {[keep_orig_flags_macro]} { + append macro "#if 0[temp_mark]\n" + } + if {[keep_orig_flags_macro]} { + append_orig macro $line + } + set data $line\n + while {![eof $fd]} { + set line [gets $fd] + if {[keep_orig_flags_macro]} { + append macro $line\n + } + append data $line\n + if {![regexp {\\$} $line]} { + append out [process $data] + break + } + } + + #-------------------------------------------------- + # Prepare the content of the .flags.hpp file + #-------------------------------------------------- + while {[regsub -all "(\n#\[^\n\]*_HPP)\n" $out "\\1_HACK\n" out]} {} + set flags_hpp "" + + if {$ifdef != ""} { + append flags_hpp "#include \"utilities/macros.hpp\"\n" + append flags_hpp "#if $ifdef\n" + } + + append flags_hpp "#include \"runtime/flags/jvmFlag.hpp\"\n" + append flags_hpp [string trimright $out] + + if {$ifdef != ""} { + append flags_hpp "\n#endif // $ifdef" + } + + if {[info exists all_decl]} { + if {[keep_orig_flags_macro]} { + append orig $insert + } else { + append orig $flags_hpp\n + } + } + if {[keep_orig_flags_macro]} { + append macro "#endif[temp_mark]\n" + } + if {[keep_orig_flags_macro]} { + append orig $macro + } + } else { + append_orig orig $line + } + } + close $fd + + # Change "Defines ..." to "Declares ..." + regsub {Defines all global flags} $orig {Declare all global flags} orig + regsub {Defines (.*specific flags)} $orig {Declare \1} orig + + #-------------------------------------------------- + # Patch the original .hpp file + #-------------------------------------------------- + set fd [open $file.tmp w+] + regsub -all \n+\$ $orig "" orig + puts $fd $orig + close $fd + move_file $file.tmp $file + + #-------------------------------------------------- + # Write the .cpp file (if file exists, add the flag definitions to the end) + #-------------------------------------------------- + write_c_file $file [flags_header_file $file] $ifdef $common + + #-------------------------------------------------- + # not final: Write the .flags.hpp file + #-------------------------------------------------- + if {[keep_orig_flags_macro]} { + set file [flags_header_file $file] + + if {![info exists all_decl]} { + if {[file exists $file]} { + puts "hg remove $file" + } + return + } + + file mkdir [file dir $file] + set fd [open $file.tmp w+] + puts $fd $flags_hpp + close $fd + + move_file $file.tmp $file + } + + if {[info exists env(QUICK_TEST)]} { + exit + } + #exit +} + +set flags {} + +foreach {f n attr} { + develop VMDevelop {} + develop_pd VMDevelopPD {} + product VMProduct {} + product_pd VMProductPD {} + diagnostic VMDiagnostic DIAGNOSTIC + diagnostic_pd VMDiagnosticPD {DIAGNOSTIC} + experimental VMExperimental EXPERIMENTAL + notproduct VMNotProduct {} + manageable VMManageable MANAGEABLE + product_rw VMProductRW READ_WRITE + lp64_product VMLP64Product LP64 +} { + set className($f) $n + set attrs($f) $attr + lappend flags $f +} + +set prefix "" +set flagdecl "(" + +foreach f $flags { + append flagdecl $prefix$f + set prefix ")|(" +} + +append flagdecl ")" + +set defn_indent [format %23s ""] + +proc get_docs {docs n} { + global defn_indent + # Skip the stuff before the first $n commas (these are the type, name and optional def_value) + for {set i 0} {$i < $n} {incr i} { + regsub {^[^,]*,} $docs "" docs + } + + regsub -all {^[\\ ]*} $docs "" docs + regsub -all " *\\\\\n *" $docs "\n$defn_indent" docs + + set docs [string trim $docs] + return ${defn_indent}${docs} +} + +proc clean_slashes {text} { + regsub -all {^[\\ ]*} $text "" text + regsub -all " *\\\\\n *" $text "" text + return [string trim $text] +} + +# These flags are misidentified as "notproduct" in the original source code -- +# they are actually used as develop flags. +# +foreach bad { + CheckMemoryInitialization + OptoBreakpointC2R + OptoBreakpointOSR + PrintInitialBlockList + PrintOptoInlining + PrintOpto + PrintSystemDictionaryAtExit + TestUnresponsiveErrorHandler + TraceSuperWordLoopUnrollAnalysis + TraceSuperWord + VerifyLoopOptimizations +} { + set notnotproduct($bad) 1 +} + + +proc spaces {n} { + return [format "%${n}s" ""] +} + +proc replace {class match range constraint comment} { + global className defn_indent attrs all_decl all_defn lp64_decl lp64_defn flagcond notnotproduct all_comments all_names + + set list [split $match ,] + set type [string trim [lindex $list 0]] + set name [string trim [lindex $list 1]] + + set PD "" + if {[regexp {_pd$} $class]} { + set defv "" + set defv_sep "" + set docs [get_docs $match 2] + set PD _PD + } else { + set defv [string trim [lindex $list 2]] + set defv_sep ", " + set docs [get_docs $match 3] + } + + set range [clean_slashes $range] + set constraint [clean_slashes $constraint] + set defv [clean_slashes $defv] + + set cname $className($class) + + # Special cases for ranges that cannot be represented in constant expressions + if {[regexp "os::vm_page_size" $range]} { + set kind VMPageSize + if {"$constraint" != {}} { + error "constraint must be empty but is $constraint" + } + } elseif {[regexp "os::vm_allocation_granularity" $range]} { + set kind VMAllocationGranularity + if {"$constraint" != {}} { + error "constraint must be empty but is $constraint" + } + } + + if {"$constraint" != {}} { + regsub , $constraint ", JVMFlag::" constraint + regsub ":: *" $constraint "::" constraint + set constraint "(void*)$constraint" + } + + if {[regexp develop $class] || [info exists notnotproduct($name)]} { + set macro_prefix DEVELOP + } elseif {$class == "notproduct"} { + set macro_prefix NOTPROD + } else { + set macro_prefix PRODUCT + } + + set def_prefix DEFN_${macro_prefix} + + set my_attrs $attrs($class) + if {"$type" == "ccstrlist"} { + set type ccstr + lappend my_attrs STRINGLIST + } + + set decl ${macro_prefix}_FLAG${PD} + set defn DEFN_$decl + + set attr "" + set prefix "" + foreach a $my_attrs { + append attr "${prefix}JVMFlag::${a}" + set prefix " | " + } + if {$range != ""} { + append attr "${prefix}JVMFlag::RANGE" + set prefix " | " + } + if {$constraint != ""} { + append attr "${prefix}JVMFlag::CONSTRAINT" + set prefix " | " + } + + if {$attr == ""} { + set attr JVMFlag::DEFAULT + } + + set sspc [expr 8 - [string length $type] - [string length ${PD}]] + set t "$type,[spaces $sspc]" + + set dec "" + append dec "${decl}($t ${name}${defv_sep}${defv}, ${attr},\n" + append dec "$docs);\n" + set def "" + append def "${defn}(${name});" + + if {$class == "lp64_product"} { + # This is the declaration for 32-bit builds. + set lp64_decl($name) "const $type $name = $defv; // !JVMFlag::LP64" + } + + set all_decl($name) $dec + set all_defn($name) $def + + if {$range != ""} { + if {[info exists kind]} { + append all_decl($name) " FLAG_CUSTOM_RANGE([spaces 2]$name, $kind);\n" + } elseif {[regexp :: $range]} { + set warning "TODO: to avoid circular dependency, the min/max cannot be declared in header file" + append all_decl($name) " //$warning\n" + append all_decl($name) " //FLAG_RANGE([spaces 9]$name, $range);\n" + set list [split $range ,] + append all_defn($name) "\n // $warning" + append all_defn($name) "\n inline FLAG_TYPE_$name FLAG_MIN_${name}() { return [string trim [lindex $list 0]]; }" + append all_defn($name) "\n inline FLAG_TYPE_$name FLAG_MAX_${name}() { return [string trim [lindex $list 1]]; }\n " + } else { + append all_decl($name) " FLAG_RANGE([spaces 9]$name, $range);\n" + } + if {[info exists kind]} { + append all_defn($name) " ${def_prefix}_CUSTOM_RANGE($name);" + } else { + append all_defn($name) " ${def_prefix}_RANGE($name);" + } + } + if {$constraint != ""} { + append all_decl($name) " FLAG_CONSTRAINT([spaces 4]$name, $constraint);\n" + append all_defn($name) " ${def_prefix}_CONSTRAINT($name);"; + } + + if {[info exists flagcond($name)]} { + set cond $flagcond($name) + set all_decl($name) "${cond}($dec)\n" + set all_defn($name) "${cond}($def)\n" + } + append all_decl($name) \n + + set all_comments($name) $comment + + lappend all_names $name +} + +proc get_last_match {text pat} { + set match "" + while {[regexp $pat $text dummy match]} { + regexp $pat $text "" text + } + return $match +} + +proc parse_range {text} { + if {[regexp {\uffff.*range *[\(](.*)} $text dummy match]} { + regsub {/[*].*} $match "" match + regsub {constraint[\(].*} $match "" match + regsub {[\)][^\)]*$} $match "" match + return $match + } else { + return "" + } +} + +proc check_conditionals {data} { + global flagdecl flagcond + + set pat "(\[A-Z0-9_\]+)\[\(\]($flagdecl)" + foreach line [split $data \n] { + if {[regexp $pat $line dummy cond]} { + set flagname [string trim [lindex [split $line ,] 1]] + set flagcond($flagname) $cond + } + } +} + +proc get_comments {data} { + #set t $data + regsub -all {/[*]} $data \uffee data + regsub -all {[*]/} $data \uffef data + + regsub ".*\[\)\] *\\\\\n" $data "" data + set data "\n$data\n" + #set y $data + + set list {} + + set start "============================================================\n" + set pat "\n *\uffee(\[^\uffef\]+)\uffef" + while {[regexp $pat $data dummy match]} { + regsub $pat $data "\n" data + lappend list $match + #puts $start$match + #set start "" + #if {[string trim $match] == "2^24"} { + # puts $t + # puts ==$y + # exit + #} + } + + return $list +} + +proc process {data} { + global flagdecl + + regsub {^#define [A-Za-z0-9_]+[(][^)]+.} $data "" data + set data [string trim $data] + + set mark_begin_pat "($flagdecl)\[(\]" + + # get rid of the double close parens of JFR_ONLY(product(bool, FlightRecorder, ".....")) + regsub -all {\"[\)][\)] *\\} $data "\"\) \\\\" data + + check_conditionals $data + + regsub -all $mark_begin_pat $data "\ufff0\\1\ufffe" data + regsub -all "\" *\[\)\] *(\\\\|$)" $data "\uffff" data + + set flag_pat "($flagdecl)\ufffe(\[^\uffff\]+)\uffff" + + set next_comment "" + + foreach part [split $data \ufff0] { + set range "" + set constraint "" + + set comment $next_comment + set next_comment [get_comments $part] + + if {[regexp $flag_pat $part match class]} { + regsub .*\ufffe $match "" match + regsub \uffff $match "\"" match + set list [split $data \ufffc] + set range [parse_range $part] + regexp {constraint[(]([^)]+).} $part dummy constraint + + set newflag [replace $class $match $range $constraint $comment] + } + } + + set data [format_output all_decl lp64_decl 1] + + # Remove all whitespaces and empty lines ... + while {[regsub -all "\n *\\\\\n" $data "\n" data]} {} + regsub -all " *\\\\\n" $data "\n" data + #regsub -all "\n +" $data "\n" data + #regsub -all "\n+" $data "\n" data + + # ... but leave an empty line before comments + regsub -all ";\n/" $data ";\n\n/" data + + return $data +} + +proc format_output {allarr lp64arr use_comments} { + global copyright all_names + + upvar #0 $allarr all + upvar #0 $lp64arr lp64 + + set out "" + set list $all_names + + foreach name $list { + if {![info exists lp64($name)]} { + append out [format_one_flag $allarr $name $use_comments] + } + } + + if {[info exists lp64]} { + append out "\n#ifdef _LP64\n" + foreach name $list { + if {[info exists lp64($name)]} { + append out [format_one_flag $allarr $name $use_comments] + } + } + if {$allarr == "all_decl"} { + append out "#elif defined(IS_DECLARING_FLAG)\n" + foreach name $list { + if {[info exists lp64($name)]} { + append out $lp64($name)\n + } + } + } + append out "#endif // _LP64\n" + } + + regsub -all "\n\[)\]" $out ")" out + + return $out +} + +proc format_one_flag {allarr name use_comments} { + upvar #0 $allarr all + global all_comments + + set cmt $all_comments($name) + set comments "" + if {$cmt != "" && $use_comments} { + set comments "\n" + foreach line $cmt { + append comments " // $line\n" + } + } + + if {$use_comments} { + set newline "" + } else { + set newline "\n" + } + return $comments$all($name)$newline +} + +set copyright {/* + * Copyright (c) 2020, 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. + * + * 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. + * + */} + +proc write_c_file {hppfile flagsfile ifdef common} { + global copyright all_decl + + # put the C file first so we can compile it first without waiting for the other 1000 files + regsub {[.]hpp} $hppfile ".cpp" cppfile + + if {![info exists all_decl]} { + if {[file exists $cppfile]} { + puts "hg remove $cppfile" + } + return + } + + set data "" + if {[catch { + set fd [open $cppfile] + set data [read $fd] + close $fd + }]} { + set data $copyright + append data "\n" + append data "#include \"precompiled.hpp\"\n" + } + + regsub "#include \"runtime/flags/newFlagInstantiate.hpp\"\n" $data "" data + if {[file tail $cppfile] != "c2_globals.cpp"} { + regsub "#include \"runtime/globals.hpp\"\n" $data "" data + } + + regsub "// -- Define all JVM flags that have been declared.*" $data "" data + set data [string trimright $data] + + append data "\n" + append data "\n" + append data "// -- Define all JVM flags that have been declared in $hppfile\n\n" + + if {$common != ""} { + append data "// Add JVMFlag::$common to the JVMFlag::attr() for all flags defined in this file\n" + append data "#ifdef FLAG_COMMON_ATTRS\n" + append data "#undef FLAG_COMMON_ATTRS\n" + append data "#endif\n" + append data "#define FLAG_COMMON_ATTRS JVMFlag::$common\n" + append data "\n" + } + + #if {$ifdef != ""} { + # append data "#if $ifdef\n" + #} + + append data "#include \"[file tail $hppfile]\"\n" + append data "#include \"runtime/flags/jvmFlag.inline.hpp\"\n" + + append data [format_output all_defn lp64_defn 0] + + append data "\n" + + if {$common != ""} { + #append data "#undef FLAG_COMMON_ATTRS\n" + #append data "#define FLAG_COMMON_ATTRS 0\n" + } + + set fd [open $cppfile.tmp w+] + puts $fd "[string trim $data]" + close $fd + + move_file $cppfile.tmp $cppfile +} + +set allhdrs {} + +foreach {file macro ifdef common} { + cpu/aarch64/globals_aarch64.hpp ARCH_FLAGS {} ARCH + cpu/arm/globals_arm.hpp ARCH_FLAGS {} ARCH + cpu/ppc/globals_ppc.hpp ARCH_FLAGS {} ARCH + cpu/s390/globals_s390.hpp ARCH_FLAGS {} ARCH + cpu/sparc/globals_sparc.hpp ARCH_FLAGS {} ARCH + cpu/x86/globals_x86.hpp ARCH_FLAGS {} ARCH + cpu/zero/globals_zero.hpp ARCH_FLAGS {} ARCH + os/aix/globals_aix.hpp RUNTIME_OS_FLAGS {} {} + os/bsd/globals_bsd.hpp RUNTIME_OS_FLAGS {} {} + os/linux/globals_linux.hpp RUNTIME_OS_FLAGS {} {} + os/solaris/globals_solaris.hpp RUNTIME_OS_FLAGS {} {} + os/windows/globals_windows.hpp RUNTIME_OS_FLAGS {} {} + share/c1/c1_globals.hpp C1_FLAGS COMPILER1 C1 + share/gc/epsilon/epsilon_globals.hpp GC_EPSILON_FLAGS INCLUDE_EPSILONGC {} + share/gc/g1/g1_globals.hpp GC_G1_FLAGS INCLUDE_G1GC {} + share/gc/parallel/parallel_globals.hpp GC_PARALLEL_FLAGS INCLUDE_PARALLELGC {} + share/gc/serial/serial_globals.hpp GC_SERIAL_FLAGS INCLUDE_SERIALGC {} + share/gc/shared/gc_globals.hpp GC_FLAGS {} {} + share/gc/shenandoah/shenandoah_globals.hpp GC_SHENANDOAH_FLAGS INCLUDE_SHENANDOAHGC {} + share/gc/z/z_globals.hpp GC_Z_FLAGS INCLUDE_ZGC {} + share/runtime/globals.hpp RUNTIME_FLAGS {} {} + share/jvmci/jvmci_globals.hpp JVMCI_FLAGS INCLUDE_JVMCI JVMCI + share/opto/c2_globals.hpp C2_FLAGS COMPILER2 C2 +} { + doit $file $macro $ifdef $common +}