| OLD | NEW |
| 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/bailout-reason.h" | 7 #include "src/bailout-reason.h" |
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 #include "src/field-index.h" | 9 #include "src/field-index.h" |
| 10 #include "src/hydrogen.h" | 10 #include "src/hydrogen.h" |
| (...skipping 2174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2185 HValue* bit_field2, | 2185 HValue* bit_field2, |
| 2186 ElementsKind kind); | 2186 ElementsKind kind); |
| 2187 | 2187 |
| 2188 void BuildFastElementLoad(HGraphBuilder::IfBuilder* if_builder, | 2188 void BuildFastElementLoad(HGraphBuilder::IfBuilder* if_builder, |
| 2189 HValue* receiver, | 2189 HValue* receiver, |
| 2190 HValue* key, | 2190 HValue* key, |
| 2191 HValue* instance_type, | 2191 HValue* instance_type, |
| 2192 HValue* bit_field2, | 2192 HValue* bit_field2, |
| 2193 ElementsKind kind); | 2193 ElementsKind kind); |
| 2194 | 2194 |
| 2195 void BuildExternalElementLoad(HGraphBuilder::IfBuilder* if_builder, | |
| 2196 HValue* receiver, | |
| 2197 HValue* key, | |
| 2198 HValue* instance_type, | |
| 2199 HValue* bit_field2, | |
| 2200 ElementsKind kind); | |
| 2201 | |
| 2202 KeyedLoadGenericStub* casted_stub() { | 2195 KeyedLoadGenericStub* casted_stub() { |
| 2203 return static_cast<KeyedLoadGenericStub*>(stub()); | 2196 return static_cast<KeyedLoadGenericStub*>(stub()); |
| 2204 } | 2197 } |
| 2205 }; | 2198 }; |
| 2206 | 2199 |
| 2207 | 2200 |
| 2208 void CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildElementsKindLimitCheck( | 2201 void CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildElementsKindLimitCheck( |
| 2209 HGraphBuilder::IfBuilder* if_builder, HValue* bit_field2, | 2202 HGraphBuilder::IfBuilder* if_builder, HValue* bit_field2, |
| 2210 ElementsKind kind) { | 2203 ElementsKind kind) { |
| 2211 ElementsKind next_kind = static_cast<ElementsKind>(kind + 1); | 2204 ElementsKind next_kind = static_cast<ElementsKind>(kind + 1); |
| 2212 HValue* kind_limit = Add<HConstant>( | 2205 HValue* kind_limit = Add<HConstant>( |
| 2213 static_cast<int>(Map::ElementsKindBits::encode(next_kind))); | 2206 static_cast<int>(Map::ElementsKindBits::encode(next_kind))); |
| 2214 | 2207 |
| 2215 if_builder->If<HCompareNumericAndBranch>(bit_field2, kind_limit, Token::LT); | 2208 if_builder->If<HCompareNumericAndBranch>(bit_field2, kind_limit, Token::LT); |
| 2216 if_builder->Then(); | 2209 if_builder->Then(); |
| 2217 } | 2210 } |
| 2218 | 2211 |
| 2219 | 2212 |
| 2220 void CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildFastElementLoad( | 2213 void CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildFastElementLoad( |
| 2221 HGraphBuilder::IfBuilder* if_builder, HValue* receiver, HValue* key, | 2214 HGraphBuilder::IfBuilder* if_builder, HValue* receiver, HValue* key, |
| 2222 HValue* instance_type, HValue* bit_field2, ElementsKind kind) { | 2215 HValue* instance_type, HValue* bit_field2, ElementsKind kind) { |
| 2223 DCHECK(!IsExternalArrayElementsKind(kind)); | |
| 2224 | |
| 2225 BuildElementsKindLimitCheck(if_builder, bit_field2, kind); | 2216 BuildElementsKindLimitCheck(if_builder, bit_field2, kind); |
| 2226 | 2217 |
| 2227 IfBuilder js_array_check(this); | 2218 IfBuilder js_array_check(this); |
| 2228 js_array_check.If<HCompareNumericAndBranch>( | 2219 js_array_check.If<HCompareNumericAndBranch>( |
| 2229 instance_type, Add<HConstant>(JS_ARRAY_TYPE), Token::EQ); | 2220 instance_type, Add<HConstant>(JS_ARRAY_TYPE), Token::EQ); |
| 2230 js_array_check.Then(); | 2221 js_array_check.Then(); |
| 2231 Push(BuildUncheckedMonomorphicElementAccess(receiver, key, NULL, | 2222 Push(BuildUncheckedMonomorphicElementAccess(receiver, key, NULL, |
| 2232 true, kind, | 2223 true, kind, |
| 2233 LOAD, NEVER_RETURN_HOLE, | 2224 LOAD, NEVER_RETURN_HOLE, |
| 2234 STANDARD_STORE)); | 2225 STANDARD_STORE)); |
| 2235 js_array_check.Else(); | 2226 js_array_check.Else(); |
| 2236 Push(BuildUncheckedMonomorphicElementAccess(receiver, key, NULL, | 2227 Push(BuildUncheckedMonomorphicElementAccess(receiver, key, NULL, |
| 2237 false, kind, | 2228 false, kind, |
| 2238 LOAD, NEVER_RETURN_HOLE, | 2229 LOAD, NEVER_RETURN_HOLE, |
| 2239 STANDARD_STORE)); | 2230 STANDARD_STORE)); |
| 2240 js_array_check.End(); | 2231 js_array_check.End(); |
| 2241 } | 2232 } |
| 2242 | 2233 |
| 2243 | 2234 |
| 2244 void CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildExternalElementLoad( | |
| 2245 HGraphBuilder::IfBuilder* if_builder, HValue* receiver, HValue* key, | |
| 2246 HValue* instance_type, HValue* bit_field2, ElementsKind kind) { | |
| 2247 DCHECK(IsExternalArrayElementsKind(kind)); | |
| 2248 | |
| 2249 BuildElementsKindLimitCheck(if_builder, bit_field2, kind); | |
| 2250 | |
| 2251 Push(BuildUncheckedMonomorphicElementAccess(receiver, key, NULL, | |
| 2252 false, kind, | |
| 2253 LOAD, NEVER_RETURN_HOLE, | |
| 2254 STANDARD_STORE)); | |
| 2255 } | |
| 2256 | |
| 2257 | |
| 2258 HValue* CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildCodeStub() { | 2235 HValue* CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildCodeStub() { |
| 2259 HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex); | 2236 HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex); |
| 2260 HValue* key = GetParameter(LoadDescriptor::kNameIndex); | 2237 HValue* key = GetParameter(LoadDescriptor::kNameIndex); |
| 2261 // Split into a smi/integer case and unique string case. | 2238 // Split into a smi/integer case and unique string case. |
| 2262 HIfContinuation index_name_split_continuation(graph()->CreateBasicBlock(), | 2239 HIfContinuation index_name_split_continuation(graph()->CreateBasicBlock(), |
| 2263 graph()->CreateBasicBlock()); | 2240 graph()->CreateBasicBlock()); |
| 2264 | 2241 |
| 2265 BuildKeyedIndexCheck(key, &index_name_split_continuation); | 2242 BuildKeyedIndexCheck(key, &index_name_split_continuation); |
| 2266 | 2243 |
| 2267 IfBuilder index_name_split(this, &index_name_split_continuation); | 2244 IfBuilder index_name_split(this, &index_name_split_continuation); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2309 // The SLOW_SLOPPY_ARGUMENTS_ELEMENTS check generates a "kind_if.Then" | 2286 // The SLOW_SLOPPY_ARGUMENTS_ELEMENTS check generates a "kind_if.Then" |
| 2310 STATIC_ASSERT(FAST_SLOPPY_ARGUMENTS_ELEMENTS < | 2287 STATIC_ASSERT(FAST_SLOPPY_ARGUMENTS_ELEMENTS < |
| 2311 SLOW_SLOPPY_ARGUMENTS_ELEMENTS); | 2288 SLOW_SLOPPY_ARGUMENTS_ELEMENTS); |
| 2312 BuildElementsKindLimitCheck(&kind_if, bit_field2, | 2289 BuildElementsKindLimitCheck(&kind_if, bit_field2, |
| 2313 SLOW_SLOPPY_ARGUMENTS_ELEMENTS); | 2290 SLOW_SLOPPY_ARGUMENTS_ELEMENTS); |
| 2314 // Non-strict elements are not handled. | 2291 // Non-strict elements are not handled. |
| 2315 Add<HDeoptimize>(Deoptimizer::kNonStrictElementsInKeyedLoadGenericStub, | 2292 Add<HDeoptimize>(Deoptimizer::kNonStrictElementsInKeyedLoadGenericStub, |
| 2316 Deoptimizer::EAGER); | 2293 Deoptimizer::EAGER); |
| 2317 Push(graph()->GetConstant0()); | 2294 Push(graph()->GetConstant0()); |
| 2318 | 2295 |
| 2319 kind_if.Else(); | |
| 2320 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2, | |
| 2321 EXTERNAL_INT8_ELEMENTS); | |
| 2322 | |
| 2323 kind_if.Else(); | |
| 2324 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2, | |
| 2325 EXTERNAL_UINT8_ELEMENTS); | |
| 2326 | |
| 2327 kind_if.Else(); | |
| 2328 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2, | |
| 2329 EXTERNAL_INT16_ELEMENTS); | |
| 2330 | |
| 2331 kind_if.Else(); | |
| 2332 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2, | |
| 2333 EXTERNAL_UINT16_ELEMENTS); | |
| 2334 | |
| 2335 kind_if.Else(); | |
| 2336 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2, | |
| 2337 EXTERNAL_INT32_ELEMENTS); | |
| 2338 | |
| 2339 kind_if.Else(); | |
| 2340 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2, | |
| 2341 EXTERNAL_UINT32_ELEMENTS); | |
| 2342 | |
| 2343 kind_if.Else(); | |
| 2344 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2, | |
| 2345 EXTERNAL_FLOAT32_ELEMENTS); | |
| 2346 | |
| 2347 kind_if.Else(); | |
| 2348 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2, | |
| 2349 EXTERNAL_FLOAT64_ELEMENTS); | |
| 2350 | |
| 2351 kind_if.Else(); | |
| 2352 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2, | |
| 2353 EXTERNAL_UINT8_CLAMPED_ELEMENTS); | |
| 2354 | |
| 2355 kind_if.ElseDeopt( | 2296 kind_if.ElseDeopt( |
| 2356 Deoptimizer::kElementsKindUnhandledInKeyedLoadGenericStub); | 2297 Deoptimizer::kElementsKindUnhandledInKeyedLoadGenericStub); |
| 2357 | 2298 |
| 2358 kind_if.End(); | 2299 kind_if.End(); |
| 2359 } | 2300 } |
| 2360 index_name_split.Else(); | 2301 index_name_split.Else(); |
| 2361 { | 2302 { |
| 2362 // Key is a unique string. | 2303 // Key is a unique string. |
| 2363 key = Pop(); | 2304 key = Pop(); |
| 2364 | 2305 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2432 lookup_if->Then(); | 2373 lookup_if->Then(); |
| 2433 { | 2374 { |
| 2434 ExternalReference cache_field_offsets_ref = | 2375 ExternalReference cache_field_offsets_ref = |
| 2435 ExternalReference::keyed_lookup_cache_field_offsets(isolate()); | 2376 ExternalReference::keyed_lookup_cache_field_offsets(isolate()); |
| 2436 HValue* cache_field_offsets = | 2377 HValue* cache_field_offsets = |
| 2437 Add<HConstant>(cache_field_offsets_ref); | 2378 Add<HConstant>(cache_field_offsets_ref); |
| 2438 HValue* index = AddUncasted<HAdd>(hash, Add<HConstant>(probe)); | 2379 HValue* index = AddUncasted<HAdd>(hash, Add<HConstant>(probe)); |
| 2439 index->ClearFlag(HValue::kCanOverflow); | 2380 index->ClearFlag(HValue::kCanOverflow); |
| 2440 HValue* property_index = | 2381 HValue* property_index = |
| 2441 Add<HLoadKeyed>(cache_field_offsets, index, nullptr, | 2382 Add<HLoadKeyed>(cache_field_offsets, index, nullptr, |
| 2442 EXTERNAL_INT32_ELEMENTS, NEVER_RETURN_HOLE, 0); | 2383 INT32_ELEMENTS, NEVER_RETURN_HOLE, 0); |
| 2443 Push(property_index); | 2384 Push(property_index); |
| 2444 } | 2385 } |
| 2445 lookup_if->Else(); | 2386 lookup_if->Else(); |
| 2446 } | 2387 } |
| 2447 for (int i = 0; i < KeyedLookupCache::kEntriesPerBucket; ++i) { | 2388 for (int i = 0; i < KeyedLookupCache::kEntriesPerBucket; ++i) { |
| 2448 lookup_ifs[i].JoinContinuation(&inline_or_runtime_continuation); | 2389 lookup_ifs[i].JoinContinuation(&inline_or_runtime_continuation); |
| 2449 } | 2390 } |
| 2450 } | 2391 } |
| 2451 | 2392 |
| 2452 IfBuilder inline_or_runtime(this, &inline_or_runtime_continuation); | 2393 IfBuilder inline_or_runtime(this, &inline_or_runtime_continuation); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2475 return Pop(); | 2416 return Pop(); |
| 2476 } | 2417 } |
| 2477 | 2418 |
| 2478 | 2419 |
| 2479 Handle<Code> KeyedLoadGenericStub::GenerateCode() { | 2420 Handle<Code> KeyedLoadGenericStub::GenerateCode() { |
| 2480 return DoGenerateCode(this); | 2421 return DoGenerateCode(this); |
| 2481 } | 2422 } |
| 2482 | 2423 |
| 2483 } // namespace internal | 2424 } // namespace internal |
| 2484 } // namespace v8 | 2425 } // namespace v8 |
| OLD | NEW |