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

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

Issue 1366563002: [builtins] Re-add similar String wrapper optimization for StringAdd. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 3 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/bootstrapper.cc ('k') | src/contexts.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 59d3a8b7d1e16742bfd31737d18259bc77fdc9af..9f782225c1614648c95537e68bc08eb4ec7f0598 100644
--- a/src/code-stubs-hydrogen.cc
+++ b/src/code-stubs-hydrogen.cc
@@ -113,7 +113,8 @@ class CodeStubGraphBuilderBase : public HGraphBuilder {
HValue* shared_info,
HValue* native_context);
- HValue* CheckString(HValue* input, bool convert);
+ HValue* BuildToString(HValue* input, bool convert);
+ HValue* BuildToPrimitive(HValue* input, HValue* input_map);
private:
HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder);
@@ -1458,7 +1459,7 @@ Handle<Code> BinaryOpWithAllocationSiteStub::GenerateCode() {
}
-HValue* CodeStubGraphBuilderBase::CheckString(HValue* input, bool convert) {
+HValue* CodeStubGraphBuilderBase::BuildToString(HValue* input, bool convert) {
if (!convert) return BuildCheckString(input);
IfBuilder if_inputissmi(this);
HValue* inputissmi = if_inputissmi.If<HIsSmiAndBranch>(input);
@@ -1496,11 +1497,8 @@ HValue* CodeStubGraphBuilderBase::CheckString(HValue* input, bool convert) {
}
if_inputisprimitive.Else();
{
- // TODO(bmeurer): Add support for fast ToPrimitive conversion using
- // a dedicated ToPrimitiveStub.
- Add<HPushArguments>(input);
- Push(Add<HCallRuntime>(Runtime::FunctionForId(Runtime::kToPrimitive),
- 1));
+ // Convert the input to a primitive.
+ Push(BuildToPrimitive(input, input_map));
}
if_inputisprimitive.End();
// Convert the primitive to a string value.
@@ -1518,6 +1516,83 @@ HValue* CodeStubGraphBuilderBase::CheckString(HValue* input, bool convert) {
}
+HValue* CodeStubGraphBuilderBase::BuildToPrimitive(HValue* input,
+ HValue* input_map) {
+ // Get the native context of the caller.
+ HValue* native_context = BuildGetNativeContext();
+
+ // Determine the initial map of the %ObjectPrototype%.
+ HValue* object_function_prototype_map =
+ Add<HLoadNamedField>(native_context, nullptr,
+ HObjectAccess::ForContextSlot(
+ Context::OBJECT_FUNCTION_PROTOTYPE_MAP_INDEX));
+
+ // Determine the initial map of the %StringPrototype%.
+ HValue* string_function_prototype_map =
+ Add<HLoadNamedField>(native_context, nullptr,
+ HObjectAccess::ForContextSlot(
+ Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX));
+
+ // Determine the initial map of the String function.
+ HValue* string_function = Add<HLoadNamedField>(
+ native_context, nullptr,
+ HObjectAccess::ForContextSlot(Context::STRING_FUNCTION_INDEX));
+ HValue* string_function_initial_map = Add<HLoadNamedField>(
+ string_function, nullptr, HObjectAccess::ForPrototypeOrInitialMap());
+
+ // Determine the map of the [[Prototype]] of {input}.
+ HValue* input_prototype =
+ Add<HLoadNamedField>(input_map, nullptr, HObjectAccess::ForPrototype());
+ HValue* input_prototype_map =
+ Add<HLoadNamedField>(input_prototype, nullptr, HObjectAccess::ForMap());
+
+ // For string wrappers (JSValue instances with [[StringData]] internal
+ // fields), we can shortcirciut the ToPrimitive if
+ //
+ // (a) the {input} map matches the initial map of the String function,
+ // (b) the {input} [[Prototype]] is the unmodified %StringPrototype% (i.e.
+ // no one monkey-patched toString, @@toPrimitive or valueOf), and
+ // (c) the %ObjectPrototype% (i.e. the [[Prototype]] of the
+ // %StringPrototype%) is also unmodified, that is no one sneaked a
+ // @@toPrimitive into the %ObjectPrototype%.
+ //
+ // If all these assumptions hold, we can just take the [[StringData]] value
+ // and return it.
+ // TODO(bmeurer): This just repairs a regression introduced by removing the
+ // weird (and broken) intrinsic %_IsStringWrapperSafeForDefaultValue, which
+ // was intendend to something similar to this, although less efficient and
+ // wrong in the presence of @@toPrimitive. Long-term we might want to move
+ // into the direction of having a ToPrimitiveStub that can do common cases
+ // while staying in JavaScript land (i.e. not going to C++).
+ IfBuilder if_inputisstringwrapper(this);
+ if_inputisstringwrapper.If<HCompareObjectEqAndBranch>(
+ input_map, string_function_initial_map);
+ if_inputisstringwrapper.And();
+ if_inputisstringwrapper.If<HCompareObjectEqAndBranch>(
+ input_prototype_map, string_function_prototype_map);
+ if_inputisstringwrapper.And();
+ if_inputisstringwrapper.If<HCompareObjectEqAndBranch>(
+ Add<HLoadNamedField>(Add<HLoadNamedField>(input_prototype_map, nullptr,
+ HObjectAccess::ForPrototype()),
+ nullptr, HObjectAccess::ForMap()),
+ object_function_prototype_map);
+ if_inputisstringwrapper.Then();
+ {
+ Push(BuildLoadNamedField(
+ input, FieldIndex::ForInObjectOffset(JSValue::kValueOffset)));
+ }
+ if_inputisstringwrapper.Else();
+ {
+ // TODO(bmeurer): Add support for fast ToPrimitive conversion using
+ // a dedicated ToPrimitiveStub.
+ Add<HPushArguments>(input);
+ Push(Add<HCallRuntime>(Runtime::FunctionForId(Runtime::kToPrimitive), 1));
+ }
+ if_inputisstringwrapper.End();
+ return Pop();
+}
+
+
template <>
HValue* CodeStubGraphBuilder<StringAddStub>::BuildCodeInitializedStub() {
StringAddStub* stub = casted_stub();
@@ -1530,11 +1605,11 @@ HValue* CodeStubGraphBuilder<StringAddStub>::BuildCodeInitializedStub() {
// Make sure that both arguments are strings if not known in advance.
if ((flags & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT) {
left =
- CheckString(left, (flags & STRING_ADD_CONVERT) == STRING_ADD_CONVERT);
+ BuildToString(left, (flags & STRING_ADD_CONVERT) == STRING_ADD_CONVERT);
}
if ((flags & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT) {
- right =
- CheckString(right, (flags & STRING_ADD_CONVERT) == STRING_ADD_CONVERT);
+ right = BuildToString(right,
+ (flags & STRING_ADD_CONVERT) == STRING_ADD_CONVERT);
}
return BuildStringAdd(left, right, HAllocationMode(pretenure_flag));
« no previous file with comments | « src/bootstrapper.cc ('k') | src/contexts.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698