void BCEscapeAnalyzer::invoke(StateInfo &state, Bytecodes::Code code, ciMethod* target, ciKlass* holder) {
  int i;

  // retrieve information about the callee
  ciInstanceKlass* klass = target->holder();
  ciInstanceKlass* calling_klass = method()->holder();
  ciInstanceKlass* callee_holder = ciEnv::get_instance_klass_for_declared_method_holder(holder);
  ciInstanceKlass* actual_recv = callee_holder;
  
  // compute size of arguments
  int arg_size = target->arg_size();
  if (!target->is_loaded() && code == Bytecodes::_invokestatic) {
    arg_size--;
  }
  int arg_base = MAX2(state._stack_height - arg_size, 0);

  // direct recursive calls are skipped if they can be bound statically without introducing
  // dependencies and if parameters are passed at the same position as in the current method
  // other calls are skipped if there are no unescaped arguments passed to them
  bool directly_recursive = (method() == target) &&
               (code != Bytecodes::_invokevirtual || target->is_final_method() || state._stack[arg_base] .is_empty());

  // check if analysis of callee can safely be skipped
  bool skip_callee = true;
  for (i = state._stack_height - 1; i >= arg_base && skip_callee; i--) {
    ArgumentMap arg = state._stack[i];
    skip_callee = !is_argument(arg) || !is_arg_stack(arg) || (directly_recursive && arg.is_singleton(i - arg_base));
  }
  if (skip_callee) {
    TRACE_BCEA(3, tty->print_cr("[EA] skipping method %s::%s", holder->name()->as_utf8(), target->name()->as_utf8()));
    for (i = 0; i < arg_size; i++) {
      set_method_escape(state.raw_pop());
    }
    return;
  }

  // determine actual method (use CHA if necessary)
  ciMethod* inline_target = NULL;
  if (target->is_loaded() && klass->is_loaded()
&&(klass->is_initialized()||(klass->is_interface()&&target->holder()->is_initialized()))
      && target->will_link(klass, callee_holder, code)) {
    if (code == Bytecodes::_invokestatic
        || code == Bytecodes::_invokespecial
||(code==Bytecodes::_invokevirtual&&target->is_final_method())){
      inline_target = target;
    } else {
      inline_target = target->find_monomorphic_target(calling_klass, callee_holder, actual_recv);
    }
  }

  if (inline_target != NULL && !is_recursive_call(inline_target)) {
    // analyze callee
    BCEscapeAnalyzer analyzer(inline_target, this);
    
    // adjust escape state of actual parameters
    bool must_record_dependencies = false;
    for (i = arg_size - 1; i >= 0; i--) {
      ArgumentMap arg = state.raw_pop();
      if (!is_argument(arg))
        continue;
      if (!is_arg_stack(arg)) {
        // arguments have already been recognized as escaping
      } else if (analyzer.is_arg_stack(i) && !analyzer.is_arg_returned(i)) {
        set_method_escape(arg);
        must_record_dependencies = true;
      } else {
        set_global_escape(arg);
      }
    }

    // record dependencies if at least one parameter retained stack-allocatable
    if (must_record_dependencies) {
if(code==Bytecodes::_invokeinterface||(code==Bytecodes::_invokevirtual&&!target->is_final_method())){
        _dependencies.append(actual_recv);
        _dependencies.append(inline_target);
      }
      _dependencies.appendAll(analyzer.dependencies());
    }
  } else {
    TRACE_BCEA(1, tty->print_cr("[EA] virtual method %s is not monomorphic.",
				target->name()->as_utf8()));
    // conservatively mark all actual parameters as escaping globally
    for (i = 0; i < arg_size; i++) {
      ArgumentMap arg = state.raw_pop();
      if (!is_argument(arg))
        continue;
      set_global_escape(arg);
    }
  }
}
void fix_file (const std::wstring& in, const std::wstring& out)
{
    std::wcout << L"in:" << in << L"\nout:" << out << L'\n';
    rsc::istream fsin(in);
    rsc::ostream fsout(out);

    int count = 0;
    bool quote = false;
    char16_t before = L'\0';
    char16_t current, after;
    fsin.get(current);
    while (!fsin.eof())
    {
        fsin.get(after);

        if (is_double_quote(current))
            quote = !quote;

        if (!quote)
        {
            // not in quote, do nothing
        }
        else if (is_floating_vowel(current))
        {
            if (is_long_tail(before))
            {
                count++;
                current = move_floating_left(current);
            }
        }
        else if (is_floating_vowel(current))
        {
            if (is_long_tail(before))
            {
                count++;
                current = move_floating_left(current);
            }
        }
        else if (is_tone_marker(current))
        {
            if (is_floating_vowel(before))
            {
                if (is_long_tail(before))
                {
                    count++;
                    current = move_tone_marker_left_height(current);
                }
            }
            else if (is_long_tail(before))
            {
                if (is_backward_floating_vowel(after))
                {
                    count++;
                    current = move_tone_marker_left_height(current);
                }
                else
                {
                    count++;
                    current = move_tone_marker_left_low(current);
                }
            }
            else if (!is_backward_floating_vowel(after))
            {
                count++;
                current = move_tone_marker_low(current);
            }
        }
        else if (is_lower_foot(current))
        {
            if (is_lower_vowel(after))
            {
                count++;
                current = strip_lower_foot(current);
            }
        }
        else if (is_lower_vowel(current))
        {
            if (is_lower_tail(before))
            {
                count++;
                current = move_lower_vowel_left(current);
            }
        }

        fsout.put(current);

        if (!quote)
        {
        }
        else if (is_digit(current))
        {
            if (is_argument(before) && is_argument(after))
            {
                count++;
                fsout.put(argument_prefix());
            }
        }

        before = current;
        current = after;
    } // while

    if (count > 0)
        std::wcout << L'\n';
    std::wcout << L"fixed:" << count << std::endl;
}
示例#3
0
/*
 * config_reader_get_scenarios -- return scenarios from config file
 *
 * This function reads the config file and returns a list of scenarios.
 * Each scenario contains a list of key/value arguments.
 * The scenario's arguments are merged with arguments from global section.
 */
