Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(439)

Unified Diff: src/code-stubs-hydrogen.cc

Issue 22562002: Convert FastNewClosureStub into hydrogen. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Nit fixin Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/code-stubs.cc ('k') | src/hydrogen.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/code-stubs-hydrogen.cc
diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
index 3e18138eb2b459bc9b0f56392aae3334d2b643f6..35927f494bd6445eca6f1f303ecd1f455c196514 100644
--- a/src/code-stubs-hydrogen.cc
+++ b/src/code-stubs-hydrogen.cc
@@ -112,6 +112,13 @@ class CodeStubGraphBuilderBase : public HGraphBuilder {
HValue* BuildInternalArrayConstructor(ElementsKind kind,
ArgumentClass argument_class);
+ void BuildInstallOptimizedCode(HValue* js_function, HValue* native_context,
+ HValue* code_object);
+ void BuildInstallCode(HValue* js_function, HValue* shared_info);
+ void BuildInstallFromOptimizedCodeMap(HValue* js_function,
+ HValue* shared_info,
+ HValue* native_context);
+
private:
HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder);
HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder,
@@ -904,4 +911,194 @@ Handle<Code> ElementsTransitionAndStoreStub::GenerateCode() {
}
+void CodeStubGraphBuilderBase::BuildInstallOptimizedCode(
+ HValue* js_function,
+ HValue* native_context,
+ HValue* code_object) {
+ Counters* counters = isolate()->counters();
+ AddIncrementCounter(counters->fast_new_closure_install_optimized(),
+ context());
+
+ // TODO(fschneider): Idea: store proper code pointers in the optimized code
+ // map and either unmangle them on marking or do nothing as the whole map is
+ // discarded on major GC anyway.
+ Add<HStoreCodeEntry>(js_function, code_object);
+
+ // Now link a function into a list of optimized functions.
+ HValue* optimized_functions_list = Add<HLoadNamedField>(native_context,
+ HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST));
+ Add<HStoreNamedField>(js_function,
+ HObjectAccess::ForNextFunctionLinkPointer(),
+ optimized_functions_list);
+
+ // This store is the only one that should have a write barrier.
+ Add<HStoreNamedField>(native_context,
+ HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST),
+ js_function);
+}
+
+
+void CodeStubGraphBuilderBase::BuildInstallCode(HValue* js_function,
+ HValue* shared_info) {
+ Add<HStoreNamedField>(js_function,
+ HObjectAccess::ForNextFunctionLinkPointer(),
+ graph()->GetConstantUndefined());
+ HValue* code_object = Add<HLoadNamedField>(shared_info,
+ HObjectAccess::ForCodeOffset());
+ Add<HStoreCodeEntry>(js_function, code_object);
+}
+
+
+void CodeStubGraphBuilderBase::BuildInstallFromOptimizedCodeMap(
+ HValue* js_function,
+ HValue* shared_info,
+ HValue* native_context) {
+ Counters* counters = isolate()->counters();
+ IfBuilder is_optimized(this);
+ HInstruction* optimized_map = Add<HLoadNamedField>(shared_info,
+ HObjectAccess::ForOptimizedCodeMap());
+ HValue* null_constant = Add<HConstant>(0);
+ is_optimized.If<HCompareObjectEqAndBranch>(optimized_map, null_constant);
+ is_optimized.Then();
+ {
+ BuildInstallCode(js_function, shared_info);
+ }
+ is_optimized.Else();
+ {
+ AddIncrementCounter(counters->fast_new_closure_try_optimized(), context());
+ // optimized_map points to fixed array of 3-element entries
+ // (native context, optimized code, literals).
+ // Map must never be empty, so check the first elements.
+ Label install_optimized;
+ HValue* first_context_slot = Add<HLoadNamedField>(optimized_map,
+ HObjectAccess::ForFirstContextSlot());
+ IfBuilder already_in(this);
+ already_in.If<HCompareObjectEqAndBranch>(native_context,
+ first_context_slot);
+ already_in.Then();
+ {
+ HValue* code_object = Add<HLoadNamedField>(optimized_map,
+ HObjectAccess::ForFirstCodeSlot());
+ BuildInstallOptimizedCode(js_function, native_context, code_object);
+ }
+ already_in.Else();
+ {
+ HValue* shared_function_entry_length =
+ Add<HConstant>(SharedFunctionInfo::kEntryLength);
+ LoopBuilder loop_builder(this,
+ context(),
+ LoopBuilder::kPostDecrement,
+ shared_function_entry_length);
+ HValue* array_length = Add<HLoadNamedField>(optimized_map,
+ HObjectAccess::ForFixedArrayLength());
+ HValue* key = loop_builder.BeginBody(array_length,
+ graph()->GetConstant0(),
+ Token::GT);
+ {
+ // Iterate through the rest of map backwards.
+ // Do not double check first entry.
+ HValue* second_entry_index =
+ Add<HConstant>(SharedFunctionInfo::kSecondEntryIndex);
+ IfBuilder restore_check(this);
+ restore_check.If<HCompareNumericAndBranch>(key, second_entry_index,
+ Token::EQ);
+ restore_check.Then();
+ {
+ // Store the unoptimized code
+ BuildInstallCode(js_function, shared_info);
+ loop_builder.Break();
+ }
+ restore_check.Else();
+ {
+ HValue* keyed_minus = AddInstruction(HSub::New(zone(), context(), key,
+ shared_function_entry_length));
+ HInstruction* keyed_lookup = Add<HLoadKeyed>(optimized_map,
+ keyed_minus, static_cast<HValue*>(NULL), FAST_ELEMENTS);
+ IfBuilder done_check(this);
+ done_check.If<HCompareObjectEqAndBranch>(native_context,
+ keyed_lookup);
+ done_check.Then();
+ {
+ // Hit: fetch the optimized code.
+ HValue* keyed_plus = AddInstruction(HAdd::New(zone(), context(),
+ keyed_minus, graph()->GetConstant1()));
+ HValue* code_object = Add<HLoadKeyed>(optimized_map,
+ keyed_plus, static_cast<HValue*>(NULL), FAST_ELEMENTS);
+ BuildInstallOptimizedCode(js_function, native_context, code_object);
+
+ // Fall out of the loop
+ loop_builder.Break();
+ }
+ done_check.Else();
+ done_check.End();
+ }
+ restore_check.End();
+ }
+ loop_builder.EndBody();
+ }
+ already_in.End();
+ }
+ is_optimized.End();
+}
+
+
+template<>
+HValue* CodeStubGraphBuilder<FastNewClosureStub>::BuildCodeStub() {
+ Counters* counters = isolate()->counters();
+ Factory* factory = isolate()->factory();
+ HInstruction* empty_fixed_array =
+ Add<HConstant>(factory->empty_fixed_array());
+ HValue* shared_info = GetParameter(0);
+
+ // Create a new closure from the given function info in new space
+ HValue* size = Add<HConstant>(JSFunction::kSize);
+ HInstruction* js_function = Add<HAllocate>(size, HType::JSObject(),
+ NOT_TENURED, JS_FUNCTION_TYPE);
+ AddIncrementCounter(counters->fast_new_closure_total(), context());
+
+ int map_index = Context::FunctionMapIndex(casted_stub()->language_mode(),
+ casted_stub()->is_generator());
+
+ // Compute the function map in the current native context and set that
+ // as the map of the allocated object.
+ HInstruction* native_context = BuildGetNativeContext();
+ HInstruction* map_slot_value = Add<HLoadNamedField>(native_context,
+ HObjectAccess::ForContextSlot(map_index));
+ Add<HStoreNamedField>(js_function, HObjectAccess::ForMap(), map_slot_value);
+
+ // Initialize the rest of the function.
+ Add<HStoreNamedField>(js_function, HObjectAccess::ForPropertiesPointer(),
+ empty_fixed_array);
+ Add<HStoreNamedField>(js_function, HObjectAccess::ForElementsPointer(),
+ empty_fixed_array);
+ Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(),
+ empty_fixed_array);
+ Add<HStoreNamedField>(js_function, HObjectAccess::ForPrototypeOrInitialMap(),
+ graph()->GetConstantHole());
+ Add<HStoreNamedField>(js_function,
+ HObjectAccess::ForSharedFunctionInfoPointer(),
+ shared_info);
+ Add<HStoreNamedField>(js_function, HObjectAccess::ForFunctionContextPointer(),
+ shared_info);
+ Add<HStoreNamedField>(js_function, HObjectAccess::ForFunctionContextPointer(),
+ context());
+
+ // Initialize the code pointer in the function to be the one
+ // found in the shared function info object.
+ // But first check if there is an optimized version for our context.
+ if (FLAG_cache_optimized_code) {
+ BuildInstallFromOptimizedCodeMap(js_function, shared_info, native_context);
+ } else {
+ BuildInstallCode(js_function, shared_info);
+ }
+
+ return js_function;
+}
+
+
+Handle<Code> FastNewClosureStub::GenerateCode() {
+ return DoGenerateCode(this);
+}
+
+
} } // namespace v8::internal
« no previous file with comments | « src/code-stubs.cc ('k') | src/hydrogen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698