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

Side by Side 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, 2 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 unified diff | Download patch
« no previous file with comments | « src/bootstrapper.cc ('k') | src/contexts.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/code-stubs.h" 5 #include "src/code-stubs.h"
6 6
7 #include "src/bailout-reason.h" 7 #include "src/bailout-reason.h"
8 #include "src/field-index.h" 8 #include "src/field-index.h"
9 #include "src/hydrogen.h" 9 #include "src/hydrogen.h"
10 #include "src/ic/ic.h" 10 #include "src/ic/ic.h"
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 HValue* code_object, HValue* literals); 106 HValue* code_object, HValue* literals);
107 void BuildInstallCode(HValue* js_function, HValue* shared_info); 107 void BuildInstallCode(HValue* js_function, HValue* shared_info);
108 108
109 HInstruction* LoadFromOptimizedCodeMap(HValue* optimized_map, 109 HInstruction* LoadFromOptimizedCodeMap(HValue* optimized_map,
110 HValue* iterator, 110 HValue* iterator,
111 int field_offset); 111 int field_offset);
112 void BuildInstallFromOptimizedCodeMap(HValue* js_function, 112 void BuildInstallFromOptimizedCodeMap(HValue* js_function,
113 HValue* shared_info, 113 HValue* shared_info,
114 HValue* native_context); 114 HValue* native_context);
115 115
116 HValue* CheckString(HValue* input, bool convert); 116 HValue* BuildToString(HValue* input, bool convert);
117 HValue* BuildToPrimitive(HValue* input, HValue* input_map);
117 118
118 private: 119 private:
119 HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder); 120 HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder);
120 HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder, 121 HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder,
121 ElementsKind kind); 122 ElementsKind kind);
122 123
123 base::SmartArrayPointer<HParameter*> parameters_; 124 base::SmartArrayPointer<HParameter*> parameters_;
124 HValue* arguments_length_; 125 HValue* arguments_length_;
125 CompilationInfo* info_; 126 CompilationInfo* info_;
126 CodeStubDescriptor descriptor_; 127 CodeStubDescriptor descriptor_;
(...skipping 1324 matching lines...) Expand 10 before | Expand all | Expand 10 after
1451 result_type, state.fixed_right_arg(), 1452 result_type, state.fixed_right_arg(),
1452 allocation_mode, state.strength()); 1453 allocation_mode, state.strength());
1453 } 1454 }
1454 1455
1455 1456
1456 Handle<Code> BinaryOpWithAllocationSiteStub::GenerateCode() { 1457 Handle<Code> BinaryOpWithAllocationSiteStub::GenerateCode() {
1457 return DoGenerateCode(this); 1458 return DoGenerateCode(this);
1458 } 1459 }
1459 1460
1460 1461
1461 HValue* CodeStubGraphBuilderBase::CheckString(HValue* input, bool convert) { 1462 HValue* CodeStubGraphBuilderBase::BuildToString(HValue* input, bool convert) {
1462 if (!convert) return BuildCheckString(input); 1463 if (!convert) return BuildCheckString(input);
1463 IfBuilder if_inputissmi(this); 1464 IfBuilder if_inputissmi(this);
1464 HValue* inputissmi = if_inputissmi.If<HIsSmiAndBranch>(input); 1465 HValue* inputissmi = if_inputissmi.If<HIsSmiAndBranch>(input);
1465 if_inputissmi.Then(); 1466 if_inputissmi.Then();
1466 { 1467 {
1467 // Convert the input smi to a string. 1468 // Convert the input smi to a string.
1468 Push(BuildNumberToString(input, Type::SignedSmall())); 1469 Push(BuildNumberToString(input, Type::SignedSmall()));
1469 } 1470 }
1470 if_inputissmi.Else(); 1471 if_inputissmi.Else();
1471 { 1472 {
(...skipping 17 matching lines...) Expand all
1489 STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE); 1490 STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE);
1490 if_inputisprimitive.If<HCompareNumericAndBranch>( 1491 if_inputisprimitive.If<HCompareNumericAndBranch>(
1491 input_instance_type, Add<HConstant>(LAST_PRIMITIVE_TYPE), Token::LTE); 1492 input_instance_type, Add<HConstant>(LAST_PRIMITIVE_TYPE), Token::LTE);
1492 if_inputisprimitive.Then(); 1493 if_inputisprimitive.Then();
1493 { 1494 {
1494 // The input is already a primitive. 1495 // The input is already a primitive.
1495 Push(input); 1496 Push(input);
1496 } 1497 }
1497 if_inputisprimitive.Else(); 1498 if_inputisprimitive.Else();
1498 { 1499 {
1499 // TODO(bmeurer): Add support for fast ToPrimitive conversion using 1500 // Convert the input to a primitive.
1500 // a dedicated ToPrimitiveStub. 1501 Push(BuildToPrimitive(input, input_map));
1501 Add<HPushArguments>(input);
1502 Push(Add<HCallRuntime>(Runtime::FunctionForId(Runtime::kToPrimitive),
1503 1));
1504 } 1502 }
1505 if_inputisprimitive.End(); 1503 if_inputisprimitive.End();
1506 // Convert the primitive to a string value. 1504 // Convert the primitive to a string value.
1507 ToStringDescriptor descriptor(isolate()); 1505 ToStringDescriptor descriptor(isolate());
1508 ToStringStub stub(isolate()); 1506 ToStringStub stub(isolate());
1509 HValue* values[] = {context(), Pop()}; 1507 HValue* values[] = {context(), Pop()};
1510 Push(AddUncasted<HCallWithDescriptor>( 1508 Push(AddUncasted<HCallWithDescriptor>(
1511 Add<HConstant>(stub.GetCode()), 0, descriptor, 1509 Add<HConstant>(stub.GetCode()), 0, descriptor,
1512 Vector<HValue*>(values, arraysize(values)))); 1510 Vector<HValue*>(values, arraysize(values))));
1513 } 1511 }
1514 if_inputisstring.End(); 1512 if_inputisstring.End();
1515 } 1513 }
1516 if_inputissmi.End(); 1514 if_inputissmi.End();
1517 return Pop(); 1515 return Pop();
1518 } 1516 }
1519 1517
1520 1518
1519 HValue* CodeStubGraphBuilderBase::BuildToPrimitive(HValue* input,
1520 HValue* input_map) {
1521 // Get the native context of the caller.
1522 HValue* native_context = BuildGetNativeContext();
1523
1524 // Determine the initial map of the %ObjectPrototype%.
1525 HValue* object_function_prototype_map =
1526 Add<HLoadNamedField>(native_context, nullptr,
1527 HObjectAccess::ForContextSlot(
1528 Context::OBJECT_FUNCTION_PROTOTYPE_MAP_INDEX));
1529
1530 // Determine the initial map of the %StringPrototype%.
1531 HValue* string_function_prototype_map =
1532 Add<HLoadNamedField>(native_context, nullptr,
1533 HObjectAccess::ForContextSlot(
1534 Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX));
1535
1536 // Determine the initial map of the String function.
1537 HValue* string_function = Add<HLoadNamedField>(
1538 native_context, nullptr,
1539 HObjectAccess::ForContextSlot(Context::STRING_FUNCTION_INDEX));
1540 HValue* string_function_initial_map = Add<HLoadNamedField>(
1541 string_function, nullptr, HObjectAccess::ForPrototypeOrInitialMap());
1542
1543 // Determine the map of the [[Prototype]] of {input}.
1544 HValue* input_prototype =
1545 Add<HLoadNamedField>(input_map, nullptr, HObjectAccess::ForPrototype());
1546 HValue* input_prototype_map =
1547 Add<HLoadNamedField>(input_prototype, nullptr, HObjectAccess::ForMap());
1548
1549 // For string wrappers (JSValue instances with [[StringData]] internal
1550 // fields), we can shortcirciut the ToPrimitive if
1551 //
1552 // (a) the {input} map matches the initial map of the String function,
1553 // (b) the {input} [[Prototype]] is the unmodified %StringPrototype% (i.e.
1554 // no one monkey-patched toString, @@toPrimitive or valueOf), and
1555 // (c) the %ObjectPrototype% (i.e. the [[Prototype]] of the
1556 // %StringPrototype%) is also unmodified, that is no one sneaked a
1557 // @@toPrimitive into the %ObjectPrototype%.
1558 //
1559 // If all these assumptions hold, we can just take the [[StringData]] value
1560 // and return it.
1561 // TODO(bmeurer): This just repairs a regression introduced by removing the
1562 // weird (and broken) intrinsic %_IsStringWrapperSafeForDefaultValue, which
1563 // was intendend to something similar to this, although less efficient and
1564 // wrong in the presence of @@toPrimitive. Long-term we might want to move
1565 // into the direction of having a ToPrimitiveStub that can do common cases
1566 // while staying in JavaScript land (i.e. not going to C++).
1567 IfBuilder if_inputisstringwrapper(this);
1568 if_inputisstringwrapper.If<HCompareObjectEqAndBranch>(
1569 input_map, string_function_initial_map);
1570 if_inputisstringwrapper.And();
1571 if_inputisstringwrapper.If<HCompareObjectEqAndBranch>(
1572 input_prototype_map, string_function_prototype_map);
1573 if_inputisstringwrapper.And();
1574 if_inputisstringwrapper.If<HCompareObjectEqAndBranch>(
1575 Add<HLoadNamedField>(Add<HLoadNamedField>(input_prototype_map, nullptr,
1576 HObjectAccess::ForPrototype()),
1577 nullptr, HObjectAccess::ForMap()),
1578 object_function_prototype_map);
1579 if_inputisstringwrapper.Then();
1580 {
1581 Push(BuildLoadNamedField(
1582 input, FieldIndex::ForInObjectOffset(JSValue::kValueOffset)));
1583 }
1584 if_inputisstringwrapper.Else();
1585 {
1586 // TODO(bmeurer): Add support for fast ToPrimitive conversion using
1587 // a dedicated ToPrimitiveStub.
1588 Add<HPushArguments>(input);
1589 Push(Add<HCallRuntime>(Runtime::FunctionForId(Runtime::kToPrimitive), 1));
1590 }
1591 if_inputisstringwrapper.End();
1592 return Pop();
1593 }
1594
1595
1521 template <> 1596 template <>
1522 HValue* CodeStubGraphBuilder<StringAddStub>::BuildCodeInitializedStub() { 1597 HValue* CodeStubGraphBuilder<StringAddStub>::BuildCodeInitializedStub() {
1523 StringAddStub* stub = casted_stub(); 1598 StringAddStub* stub = casted_stub();
1524 StringAddFlags flags = stub->flags(); 1599 StringAddFlags flags = stub->flags();
1525 PretenureFlag pretenure_flag = stub->pretenure_flag(); 1600 PretenureFlag pretenure_flag = stub->pretenure_flag();
1526 1601
1527 HValue* left = GetParameter(StringAddStub::kLeft); 1602 HValue* left = GetParameter(StringAddStub::kLeft);
1528 HValue* right = GetParameter(StringAddStub::kRight); 1603 HValue* right = GetParameter(StringAddStub::kRight);
1529 1604
1530 // Make sure that both arguments are strings if not known in advance. 1605 // Make sure that both arguments are strings if not known in advance.
1531 if ((flags & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT) { 1606 if ((flags & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT) {
1532 left = 1607 left =
1533 CheckString(left, (flags & STRING_ADD_CONVERT) == STRING_ADD_CONVERT); 1608 BuildToString(left, (flags & STRING_ADD_CONVERT) == STRING_ADD_CONVERT);
1534 } 1609 }
1535 if ((flags & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT) { 1610 if ((flags & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT) {
1536 right = 1611 right = BuildToString(right,
1537 CheckString(right, (flags & STRING_ADD_CONVERT) == STRING_ADD_CONVERT); 1612 (flags & STRING_ADD_CONVERT) == STRING_ADD_CONVERT);
1538 } 1613 }
1539 1614
1540 return BuildStringAdd(left, right, HAllocationMode(pretenure_flag)); 1615 return BuildStringAdd(left, right, HAllocationMode(pretenure_flag));
1541 } 1616 }
1542 1617
1543 1618
1544 Handle<Code> StringAddStub::GenerateCode() { 1619 Handle<Code> StringAddStub::GenerateCode() {
1545 return DoGenerateCode(this); 1620 return DoGenerateCode(this);
1546 } 1621 }
1547 1622
(...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after
2275 return Pop(); 2350 return Pop();
2276 } 2351 }
2277 2352
2278 2353
2279 Handle<Code> KeyedLoadGenericStub::GenerateCode() { 2354 Handle<Code> KeyedLoadGenericStub::GenerateCode() {
2280 return DoGenerateCode(this); 2355 return DoGenerateCode(this);
2281 } 2356 }
2282 2357
2283 } // namespace internal 2358 } // namespace internal
2284 } // namespace v8 2359 } // namespace v8
OLDNEW
« 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