1 /*
   2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_COMPILER_DIRECTIVESPARSER_HPP
  26 #define SHARE_VM_COMPILER_DIRECTIVESPARSER_HPP
  27 
  28 #include "utilities/json.hpp"
  29 #include "compiler/compilerDirectives.hpp"
  30 
  31 enum FlagType {
  32   boolFlag,
  33   intxFlag,
  34   doubleFlag,
  35   ccstrFlag,
  36   UnknownFlagType
  37 };
  38 
  39 static const char* flag_type_names[] = {
  40     "bool",
  41     "int",
  42     "double",
  43     "string",
  44     "unknown"
  45 };
  46 
  47 class DirectivesParser : public JSON {
  48 public:
  49   static bool has_file();
  50   static bool parse_from_flag();
  51   static bool parse_from_file(const char* filename);
  52   static bool parse_string(const char* string);
  53   bool install_directives();
  54 
  55 private:
  56   DirectivesParser(const char* text);
  57   ~DirectivesParser();
  58 
  59   bool callback(JSON_TYPE t, JSON_VAL* v, uint level);
  60   static bool parse_from_file_inner(const char* filename);
  61 
  62   // types of "keys". i.e recognized <key>:<value> pairs in our JSON syntax
  63   typedef enum {
  64      type_c1,
  65      type_c2,
  66      type_enable,
  67      type_preset,
  68      type_match,
  69      type_inline,
  70 
  71      // After here, there is no correlation between
  72      // keytype and keys array
  73      //type_strategy,
  74      type_flag,
  75      //type_dir,
  76 
  77      // Synthetic.
  78      type_dir_array,
  79      type_directives,
  80      type_value_array
  81   } keytype;
  82 
  83   // name, type, dtd info and maybe a setter
  84   // this is how we map key-values
  85   typedef struct {
  86      const char *name;
  87      keytype     type;
  88      uint    allow_array_value : 1;
  89      uint    allowedmask;
  90      void (DirectiveSet::*set)(void* arg);
  91      FlagType flag_type;
  92   } key;
  93 
  94   // Array with valid keys for the directive file
  95   static const key keys[];
  96   // Marker for outermost moosewings/array
  97   static const key dir_array_key;
  98   // Marker for a directives set (these are "implicit" objects, as in not named)
  99   static const key dir_key;
 100   // Marker for a multi value
 101   static const key value_array_key;
 102 
 103   // A compiler directive shouldn't be able to use more than 5 stack slots.
 104   // Example of max stack usage:
 105   // depth 1: type_dir_array  [
 106   // depth 2: type_directives   {
 107   // depth 3: type_c1             c1: {
 108   // depth 4: type_inline           inline:
 109   // depth 5: type_value_array      [ ...
 110   static const uint MAX_DEPTH = 5;
 111   const key* stack[MAX_DEPTH];
 112   uint depth;
 113 
 114   bool push_key(const char* str, size_t len);
 115   bool push_key(const key* k);
 116   const key* current_key();
 117   const key* pop_key();
 118   static const key* lookup_key(const char* s, size_t len);
 119 
 120   bool set_option(JSON_TYPE t, JSON_VAL* v);
 121   bool set_option_flag(JSON_TYPE t, JSON_VAL* v, const key* option_key, DirectiveSet* set);
 122 
 123   CompilerDirectives* current_directive;
 124   DirectiveSet*       current_directiveset;
 125 
 126   void push_tmp(CompilerDirectives* dir);
 127   CompilerDirectives* pop_tmp();
 128   CompilerDirectives* _tmp_top; // temporary storage for dirs while parsing
 129 
 130   static uint mask(keytype kt);
 131 
 132 #ifndef PRODUCT
 133   static void test(const char* json, bool valid);
 134 public:
 135   static bool test();
 136 #endif
 137 };
 138 
 139 #endif // SHARE_VM_COMPILER_DIRECTIVESPARSER_HPP