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   void   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 
  61   // types of "keys". i.e recognized <key>:<value> pairs in our JSON syntax
  62   typedef enum {
  63      type_c1,
  64      type_c2,
  65      type_enable,
  66      type_preset,
  67      type_match,
  68      type_inline,
  69 
  70      // After here, there is no correlation between
  71      // keytype and keys array
  72      //type_strategy,
  73      type_flag,
  74      //type_dir,
  75 
  76      // Synthetic.
  77      type_dir_array,
  78      type_directives,
  79      type_value_array
  80   } keytype;
  81 
  82   // name, type, dtd info and maybe a setter
  83   // this is how we map key-values
  84   typedef struct {
  85      const char *name;
  86      keytype     type;
  87      uint    allow_array_value : 1;
  88      uint    allowedmask;
  89      void (DirectiveSet::*set)(void* arg);
  90      FlagType flag_type;
  91   } key;
  92 
  93   // Array with valid keys for the directive file
  94   static const key keys[];
  95   // Marker for outermost moosewings/array
  96   static const key dir_array_key;
  97   // Marker for a directives set (these are "implicit" objects, as in not named)
  98   static const key dir_key;
  99   // Marker for a multi value
 100   static const key value_array_key;
 101 
 102   // A compiler directive shouldn't be able to use more than 5 stack slots.
 103   // Example of max stack usage:
 104   // depth 1: type_dir_array  [
 105   // depth 2: type_directives   {
 106   // depth 3: type_c1             c1: {
 107   // depth 4: type_inline           inline:
 108   // depth 5: type_value_array      [ ...
 109   static const uint MAX_DEPTH = 5;
 110   const key* stack[MAX_DEPTH];
 111   uint depth;
 112 
 113   bool push_key(const char* str, size_t len);
 114   bool push_key(const key* k);
 115   const key* current_key();
 116   const key* pop_key();
 117   static const key* lookup_key(const char* s, size_t len);
 118 
 119   bool set_option(JSON_TYPE t, JSON_VAL* v);
 120   bool set_option_flag(JSON_TYPE t, JSON_VAL* v, const key* option_key, DirectiveSet* set);
 121   //void log_option(JSON_TYPE t, JSON_VAL* v, const key* option_key, const key* enclosing_key);
 122 
 123   CompilerDirectives* current_dir;
 124   DirectiveSet*       current_dirset;
 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