OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/hydrogen.h" | 5 #include "src/hydrogen.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 2049 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2060 HValue* HGraphBuilder::BuildCreateConsString( | 2060 HValue* HGraphBuilder::BuildCreateConsString( |
2061 HValue* length, | 2061 HValue* length, |
2062 HValue* left, | 2062 HValue* left, |
2063 HValue* right, | 2063 HValue* right, |
2064 HAllocationMode allocation_mode) { | 2064 HAllocationMode allocation_mode) { |
2065 // Determine the string instance types. | 2065 // Determine the string instance types. |
2066 HInstruction* left_instance_type = AddLoadStringInstanceType(left); | 2066 HInstruction* left_instance_type = AddLoadStringInstanceType(left); |
2067 HInstruction* right_instance_type = AddLoadStringInstanceType(right); | 2067 HInstruction* right_instance_type = AddLoadStringInstanceType(right); |
2068 | 2068 |
2069 // Allocate the cons string object. HAllocate does not care whether we | 2069 // Allocate the cons string object. HAllocate does not care whether we |
2070 // pass CONS_STRING_TYPE or CONS_ASCII_STRING_TYPE here, so we just use | 2070 // pass CONS_STRING_TYPE or CONS_ONE_BYTE_STRING_TYPE here, so we just use |
2071 // CONS_STRING_TYPE here. Below we decide whether the cons string is | 2071 // CONS_STRING_TYPE here. Below we decide whether the cons string is |
2072 // one-byte or two-byte and set the appropriate map. | 2072 // one-byte or two-byte and set the appropriate map. |
2073 DCHECK(HAllocate::CompatibleInstanceTypes(CONS_STRING_TYPE, | 2073 DCHECK(HAllocate::CompatibleInstanceTypes(CONS_STRING_TYPE, |
2074 CONS_ASCII_STRING_TYPE)); | 2074 CONS_ONE_BYTE_STRING_TYPE)); |
2075 HAllocate* result = BuildAllocate(Add<HConstant>(ConsString::kSize), | 2075 HAllocate* result = BuildAllocate(Add<HConstant>(ConsString::kSize), |
2076 HType::String(), CONS_STRING_TYPE, | 2076 HType::String(), CONS_STRING_TYPE, |
2077 allocation_mode); | 2077 allocation_mode); |
2078 | 2078 |
2079 // Compute intersection and difference of instance types. | 2079 // Compute intersection and difference of instance types. |
2080 HValue* anded_instance_types = AddUncasted<HBitwise>( | 2080 HValue* anded_instance_types = AddUncasted<HBitwise>( |
2081 Token::BIT_AND, left_instance_type, right_instance_type); | 2081 Token::BIT_AND, left_instance_type, right_instance_type); |
2082 HValue* xored_instance_types = AddUncasted<HBitwise>( | 2082 HValue* xored_instance_types = AddUncasted<HBitwise>( |
2083 Token::BIT_XOR, left_instance_type, right_instance_type); | 2083 Token::BIT_XOR, left_instance_type, right_instance_type); |
2084 | 2084 |
(...skipping 24 matching lines...) Expand all Loading... |
2109 Token::BIT_AND, xored_instance_types, | 2109 Token::BIT_AND, xored_instance_types, |
2110 Add<HConstant>(static_cast<int32_t>( | 2110 Add<HConstant>(static_cast<int32_t>( |
2111 kOneByteStringTag | kOneByteDataHintTag))), | 2111 kOneByteStringTag | kOneByteDataHintTag))), |
2112 Add<HConstant>(static_cast<int32_t>( | 2112 Add<HConstant>(static_cast<int32_t>( |
2113 kOneByteStringTag | kOneByteDataHintTag)), Token::EQ); | 2113 kOneByteStringTag | kOneByteDataHintTag)), Token::EQ); |
2114 if_onebyte.Then(); | 2114 if_onebyte.Then(); |
2115 { | 2115 { |
2116 // We can safely skip the write barrier for storing the map here. | 2116 // We can safely skip the write barrier for storing the map here. |
2117 Add<HStoreNamedField>( | 2117 Add<HStoreNamedField>( |
2118 result, HObjectAccess::ForMap(), | 2118 result, HObjectAccess::ForMap(), |
2119 Add<HConstant>(isolate()->factory()->cons_ascii_string_map())); | 2119 Add<HConstant>(isolate()->factory()->cons_one_byte_string_map())); |
2120 } | 2120 } |
2121 if_onebyte.Else(); | 2121 if_onebyte.Else(); |
2122 { | 2122 { |
2123 // We can safely skip the write barrier for storing the map here. | 2123 // We can safely skip the write barrier for storing the map here. |
2124 Add<HStoreNamedField>( | 2124 Add<HStoreNamedField>( |
2125 result, HObjectAccess::ForMap(), | 2125 result, HObjectAccess::ForMap(), |
2126 Add<HConstant>(isolate()->factory()->cons_string_map())); | 2126 Add<HConstant>(isolate()->factory()->cons_string_map())); |
2127 } | 2127 } |
2128 if_onebyte.End(); | 2128 if_onebyte.End(); |
2129 | 2129 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2237 STATIC_ASSERT(kSeqStringTag == 0); | 2237 STATIC_ASSERT(kSeqStringTag == 0); |
2238 if_sameencodingandsequential.If<HCompareNumericAndBranch>( | 2238 if_sameencodingandsequential.If<HCompareNumericAndBranch>( |
2239 AddUncasted<HBitwise>( | 2239 AddUncasted<HBitwise>( |
2240 Token::BIT_AND, ored_instance_types, | 2240 Token::BIT_AND, ored_instance_types, |
2241 Add<HConstant>(static_cast<int32_t>(kStringRepresentationMask))), | 2241 Add<HConstant>(static_cast<int32_t>(kStringRepresentationMask))), |
2242 graph()->GetConstant0(), Token::EQ); | 2242 graph()->GetConstant0(), Token::EQ); |
2243 if_sameencodingandsequential.Then(); | 2243 if_sameencodingandsequential.Then(); |
2244 { | 2244 { |
2245 HConstant* string_map = | 2245 HConstant* string_map = |
2246 Add<HConstant>(isolate()->factory()->string_map()); | 2246 Add<HConstant>(isolate()->factory()->string_map()); |
2247 HConstant* ascii_string_map = | 2247 HConstant* one_byte_string_map = |
2248 Add<HConstant>(isolate()->factory()->ascii_string_map()); | 2248 Add<HConstant>(isolate()->factory()->one_byte_string_map()); |
2249 | 2249 |
2250 // Determine map and size depending on whether result is one-byte string. | 2250 // Determine map and size depending on whether result is one-byte string. |
2251 IfBuilder if_onebyte(this); | 2251 IfBuilder if_onebyte(this); |
2252 STATIC_ASSERT(kOneByteStringTag != 0); | 2252 STATIC_ASSERT(kOneByteStringTag != 0); |
2253 if_onebyte.If<HCompareNumericAndBranch>( | 2253 if_onebyte.If<HCompareNumericAndBranch>( |
2254 AddUncasted<HBitwise>( | 2254 AddUncasted<HBitwise>( |
2255 Token::BIT_AND, ored_instance_types, | 2255 Token::BIT_AND, ored_instance_types, |
2256 Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))), | 2256 Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))), |
2257 graph()->GetConstant0(), Token::NE); | 2257 graph()->GetConstant0(), Token::NE); |
2258 if_onebyte.Then(); | 2258 if_onebyte.Then(); |
2259 { | 2259 { |
2260 // Allocate sequential one-byte string object. | 2260 // Allocate sequential one-byte string object. |
2261 Push(length); | 2261 Push(length); |
2262 Push(ascii_string_map); | 2262 Push(one_byte_string_map); |
2263 } | 2263 } |
2264 if_onebyte.Else(); | 2264 if_onebyte.Else(); |
2265 { | 2265 { |
2266 // Allocate sequential two-byte string object. | 2266 // Allocate sequential two-byte string object. |
2267 HValue* size = AddUncasted<HShl>(length, graph()->GetConstant1()); | 2267 HValue* size = AddUncasted<HShl>(length, graph()->GetConstant1()); |
2268 size->ClearFlag(HValue::kCanOverflow); | 2268 size->ClearFlag(HValue::kCanOverflow); |
2269 size->SetFlag(HValue::kUint32); | 2269 size->SetFlag(HValue::kUint32); |
2270 Push(size); | 2270 Push(size); |
2271 Push(string_map); | 2271 Push(string_map); |
2272 } | 2272 } |
2273 if_onebyte.End(); | 2273 if_onebyte.End(); |
2274 HValue* map = Pop(); | 2274 HValue* map = Pop(); |
2275 | 2275 |
2276 // Calculate the number of bytes needed for the characters in the | 2276 // Calculate the number of bytes needed for the characters in the |
2277 // string while observing object alignment. | 2277 // string while observing object alignment. |
2278 STATIC_ASSERT((SeqString::kHeaderSize & kObjectAlignmentMask) == 0); | 2278 STATIC_ASSERT((SeqString::kHeaderSize & kObjectAlignmentMask) == 0); |
2279 HValue* size = BuildObjectSizeAlignment(Pop(), SeqString::kHeaderSize); | 2279 HValue* size = BuildObjectSizeAlignment(Pop(), SeqString::kHeaderSize); |
2280 | 2280 |
2281 // Allocate the string object. HAllocate does not care whether we pass | 2281 // Allocate the string object. HAllocate does not care whether we pass |
2282 // STRING_TYPE or ASCII_STRING_TYPE here, so we just use STRING_TYPE here. | 2282 // STRING_TYPE or ONE_BYTE_STRING_TYPE here, so we just use STRING_TYPE. |
2283 HAllocate* result = BuildAllocate( | 2283 HAllocate* result = BuildAllocate( |
2284 size, HType::String(), STRING_TYPE, allocation_mode); | 2284 size, HType::String(), STRING_TYPE, allocation_mode); |
2285 Add<HStoreNamedField>(result, HObjectAccess::ForMap(), map); | 2285 Add<HStoreNamedField>(result, HObjectAccess::ForMap(), map); |
2286 | 2286 |
2287 // Initialize the string fields. | 2287 // Initialize the string fields. |
2288 Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(), | 2288 Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(), |
2289 Add<HConstant>(String::kEmptyHashField)); | 2289 Add<HConstant>(String::kEmptyHashField)); |
2290 Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length); | 2290 Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length); |
2291 | 2291 |
2292 // Copy characters to the result string. | 2292 // Copy characters to the result string. |
(...skipping 8160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10453 | 10453 |
10454 | 10454 |
10455 // Check for the form (%_ClassOf(foo) === 'BarClass'). | 10455 // Check for the form (%_ClassOf(foo) === 'BarClass'). |
10456 static bool IsClassOfTest(CompareOperation* expr) { | 10456 static bool IsClassOfTest(CompareOperation* expr) { |
10457 if (expr->op() != Token::EQ_STRICT) return false; | 10457 if (expr->op() != Token::EQ_STRICT) return false; |
10458 CallRuntime* call = expr->left()->AsCallRuntime(); | 10458 CallRuntime* call = expr->left()->AsCallRuntime(); |
10459 if (call == NULL) return false; | 10459 if (call == NULL) return false; |
10460 Literal* literal = expr->right()->AsLiteral(); | 10460 Literal* literal = expr->right()->AsLiteral(); |
10461 if (literal == NULL) return false; | 10461 if (literal == NULL) return false; |
10462 if (!literal->value()->IsString()) return false; | 10462 if (!literal->value()->IsString()) return false; |
10463 if (!call->name()->IsOneByteEqualTo(STATIC_ASCII_VECTOR("_ClassOf"))) { | 10463 if (!call->name()->IsOneByteEqualTo(STATIC_CHAR_VECTOR("_ClassOf"))) { |
10464 return false; | 10464 return false; |
10465 } | 10465 } |
10466 DCHECK(call->arguments()->length() == 1); | 10466 DCHECK(call->arguments()->length() == 1); |
10467 return true; | 10467 return true; |
10468 } | 10468 } |
10469 | 10469 |
10470 | 10470 |
10471 void HOptimizedGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { | 10471 void HOptimizedGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { |
10472 DCHECK(!HasStackOverflow()); | 10472 DCHECK(!HasStackOverflow()); |
10473 DCHECK(current_block() != NULL); | 10473 DCHECK(current_block() != NULL); |
(...skipping 1361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11835 | 11835 |
11836 void HOptimizedGraphBuilder::GenerateGetCachedArrayIndex(CallRuntime* call) { | 11836 void HOptimizedGraphBuilder::GenerateGetCachedArrayIndex(CallRuntime* call) { |
11837 DCHECK(call->arguments()->length() == 1); | 11837 DCHECK(call->arguments()->length() == 1); |
11838 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 11838 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
11839 HValue* value = Pop(); | 11839 HValue* value = Pop(); |
11840 HGetCachedArrayIndex* result = New<HGetCachedArrayIndex>(value); | 11840 HGetCachedArrayIndex* result = New<HGetCachedArrayIndex>(value); |
11841 return ast_context()->ReturnInstruction(result, call->id()); | 11841 return ast_context()->ReturnInstruction(result, call->id()); |
11842 } | 11842 } |
11843 | 11843 |
11844 | 11844 |
11845 void HOptimizedGraphBuilder::GenerateFastAsciiArrayJoin(CallRuntime* call) { | 11845 void HOptimizedGraphBuilder::GenerateFastOneByteArrayJoin(CallRuntime* call) { |
11846 return Bailout(kInlinedRuntimeFunctionFastAsciiArrayJoin); | 11846 return Bailout(kInlinedRuntimeFunctionFastOneByteArrayJoin); |
11847 } | 11847 } |
11848 | 11848 |
11849 | 11849 |
11850 // Support for generators. | 11850 // Support for generators. |
11851 void HOptimizedGraphBuilder::GenerateGeneratorNext(CallRuntime* call) { | 11851 void HOptimizedGraphBuilder::GenerateGeneratorNext(CallRuntime* call) { |
11852 return Bailout(kInlinedRuntimeFunctionGeneratorNext); | 11852 return Bailout(kInlinedRuntimeFunctionGeneratorNext); |
11853 } | 11853 } |
11854 | 11854 |
11855 | 11855 |
11856 void HOptimizedGraphBuilder::GenerateGeneratorThrow(CallRuntime* call) { | 11856 void HOptimizedGraphBuilder::GenerateGeneratorThrow(CallRuntime* call) { |
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12493 if (ShouldProduceTraceOutput()) { | 12493 if (ShouldProduceTraceOutput()) { |
12494 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 12494 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
12495 } | 12495 } |
12496 | 12496 |
12497 #ifdef DEBUG | 12497 #ifdef DEBUG |
12498 graph_->Verify(false); // No full verify. | 12498 graph_->Verify(false); // No full verify. |
12499 #endif | 12499 #endif |
12500 } | 12500 } |
12501 | 12501 |
12502 } } // namespace v8::internal | 12502 } } // namespace v8::internal |
OLD | NEW |