int
config_reader_get_scenarios(struct config_reader *cr,
			    struct scenarios **scenarios)
{
	/*
	 * Read all groups.
	 * The config file must have at least one group, otherwise
	 * it is considered as invalid.
	 */
	gsize ngroups;
	gsize g;
	gchar **groups = g_key_file_get_groups(cr->key_file, &ngroups);
	assert(nullptr != groups);
	if (!groups)
		return -1;

	/*
	 * Check if global section is present and read keys from it.
	 */
	int ret = 0;
	int has_global =
		g_key_file_has_group(cr->key_file, SECTION_GLOBAL) == TRUE;
	gsize ngkeys;
	gchar **gkeys = nullptr;
	struct scenarios *s;
	if (has_global) {
		gkeys = g_key_file_get_keys(cr->key_file, SECTION_GLOBAL,
					    &ngkeys, nullptr);
		assert(nullptr != gkeys);
		if (!gkeys) {
			ret = -1;
			goto err_groups;
		}
	}

	s = scenarios_alloc();
	assert(nullptr != s);
	if (!s) {
		ret = -1;
		goto err_gkeys;
	}

	for (g = 0; g < ngroups; g++) {
		/*
		 * Check whether a group is a scenario
		 * or global section.
		 */
		if (!is_scenario(groups[g]))
			continue;

		/*
		 * Check for KEY_BENCHMARK which contains benchmark name.
		 * If not present the benchmark name is the same as the
		 * name of the section.
		 */
		struct scenario *scenario = nullptr;
		if (g_key_file_has_key(cr->key_file, groups[g], KEY_BENCHMARK,
				       nullptr) == FALSE) {
			scenario = scenario_alloc(groups[g], groups[g]);
			assert(scenario != nullptr);
		} else {
			gchar *benchmark =
				g_key_file_get_value(cr->key_file, groups[g],
						     KEY_BENCHMARK, nullptr);
			assert(benchmark != nullptr);
			if (!benchmark) {
				ret = -1;
				goto err_scenarios;
			}
			scenario = scenario_alloc(groups[g], benchmark);
			assert(scenario != nullptr);
			free(benchmark);
		}

		gsize k;
		if (has_global) {
			/*
			 * Merge key/values from global section.
			 */
			for (k = 0; k < ngkeys; k++) {
				if (g_key_file_has_key(cr->key_file, groups[g],
						       gkeys[k],
						       nullptr) == TRUE)
					continue;

				if (!is_argument(gkeys[k]))
					continue;

				char *value = g_key_file_get_value(
					cr->key_file, SECTION_GLOBAL, gkeys[k],
					nullptr);
				assert(nullptr != value);
				if (!value) {
					ret = -1;
					goto err_scenarios;
				}

				struct kv *kv = kv_alloc(gkeys[k], value);
				assert(nullptr != kv);

				free(value);
				if (!kv) {
					ret = -1;
					goto err_scenarios;
				}

				TAILQ_INSERT_TAIL(&scenario->head, kv, next);
			}
		}

		/* check for group name */
		if (g_key_file_has_key(cr->key_file, groups[g], KEY_GROUP,
				       nullptr) != FALSE) {
			gchar *group = g_key_file_get_value(
				cr->key_file, groups[g], KEY_GROUP, nullptr);
			assert(group != nullptr);
			scenario_set_group(scenario, group);
		} else if (g_key_file_has_key(cr->key_file, SECTION_GLOBAL,
					      KEY_GROUP, nullptr) != FALSE) {
			gchar *group = g_key_file_get_value(cr->key_file,
							    SECTION_GLOBAL,
							    KEY_GROUP, nullptr);
			scenario_set_group(scenario, group);
		}

		gsize nkeys;
		gchar **keys = g_key_file_get_keys(cr->key_file, groups[g],
						   &nkeys, nullptr);
		assert(nullptr != keys);
		if (!keys) {
			ret = -1;
			goto err_scenarios;
		}

		/*
		 * Read key/values from the scenario's section.
		 */
		for (k = 0; k < nkeys; k++) {
			if (!is_argument(keys[k]))
				continue;
			char *value = g_key_file_get_value(
				cr->key_file, groups[g], keys[k], nullptr);
			assert(nullptr != value);
			if (!value) {
				ret = -1;
				g_strfreev(keys);
				goto err_scenarios;
			}

			struct kv *kv = kv_alloc(keys[k], value);
			assert(nullptr != kv);

			free(value);
			if (!kv) {
				g_strfreev(keys);
				ret = -1;
				goto err_scenarios;
			}

			TAILQ_INSERT_TAIL(&scenario->head, kv, next);
		}

		g_strfreev(keys);

		TAILQ_INSERT_TAIL(&s->head, scenario, next);
	}

