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

Unified Diff: src/hydrogen.cc

Issue 122463004: Revert "Fix compilation with C++11." and "Allocation site support for monomorphic StringAdds in Bin… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 12 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/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 7bdc02f79c7da451c614949dac604c742906c1fc..3fcce8046d354b469411f19d8927e3a97dfd578d 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -1693,131 +1693,22 @@ HValue* HGraphBuilder::BuildNumberToString(HValue* object,
}
-HAllocate* HGraphBuilder::BuildAllocate(
- HValue* object_size,
- HType type,
- InstanceType instance_type,
- HAllocationMode allocation_mode) {
- // Compute the effective allocation size.
- HValue* size = object_size;
- if (allocation_mode.CreateAllocationMementos()) {
- size = AddUncasted<HAdd>(size, Add<HConstant>(AllocationMemento::kSize));
+HValue* HGraphBuilder::BuildSeqStringSizeFor(HValue* length,
+ String::Encoding encoding) {
+ STATIC_ASSERT((SeqString::kHeaderSize & kObjectAlignmentMask) == 0);
+ HValue* size = length;
+ if (encoding == String::TWO_BYTE_ENCODING) {
+ size = AddUncasted<HShl>(length, graph()->GetConstant1());
size->ClearFlag(HValue::kCanOverflow);
+ size->SetFlag(HValue::kUint32);
}
-
- // Perform the actual allocation.
- HAllocate* object = Add<HAllocate>(
- size, type, allocation_mode.GetPretenureMode(),
- instance_type, allocation_mode.feedback_site());
-
- // Setup the allocation memento.
- if (allocation_mode.CreateAllocationMementos()) {
- BuildCreateAllocationMemento(
- object, object_size, allocation_mode.current_site());
- }
-
- return object;
-}
-
-
-HValue* HGraphBuilder::BuildAddStringLengths(HValue* left_length,
- HValue* right_length) {
- // Compute the combined string length. If the result is larger than the max
- // supported string length, we bailout to the runtime. This is done implicitly
- // when converting the result back to a smi in case the max string length
- // equals the max smi value. Otherwise, for platforms with 32-bit smis, we do
- HValue* length = AddUncasted<HAdd>(left_length, right_length);
- STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
- if (String::kMaxLength != Smi::kMaxValue) {
- IfBuilder if_nooverflow(this);
- if_nooverflow.If<HCompareNumericAndBranch>(
- length, Add<HConstant>(String::kMaxLength), Token::LTE);
- if_nooverflow.Then();
- if_nooverflow.ElseDeopt("String length exceeds limit");
- }
- return length;
-}
-
-
-HValue* HGraphBuilder::BuildCreateConsString(
- HValue* length,
- HValue* left,
- HValue* right,
- HAllocationMode allocation_mode) {
- // Determine the string instance types.
- HInstruction* left_instance_type = AddLoadStringInstanceType(left);
- HInstruction* right_instance_type = AddLoadStringInstanceType(right);
-
- // Allocate the cons string object. HAllocate does not care whether we
- // pass CONS_STRING_TYPE or CONS_ASCII_STRING_TYPE here, so we just use
- // CONS_STRING_TYPE here. Below we decide whether the cons string is
- // one-byte or two-byte and set the appropriate map.
- ASSERT(HAllocate::CompatibleInstanceTypes(CONS_STRING_TYPE,
- CONS_ASCII_STRING_TYPE));
- HAllocate* result = BuildAllocate(Add<HConstant>(ConsString::kSize),
- HType::String(), CONS_STRING_TYPE,
- allocation_mode);
-
- // Compute intersection and difference of instance types.
- HValue* anded_instance_types = AddUncasted<HBitwise>(
- Token::BIT_AND, left_instance_type, right_instance_type);
- HValue* xored_instance_types = AddUncasted<HBitwise>(
- Token::BIT_XOR, left_instance_type, right_instance_type);
-
- // We create a one-byte cons string if
- // 1. both strings are one-byte, or
- // 2. at least one of the strings is two-byte, but happens to contain only
- // one-byte characters.
- // To do this, we check
- // 1. if both strings are one-byte, or if the one-byte data hint is set in
- // both strings, or
- // 2. if one of the strings has the one-byte data hint set and the other
- // string is one-byte.
- IfBuilder if_onebyte(this);
- STATIC_ASSERT(kOneByteStringTag != 0);
- STATIC_ASSERT(kOneByteDataHintMask != 0);
- if_onebyte.If<HCompareNumericAndBranch>(
- AddUncasted<HBitwise>(
- Token::BIT_AND, anded_instance_types,
- Add<HConstant>(static_cast<int32_t>(
- kStringEncodingMask | kOneByteDataHintMask))),
- graph()->GetConstant0(), Token::NE);
- if_onebyte.Or();
- STATIC_ASSERT(kOneByteStringTag != 0 &&
- kOneByteDataHintTag != 0 &&
- kOneByteDataHintTag != kOneByteStringTag);
- if_onebyte.If<HCompareNumericAndBranch>(
- AddUncasted<HBitwise>(
- Token::BIT_AND, xored_instance_types,
- Add<HConstant>(static_cast<int32_t>(
- kOneByteStringTag | kOneByteDataHintTag))),
- Add<HConstant>(static_cast<int32_t>(
- kOneByteStringTag | kOneByteDataHintTag)), Token::EQ);
- if_onebyte.Then();
- {
- // We can safely skip the write barrier for storing the map here.
- Handle<Map> map = isolate()->factory()->cons_ascii_string_map();
- AddStoreMapConstantNoWriteBarrier(result, map);
- }
- if_onebyte.Else();
- {
- // We can safely skip the write barrier for storing the map here.
- Handle<Map> map = isolate()->factory()->cons_string_map();
- AddStoreMapConstantNoWriteBarrier(result, map);
- }
- if_onebyte.End();
-
- // Initialize the cons string fields.
- Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(),
- Add<HConstant>(String::kEmptyHashField));
- Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length);
- Add<HStoreNamedField>(result, HObjectAccess::ForConsStringFirst(), left);
- Add<HStoreNamedField>(result, HObjectAccess::ForConsStringSecond(), right);
-
- // Count the native string addition.
- AddIncrementCounter(isolate()->counters()->string_add_native());
-
- return result;
+ size = AddUncasted<HAdd>(size, Add<HConstant>(static_cast<int32_t>(
+ SeqString::kHeaderSize + kObjectAlignmentMask)));
+ size->ClearFlag(HValue::kCanOverflow);
+ size = AddUncasted<HBitwise>(
+ Token::BIT_AND, size, Add<HConstant>(static_cast<int32_t>(
+ ~kObjectAlignmentMask)));
+ return size;
}
@@ -1843,54 +1734,123 @@ void HGraphBuilder::BuildCopySeqStringChars(HValue* src,
}
-HValue* HGraphBuilder::BuildUncheckedStringAdd(
- HValue* left,
- HValue* right,
- HAllocationMode allocation_mode) {
+HValue* HGraphBuilder::BuildUncheckedStringAdd(HValue* left,
+ HValue* right,
+ PretenureFlag pretenure_flag) {
// Determine the string lengths.
- HValue* left_length = AddLoadStringLength(left);
- HValue* right_length = AddLoadStringLength(right);
+ HValue* left_length = Add<HLoadNamedField>(
+ left, HObjectAccess::ForStringLength());
+ HValue* right_length = Add<HLoadNamedField>(
+ right, HObjectAccess::ForStringLength());
- // Compute the combined string length.
- HValue* length = BuildAddStringLengths(left_length, right_length);
-
- // Do some manual constant folding here.
- if (left_length->IsConstant()) {
- HConstant* c_left_length = HConstant::cast(left_length);
- ASSERT_NE(0, c_left_length->Integer32Value());
- if (c_left_length->Integer32Value() + 1 >= ConsString::kMinLength) {
- // The right string contains at least one character.
- return BuildCreateConsString(length, left, right, allocation_mode);
- }
- } else if (right_length->IsConstant()) {
- HConstant* c_right_length = HConstant::cast(right_length);
- ASSERT_NE(0, c_right_length->Integer32Value());
- if (c_right_length->Integer32Value() + 1 >= ConsString::kMinLength) {
- // The left string contains at least one character.
- return BuildCreateConsString(length, left, right, allocation_mode);
- }
+ // Compute the combined string length. If the result is larger than the max
+ // supported string length, we bailout to the runtime. This is done implicitly
+ // when converting the result back to a smi in case the max string length
+ // equals the max smi valie. Otherwise, for platforms with 32-bit smis, we do
+ HValue* length = AddUncasted<HAdd>(left_length, right_length);
+ STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
+ if (String::kMaxLength != Smi::kMaxValue) {
+ IfBuilder if_nooverflow(this);
+ if_nooverflow.If<HCompareNumericAndBranch>(
+ length, Add<HConstant>(String::kMaxLength), Token::LTE);
+ if_nooverflow.Then();
+ if_nooverflow.ElseDeopt("String length exceeds limit");
}
+ // Determine the string instance types.
+ HLoadNamedField* left_instance_type = Add<HLoadNamedField>(
+ Add<HLoadNamedField>(left, HObjectAccess::ForMap()),
+ HObjectAccess::ForMapInstanceType());
+ HLoadNamedField* right_instance_type = Add<HLoadNamedField>(
+ Add<HLoadNamedField>(right, HObjectAccess::ForMap()),
+ HObjectAccess::ForMapInstanceType());
+
+ // Compute difference of instance types.
+ HValue* xored_instance_types = AddUncasted<HBitwise>(
+ Token::BIT_XOR, left_instance_type, right_instance_type);
+
// Check if we should create a cons string.
IfBuilder if_createcons(this);
if_createcons.If<HCompareNumericAndBranch>(
length, Add<HConstant>(ConsString::kMinLength), Token::GTE);
if_createcons.Then();
{
- // Create a cons string.
- Push(BuildCreateConsString(length, left, right, allocation_mode));
+ // Allocate the cons string object. HAllocate does not care whether we
+ // pass CONS_STRING_TYPE or CONS_ASCII_STRING_TYPE here, so we just use
+ // CONS_STRING_TYPE here. Below we decide whether the cons string is
+ // one-byte or two-byte and set the appropriate map.
+ ASSERT(HAllocate::CompatibleInstanceTypes(CONS_STRING_TYPE,
+ CONS_ASCII_STRING_TYPE));
+ HAllocate* string = Add<HAllocate>(Add<HConstant>(ConsString::kSize),
+ HType::String(), pretenure_flag,
+ CONS_STRING_TYPE);
+
+ // Compute the intersection of instance types.
+ HValue* anded_instance_types = AddUncasted<HBitwise>(
+ Token::BIT_AND, left_instance_type, right_instance_type);
+
+ // We create a one-byte cons string if
+ // 1. both strings are one-byte, or
+ // 2. at least one of the strings is two-byte, but happens to contain only
+ // one-byte characters.
+ // To do this, we check
+ // 1. if both strings are one-byte, or if the one-byte data hint is set in
+ // both strings, or
+ // 2. if one of the strings has the one-byte data hint set and the other
+ // string is one-byte.
+ IfBuilder if_onebyte(this);
+ STATIC_ASSERT(kOneByteStringTag != 0);
+ STATIC_ASSERT(kOneByteDataHintMask != 0);
+ if_onebyte.If<HCompareNumericAndBranch>(
+ AddUncasted<HBitwise>(
+ Token::BIT_AND, anded_instance_types,
+ Add<HConstant>(static_cast<int32_t>(
+ kStringEncodingMask | kOneByteDataHintMask))),
+ graph()->GetConstant0(), Token::NE);
+ if_onebyte.Or();
+ STATIC_ASSERT(kOneByteStringTag != 0 &&
+ kOneByteDataHintTag != 0 &&
+ kOneByteDataHintTag != kOneByteStringTag);
+ if_onebyte.If<HCompareNumericAndBranch>(
+ AddUncasted<HBitwise>(
+ Token::BIT_AND, xored_instance_types,
+ Add<HConstant>(static_cast<int32_t>(
+ kOneByteStringTag | kOneByteDataHintTag))),
+ Add<HConstant>(static_cast<int32_t>(
+ kOneByteStringTag | kOneByteDataHintTag)), Token::EQ);
+ if_onebyte.Then();
+ {
+ // We can safely skip the write barrier for storing the map here.
+ Handle<Map> map = isolate()->factory()->cons_ascii_string_map();
+ AddStoreMapConstantNoWriteBarrier(string, map);
+ }
+ if_onebyte.Else();
+ {
+ // We can safely skip the write barrier for storing the map here.
+ Handle<Map> map = isolate()->factory()->cons_string_map();
+ AddStoreMapConstantNoWriteBarrier(string, map);
+ }
+ if_onebyte.End();
+
+ // Initialize the cons string fields.
+ Add<HStoreNamedField>(string, HObjectAccess::ForStringHashField(),
+ Add<HConstant>(String::kEmptyHashField));
+ Add<HStoreNamedField>(string, HObjectAccess::ForStringLength(), length);
+ Add<HStoreNamedField>(string, HObjectAccess::ForConsStringFirst(), left);
+ Add<HStoreNamedField>(string, HObjectAccess::ForConsStringSecond(),
+ right);
+
+ // Count the native string addition.
+ AddIncrementCounter(isolate()->counters()->string_add_native());
+
+ // Cons string is result.
+ Push(string);
}
if_createcons.Else();
{
- // Determine the string instance types.
- HValue* left_instance_type = AddLoadStringInstanceType(left);
- HValue* right_instance_type = AddLoadStringInstanceType(right);
-
- // Compute union and difference of instance types.
+ // Compute union of instance types.
HValue* ored_instance_types = AddUncasted<HBitwise>(
Token::BIT_OR, left_instance_type, right_instance_type);
- HValue* xored_instance_types = AddUncasted<HBitwise>(
- Token::BIT_XOR, left_instance_type, right_instance_type);
// Check if both strings have the same encoding and both are
// sequential.
@@ -1909,12 +1869,7 @@ HValue* HGraphBuilder::BuildUncheckedStringAdd(
graph()->GetConstant0(), Token::EQ);
if_sameencodingandsequential.Then();
{
- HConstant* string_map =
- Add<HConstant>(isolate()->factory()->string_map());
- HConstant* ascii_string_map =
- Add<HConstant>(isolate()->factory()->ascii_string_map());
-
- // Determine map and size depending on whether result is one-byte string.
+ // Check if the result is a one-byte string.
IfBuilder if_onebyte(this);
STATIC_ASSERT(kOneByteStringTag != 0);
if_onebyte.If<HCompareNumericAndBranch>(
@@ -1924,84 +1879,90 @@ HValue* HGraphBuilder::BuildUncheckedStringAdd(
graph()->GetConstant0(), Token::NE);
if_onebyte.Then();
{
- // Allocate sequential one-byte string object.
- Push(length);
- Push(ascii_string_map);
- }
- if_onebyte.Else();
- {
- // Allocate sequential two-byte string object.
- HValue* size = AddUncasted<HShl>(length, graph()->GetConstant1());
- size->ClearFlag(HValue::kCanOverflow);
- size->SetFlag(HValue::kUint32);
- Push(size);
- Push(string_map);
- }
- if_onebyte.End();
- HValue* map = Pop();
-
- // Calculate the number of bytes needed for the characters in the
- // string while observing object alignment.
- STATIC_ASSERT((SeqString::kHeaderSize & kObjectAlignmentMask) == 0);
- HValue* size = Pop();
- size = AddUncasted<HAdd>(size, Add<HConstant>(static_cast<int32_t>(
- SeqString::kHeaderSize + kObjectAlignmentMask)));
- size->ClearFlag(HValue::kCanOverflow);
- size = AddUncasted<HBitwise>(
- Token::BIT_AND, size, Add<HConstant>(static_cast<int32_t>(
- ~kObjectAlignmentMask)));
-
- // Allocate the string object. HAllocate does not care whether we pass
- // STRING_TYPE or ASCII_STRING_TYPE here, so we just use STRING_TYPE here.
- HAllocate* result = BuildAllocate(
- size, HType::String(), STRING_TYPE, allocation_mode);
-
- // We can safely skip the write barrier for storing map here.
- AddStoreMapNoWriteBarrier(result, map);
-
- // Initialize the string fields.
- Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(),
- Add<HConstant>(String::kEmptyHashField));
- Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length);
-
- // Copy characters to the result string.
- IfBuilder if_twobyte(this);
- if_twobyte.If<HCompareObjectEqAndBranch>(map, string_map);
- if_twobyte.Then();
- {
- // Copy characters from the left string.
+ // Calculate the number of bytes needed for the characters in the
+ // string while observing object alignment.
+ HValue* size = BuildSeqStringSizeFor(
+ length, String::ONE_BYTE_ENCODING);
+
+ // Allocate the ASCII string object.
+ Handle<Map> map = isolate()->factory()->ascii_string_map();
+ HAllocate* string = Add<HAllocate>(size, HType::String(),
+ pretenure_flag, ASCII_STRING_TYPE);
+ string->set_known_initial_map(map);
+
+ // We can safely skip the write barrier for storing map here.
+ AddStoreMapConstantNoWriteBarrier(string, map);
+
+ // Length must be stored into the string before we copy characters to
+ // make debug verification code happy.
+ Add<HStoreNamedField>(string, HObjectAccess::ForStringLength(),
+ length);
+
+ // Copy bytes from the left string.
BuildCopySeqStringChars(
- left, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
- result, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
+ left, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
+ string, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
left_length);
- // Copy characters from the right string.
+ // Copy bytes from the right string.
BuildCopySeqStringChars(
- right, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
- result, left_length, String::TWO_BYTE_ENCODING,
+ right, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
+ string, left_length, String::ONE_BYTE_ENCODING,
right_length);
+
+ // Count the native string addition.
+ AddIncrementCounter(isolate()->counters()->string_add_native());
+
+ // Return the string.
+ Push(string);
}
- if_twobyte.Else();
+ if_onebyte.Else();
{
- // Copy characters from the left string.
+ // Calculate the number of bytes needed for the characters in the
+ // string while observing object alignment.
+ HValue* size = BuildSeqStringSizeFor(
+ length, String::TWO_BYTE_ENCODING);
+
+ // Allocate the two-byte string object.
+ Handle<Map> map = isolate()->factory()->string_map();
+ HAllocate* string = Add<HAllocate>(size, HType::String(),
+ pretenure_flag, STRING_TYPE);
+ string->set_known_initial_map(map);
+
+ // We can safely skip the write barrier for storing map here.
+ AddStoreMapConstantNoWriteBarrier(string, map);
+
+ // Length must be stored into the string before we copy characters to
+ // make debug verification code happy.
+ Add<HStoreNamedField>(string, HObjectAccess::ForStringLength(),
+ length);
+
+ // Copy bytes from the left string.
BuildCopySeqStringChars(
- left, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
- result, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
+ left, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
+ string, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
left_length);
- // Copy characters from the right string.
+ // Copy bytes from the right string.
BuildCopySeqStringChars(
- right, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
- result, left_length, String::ONE_BYTE_ENCODING,
+ right, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
+ string, left_length, String::TWO_BYTE_ENCODING,
right_length);
+
+ // Return the string.
+ Push(string);
}
- if_twobyte.End();
+ if_onebyte.End();
+
+ // Initialize the (common) string fields.
+ HValue* string = Pop();
+ Add<HStoreNamedField>(string, HObjectAccess::ForStringHashField(),
+ Add<HConstant>(String::kEmptyHashField));
// Count the native string addition.
AddIncrementCounter(isolate()->counters()->string_add_native());
- // Return the sequential string.
- Push(result);
+ Push(string);
}
if_sameencodingandsequential.Else();
{
@@ -2020,21 +1981,20 @@ HValue* HGraphBuilder::BuildUncheckedStringAdd(
}
-HValue* HGraphBuilder::BuildStringAdd(
- HValue* left,
- HValue* right,
- HAllocationMode allocation_mode) {
- NoObservableSideEffectsScope no_effects(this);
-
- // Determine string lengths.
- HValue* left_length = AddLoadStringLength(left);
- HValue* right_length = AddLoadStringLength(right);
+HValue* HGraphBuilder::BuildStringAdd(HValue* left,
+ HValue* right,
+ PretenureFlag pretenure_flag) {
+ // Determine the string lengths.
+ HValue* left_length = Add<HLoadNamedField>(
+ left, HObjectAccess::ForStringLength());
+ HValue* right_length = Add<HLoadNamedField>(
+ right, HObjectAccess::ForStringLength());
// Check if left string is empty.
- IfBuilder if_leftempty(this);
- if_leftempty.If<HCompareNumericAndBranch>(
+ IfBuilder if_leftisempty(this);
+ if_leftisempty.If<HCompareNumericAndBranch>(
left_length, graph()->GetConstant0(), Token::EQ);
- if_leftempty.Then();
+ if_leftisempty.Then();
{
// Count the native string addition.
AddIncrementCounter(isolate()->counters()->string_add_native());
@@ -2042,13 +2002,13 @@ HValue* HGraphBuilder::BuildStringAdd(
// Just return the right string.
Push(right);
}
- if_leftempty.Else();
+ if_leftisempty.Else();
{
// Check if right string is empty.
- IfBuilder if_rightempty(this);
- if_rightempty.If<HCompareNumericAndBranch>(
+ IfBuilder if_rightisempty(this);
+ if_rightisempty.If<HCompareNumericAndBranch>(
right_length, graph()->GetConstant0(), Token::EQ);
- if_rightempty.Then();
+ if_rightisempty.Then();
{
// Count the native string addition.
AddIncrementCounter(isolate()->counters()->string_add_native());
@@ -2056,14 +2016,14 @@ HValue* HGraphBuilder::BuildStringAdd(
// Just return the left string.
Push(left);
}
- if_rightempty.Else();
+ if_rightisempty.Else();
{
- // Add the two non-empty strings.
- Push(BuildUncheckedStringAdd(left, right, allocation_mode));
+ // Concatenate the two non-empty strings.
+ Push(BuildUncheckedStringAdd(left, right, pretenure_flag));
}
- if_rightempty.End();
+ if_rightisempty.End();
}
- if_leftempty.End();
+ if_leftisempty.End();
return Pop();
}
@@ -6140,27 +6100,15 @@ HInstruction* HGraphBuilder::AddLoadNamedField(HValue* object,
}
-HInstruction* HGraphBuilder::AddLoadStringInstanceType(HValue* string) {
- if (string->IsConstant()) {
- HConstant* c_string = HConstant::cast(string);
- if (c_string->HasStringValue()) {
- return Add<HConstant>(c_string->StringValue()->map()->instance_type());
+HInstruction* HGraphBuilder::BuildLoadStringLength(HValue* object,
+ HValue* checked_string) {
+ if (FLAG_fold_constants && object->IsConstant()) {
+ HConstant* constant = HConstant::cast(object);
+ if (constant->HasStringValue()) {
+ return New<HConstant>(constant->StringValue()->length());
}
}
- return AddLoadNamedField(
- AddLoadNamedField(string, HObjectAccess::ForMap()),
- HObjectAccess::ForMapInstanceType());
-}
-
-
-HInstruction* HGraphBuilder::AddLoadStringLength(HValue* string) {
- if (string->IsConstant()) {
- HConstant* c_string = HConstant::cast(string);
- if (c_string->HasStringValue()) {
- return Add<HConstant>(c_string->StringValue()->length());
- }
- }
- return AddLoadNamedField(string, HObjectAccess::ForStringLength());
+ return BuildLoadNamedField(checked_string, HObjectAccess::ForStringLength());
}
@@ -8608,9 +8556,13 @@ HInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt(
return New<HConstant>(s->Get(i));
}
}
- string = BuildCheckString(string);
- index = Add<HBoundsCheck>(index, AddLoadStringLength(string));
- return New<HStringCharCodeAt>(string, index);
+ BuildCheckHeapObject(string);
+ HValue* checkstring =
+ Add<HCheckInstanceType>(string, HCheckInstanceType::IS_STRING);
+ HInstruction* length = BuildLoadStringLength(string, checkstring);
+ AddInstruction(length);
+ HInstruction* checked_index = Add<HBoundsCheck>(index, length);
+ return New<HStringCharCodeAt>(string, checked_index);
}
@@ -8741,18 +8693,10 @@ HValue* HOptimizedGraphBuilder::BuildBinaryOperation(
Handle<Type> right_type = expr->right()->bounds().lower;
Handle<Type> result_type = expr->bounds().lower;
Maybe<int> fixed_right_arg = expr->fixed_right_arg();
- Handle<AllocationSite> allocation_site = expr->allocation_site();
-
- HAllocationMode allocation_mode =
- FLAG_allocation_site_pretenuring
- ? (allocation_site.is_null()
- ? HAllocationMode(NOT_TENURED)
- : HAllocationMode(allocation_site))
- : HAllocationMode(isolate()->heap()->GetPretenureMode());
HValue* result = HGraphBuilder::BuildBinaryOperation(
- expr->op(), left, right, left_type, right_type, result_type,
- fixed_right_arg, allocation_mode);
+ expr->op(), left, right, left_type, right_type,
+ result_type, fixed_right_arg);
// Add a simulate after instructions with observable side effects, and
// after phis, which are the result of BuildBinaryOperation when we
// inlined some complex subgraph.
@@ -8772,8 +8716,7 @@ HValue* HGraphBuilder::BuildBinaryOperation(
Handle<Type> left_type,
Handle<Type> right_type,
Handle<Type> result_type,
- Maybe<int> fixed_right_arg,
- HAllocationMode allocation_mode) {
+ Maybe<int> fixed_right_arg) {
Representation left_rep = Representation::FromType(left_type);
Representation right_rep = Representation::FromType(right_type);
@@ -8839,48 +8782,7 @@ HValue* HGraphBuilder::BuildBinaryOperation(
return AddUncasted<HInvokeFunction>(function, 2);
}
- // Inline the string addition into the stub when creating allocation
- // mementos to gather allocation site feedback.
- if (graph()->info()->IsStub() &&
- allocation_mode.CreateAllocationMementos()) {
- return BuildStringAdd(left, right, allocation_mode);
- }
-
- // Register the dependent code with the allocation site.
- if (!allocation_mode.feedback_site().is_null()) {
- ASSERT(!graph()->info()->IsStub());
- allocation_mode.feedback_site()->AddDependentCompilationInfo(
- AllocationSite::TENURING, top_info());
- }
-
- // Inline string addition if we know that we'll create a cons string.
- if (left->IsConstant()) {
- HConstant* c_left = HConstant::cast(left);
- if (c_left->HasStringValue()) {
- int c_left_length = c_left->StringValue()->length();
- if (c_left_length == 0) {
- return right;
- } else if (c_left_length + 1 >= ConsString::kMinLength) {
- return BuildStringAdd(left, right, allocation_mode);
- }
- }
- }
- if (right->IsConstant()) {
- HConstant* c_right = HConstant::cast(right);
- if (c_right->HasStringValue()) {
- int c_right_length = c_right->StringValue()->length();
- if (c_right_length == 0) {
- return left;
- } else if (c_right_length + 1 >= ConsString::kMinLength) {
- return BuildStringAdd(left, right, allocation_mode);
- }
- }
- }
-
- // Fallback to using the string add stub.
- return AddUncasted<HStringAdd>(
- left, right, allocation_mode.GetPretenureMode(),
- STRING_ADD_CHECK_NONE, allocation_mode.feedback_site());
+ return AddUncasted<HStringAdd>(left, right, STRING_ADD_CHECK_NONE);
}
if (graph()->info()->IsStub()) {
@@ -10109,7 +10011,8 @@ void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) {
CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
HValue* right = Pop();
HValue* left = Pop();
- HInstruction* result = NewUncasted<HStringAdd>(left, right);
+ HInstruction* result =
+ NewUncasted<HStringAdd>(left, right, STRING_ADD_CHECK_BOTH);
return ast_context()->ReturnInstruction(result, call->id());
}
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698