	g_strfreev(gkeys);
	g_strfreev(groups);

	*scenarios = s;
	return 0;
err_scenarios:
	scenarios_free(s);
err_gkeys:
	g_strfreev(gkeys);
err_groups:
	g_strfreev(groups);
	return ret;
}
示例#4
0
/*
 * config_reader_get_scenarios -- return scenarios from config file
 *
 * This function reads the config file and returns a list of scenarios.
 * Each scenario contains a list of key/value arguments.
 * The scenario's arguments are merged with arguments from global section.
 */
int
config_reader_get_scenarios(struct config_reader *cr,
			    struct scenarios **scenarios)
{
	/*
	 * Read all groups.
	 * The config file must have at least one group, otherwise
	 * it is considered as invalid.
	 */
	int ret = 0;

	TCHAR *sections = (TCHAR *)malloc(sizeof(TCHAR) * SIZEOF_SECTION);
	if (!sections)
		return -1;

	GetPrivateProfileSectionNames(sections, SIZEOF_SECTION, cr->lpFileName);

	if (NULL_LIST_EMPTY(sections)) {
		ret = -1;
		goto err_sections;
	}

	/*
	 * Check if global section is present and read it.
	 */
	TCHAR *global = (TCHAR *)malloc(sizeof(TCHAR) * SIZEOF_SECTION);
	if (!global)
		return -1;

	GetPrivateProfileSection(SECTION_GLOBAL, global, SIZEOF_SECTION,
				 cr->lpFileName);
	KV_LIST global_kv = KV_LIST_INIT(global);

	int has_global = !KV_LIST_EMPTY(global_kv);

	struct scenarios *s = scenarios_alloc();
	assert(NULL != s);
	if (!s) {
		ret = -1;
		goto err_gkeys;
	}

	LPTSTR global_group = NULL;
	for (KV_LIST it = global_kv; !KV_LIST_EMPTY(it); KV_LIST_NEXT(it)) {
		if (_tcscmp(KV_LIST_KEY(it), KEY_GROUP) == 0) {
			global_group = KV_LIST_VALUE(it);
			break;
		}
	}
	TCHAR *section;
	for (LPTSTR group_name = sections; !NULL_LIST_EMPTY(group_name);
	     group_name = NULL_LIST_NEXT(group_name)) {
		/*
		 * Check whether a group is a scenario
		 * or global section.
		 */
		if (!is_scenario(group_name))
			continue;

		/*
		 * Check for KEY_BENCHMARK which contains benchmark name.
		 * If not present the benchmark name is the same as the
		 * name of the section.
		 */
		section = (TCHAR *)malloc(sizeof(TCHAR) * SIZEOF_SECTION);
		if (!section)
			ret = -1;
		GetPrivateProfileSection(group_name, section, SIZEOF_SECTION,
					 cr->lpFileName);

		KV_LIST section_kv = KV_LIST_INIT(section);
		struct scenario *scenario = NULL;
		LPTSTR name = NULL;
		LPTSTR group = NULL;
		for (KV_LIST it = section_kv; !KV_LIST_EMPTY(it);
		     KV_LIST_NEXT(it)) {
			if (_tcscmp(KV_LIST_KEY(it), KEY_BENCHMARK) == 0) {
				name = KV_LIST_VALUE(it);
			}
			if (_tcscmp(KV_LIST_KEY(it), KEY_GROUP) == 0) {
				group = KV_LIST_VALUE(it);
			}
		}
		if (name == NULL) {
			scenario = scenario_alloc((const char *)group_name,
						  (const char *)group_name);
		} else {
			scenario = scenario_alloc((const char *)group_name,
						  (const char *)name);
		}
		assert(scenario != NULL);

		if (has_global) {
			/*
			 * Merge key/values from global section.
			 */
			for (KV_LIST it = global_kv; !KV_LIST_EMPTY(it);
			     KV_LIST_NEXT(it)) {
				LPTSTR key = KV_LIST_KEY(it);
				if (!is_argument(key))
					continue;

				LPTSTR value = KV_LIST_VALUE(it);
				assert(NULL != value);
				if (!value) {
					ret = -1;
					goto err_scenarios;
				}

				struct kv *kv = kv_alloc((const char *)key,
							 (const char *)value);
				assert(NULL != kv);

				if (!kv) {
					ret = -1;
					goto err_scenarios;
				}

				TAILQ_INSERT_TAIL(&scenario->head, kv, next);
			}
		}

		/* check for group name */
		if (group) {
			scenario_set_group(scenario, (const char *)group);
		} else if (global_group) {
			scenario_set_group(scenario,
					   (const char *)global_group);
		}

		for (KV_LIST it = section_kv; !KV_LIST_EMPTY(it);
		     KV_LIST_NEXT(it)) {
			LPTSTR key = KV_LIST_KEY(it);
			if (!is_argument(key))
				continue;

			LPTSTR value = KV_LIST_VALUE(it);
			assert(NULL != value);
			if (!value) {
				ret = -1;
				goto err_scenarios;
			}

			struct kv *kv = kv_alloc((const char *)key,
						 (const char *)value);
			assert(NULL != kv);

			if (!kv) {
				ret = -1;
				goto err_scenarios;
			}

			TAILQ_INSERT_TAIL(&scenario->head, kv, next);
		}
		TAILQ_INSERT_TAIL(&s->head, scenario, next);

		free(section);
	}
	*scenarios = s;

	free(global);
	free(sections);
	return 0;

err_scenarios:
	free(section);
	scenarios_free(s);
err_gkeys:
	free(global);
err_sections:
	free(sections);
	return ret;
}