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

Side by Side Diff: src/compiler/effect-control-linearizer.cc

Issue 2373983004: [turbofan] inline %StringIteratorPrototype%.next in JSBuiltinReducer. (Closed)
Patch Set: Created 4 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
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/compiler/effect-control-linearizer.h" 5 #include "src/compiler/effect-control-linearizer.h"
6 6
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/compiler/access-builder.h" 8 #include "src/compiler/access-builder.h"
9 #include "src/compiler/js-graph.h" 9 #include "src/compiler/js-graph.h"
10 #include "src/compiler/linkage.h" 10 #include "src/compiler/linkage.h"
(...skipping 701 matching lines...) Expand 10 before | Expand all | Expand 10 after
712 break; 712 break;
713 case IrOpcode::kObjectIsUndetectable: 713 case IrOpcode::kObjectIsUndetectable:
714 state = LowerObjectIsUndetectable(node, *effect, *control); 714 state = LowerObjectIsUndetectable(node, *effect, *control);
715 break; 715 break;
716 case IrOpcode::kArrayBufferWasNeutered: 716 case IrOpcode::kArrayBufferWasNeutered:
717 state = LowerArrayBufferWasNeutered(node, *effect, *control); 717 state = LowerArrayBufferWasNeutered(node, *effect, *control);
718 break; 718 break;
719 case IrOpcode::kStringFromCharCode: 719 case IrOpcode::kStringFromCharCode:
720 state = LowerStringFromCharCode(node, *effect, *control); 720 state = LowerStringFromCharCode(node, *effect, *control);
721 break; 721 break;
722 case IrOpcode::kStringFromCodePoint:
723 state = LowerStringFromCodePoint(node, *effect, *control);
724 break;
722 case IrOpcode::kStringCharCodeAt: 725 case IrOpcode::kStringCharCodeAt:
723 state = LowerStringCharCodeAt(node, *effect, *control); 726 state = LowerStringCharCodeAt(node, *effect, *control);
724 break; 727 break;
725 case IrOpcode::kStringEqual: 728 case IrOpcode::kStringEqual:
726 state = LowerStringEqual(node, *effect, *control); 729 state = LowerStringEqual(node, *effect, *control);
727 break; 730 break;
728 case IrOpcode::kStringLessThan: 731 case IrOpcode::kStringLessThan:
729 state = LowerStringLessThan(node, *effect, *control); 732 state = LowerStringLessThan(node, *effect, *control);
730 break; 733 break;
731 case IrOpcode::kStringLessThanOrEqual: 734 case IrOpcode::kStringLessThanOrEqual:
(...skipping 1489 matching lines...) Expand 10 before | Expand all | Expand 10 after
2221 graph()->NewNode(machine()->Word32And(), value_bit_field, 2224 graph()->NewNode(machine()->Word32And(), value_bit_field,
2222 jsgraph()->Int32Constant( 2225 jsgraph()->Int32Constant(
2223 JSArrayBuffer::WasNeutered::kMask)), 2226 JSArrayBuffer::WasNeutered::kMask)),
2224 jsgraph()->Int32Constant(0)), 2227 jsgraph()->Int32Constant(0)),
2225 jsgraph()->Int32Constant(0)); 2228 jsgraph()->Int32Constant(0));
2226 2229
2227 return ValueEffectControl(value, effect, control); 2230 return ValueEffectControl(value, effect, control);
2228 } 2231 }
2229 2232
2230 EffectControlLinearizer::ValueEffectControl 2233 EffectControlLinearizer::ValueEffectControl
2231 EffectControlLinearizer::LowerStringCharCodeAt(Node* node, Node* effect, 2234 EffectControlLinearizer::LowerStringCharCodeAt(Node* node, Node* effect,
Benedikt Meurer 2016/09/29 13:04:27 Can you hold off with changing the StringCharCodeA
Benedikt Meurer 2016/09/29 16:40:01 I wonder how much the pre-flattening actually buys
caitp 2016/09/29 20:08:02 Comparing these, it doesn't look like there's a si
2232 Node* control) { 2235 Node* control) {
2236 StringOperationHint hint = StringOperationHintOf(node->op());
2233 Node* subject = node->InputAt(0); 2237 Node* subject = node->InputAt(0);
2234 Node* index = node->InputAt(1); 2238 Node* index = node->InputAt(1);
2235 2239 Node* value = nullptr;
2236 // We may need to loop several times for ConsString/SlicedString {subject}s. 2240
2237 Node* loop = 2241 switch (hint) {
2238 graph()->NewNode(common()->Loop(4), control, control, control, control); 2242 case StringOperationHint::kAny: {
2239 Node* lsubject = 2243 // We may need to loop several times for ConsString/SlicedString
2240 graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 4), 2244 // {subject}s.
2241 subject, subject, subject, subject, loop); 2245 Node* loop = graph()->NewNode(common()->Loop(4), control, control,
2242 Node* lindex = 2246 control, control);
2243 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 4), index, 2247 Node* lsubject =
2244 index, index, index, loop); 2248 graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 4),
2245 Node* leffect = graph()->NewNode(common()->EffectPhi(4), effect, effect, 2249 subject, subject, subject, subject, loop);
2246 effect, effect, loop); 2250 Node* lindex =
2247 2251 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 4),
2248 control = loop; 2252 index, index, index, index, loop);
2249 effect = leffect; 2253 Node* leffect = graph()->NewNode(common()->EffectPhi(4), effect, effect,
2250 2254 effect, effect, loop);
2251 // Determine the instance type of {lsubject}. 2255
2252 Node* lsubject_map = effect = 2256 control = loop;
2253 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), 2257 effect = leffect;
2254 lsubject, effect, control); 2258
2255 Node* lsubject_instance_type = effect = graph()->NewNode( 2259 // Determine the instance type of {lsubject}.
2256 simplified()->LoadField(AccessBuilder::ForMapInstanceType()), 2260 Node* lsubject_map = effect =
2257 lsubject_map, effect, control); 2261 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
2258 2262 lsubject, effect, control);
2259 // Check if {lsubject} is a SeqString. 2263 Node* lsubject_instance_type = effect = graph()->NewNode(
2260 Node* check0 = graph()->NewNode( 2264 simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
2261 machine()->Word32Equal(), 2265 lsubject_map, effect, control);
2262 graph()->NewNode(machine()->Word32And(), lsubject_instance_type, 2266
2263 jsgraph()->Int32Constant(kStringRepresentationMask)), 2267 // Check if {lsubject} is a SeqString.
2264 jsgraph()->Int32Constant(kSeqStringTag)); 2268 Node* check0 = graph()->NewNode(
2265 Node* branch0 = graph()->NewNode(common()->Branch(), check0, control);
2266
2267 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
2268 Node* etrue0 = effect;
2269 Node* vtrue0;
2270 {
2271 // Check if the {lsubject} is a TwoByteSeqString or a OneByteSeqString.
2272 Node* check1 = graph()->NewNode(
2273 machine()->Word32Equal(),
2274 graph()->NewNode(machine()->Word32And(), lsubject_instance_type,
2275 jsgraph()->Int32Constant(kStringEncodingMask)),
2276 jsgraph()->Int32Constant(kTwoByteStringTag));
2277 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
2278
2279 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
2280 Node* etrue1 = etrue0;
2281 Node* vtrue1 = etrue1 =
2282 graph()->NewNode(simplified()->LoadElement(
2283 AccessBuilder::ForSeqTwoByteStringCharacter()),
2284 lsubject, lindex, etrue1, if_true1);
2285
2286 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
2287 Node* efalse1 = etrue0;
2288 Node* vfalse1 = efalse1 =
2289 graph()->NewNode(simplified()->LoadElement(
2290 AccessBuilder::ForSeqOneByteStringCharacter()),
2291 lsubject, lindex, efalse1, if_false1);
2292
2293 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
2294 etrue0 =
2295 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_true0);
2296 vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
2297 vtrue1, vfalse1, if_true0);
2298 }
2299
2300 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
2301 Node* efalse0 = effect;
2302 Node* vfalse0;
2303 {
2304 // Check if the {lsubject} is a ConsString.
2305 Node* check1 = graph()->NewNode(
2306 machine()->Word32Equal(),
2307 graph()->NewNode(machine()->Word32And(), lsubject_instance_type,
2308 jsgraph()->Int32Constant(kStringRepresentationMask)),
2309 jsgraph()->Int32Constant(kConsStringTag));
2310 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
2311
2312 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
2313 Node* etrue1 = efalse0;
2314 {
2315 // Load the right hand side of the {lsubject} ConsString.
2316 Node* lsubject_second = etrue1 = graph()->NewNode(
2317 simplified()->LoadField(AccessBuilder::ForConsStringSecond()),
2318 lsubject, etrue1, if_true1);
2319
2320 // Check whether the right hand side is the empty string (i.e. if
2321 // this is really a flat string in a cons string). If that is not
2322 // the case we flatten the string first.
2323 Node* check2 = graph()->NewNode(machine()->WordEqual(), lsubject_second,
2324 jsgraph()->EmptyStringConstant());
2325 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kTrue),
2326 check2, if_true1);
2327
2328 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
2329 Node* etrue2 = etrue1;
2330 Node* vtrue2 = etrue2 = graph()->NewNode(
2331 simplified()->LoadField(AccessBuilder::ForConsStringFirst()),
2332 lsubject, etrue2, if_true2);
2333
2334 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
2335 Node* efalse2 = etrue1;
2336 Node* vfalse2;
2337 {
2338 // Flatten the {lsubject} ConsString first.
2339 Operator::Properties properties =
2340 Operator::kNoDeopt | Operator::kNoThrow;
2341 Runtime::FunctionId id = Runtime::kFlattenString;
2342 CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor(
2343 graph()->zone(), id, 1, properties, CallDescriptor::kNoFlags);
2344 vfalse2 = efalse2 = graph()->NewNode(
2345 common()->Call(desc), jsgraph()->CEntryStubConstant(1), lsubject,
2346 jsgraph()->ExternalConstant(ExternalReference(id, isolate())),
2347 jsgraph()->Int32Constant(1), jsgraph()->NoContextConstant(),
2348 efalse2, if_false2);
2349 }
2350
2351 // Retry the {loop} with the new subject.
2352 loop->ReplaceInput(1, if_true2);
2353 lindex->ReplaceInput(1, lindex);
2354 leffect->ReplaceInput(1, etrue2);
2355 lsubject->ReplaceInput(1, vtrue2);
2356 loop->ReplaceInput(2, if_false2);
2357 lindex->ReplaceInput(2, lindex);
2358 leffect->ReplaceInput(2, efalse2);
2359 lsubject->ReplaceInput(2, vfalse2);
2360 }
2361
2362 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
2363 Node* efalse1 = efalse0;
2364 Node* vfalse1;
2365 {
2366 // Check if the {lsubject} is an ExternalString.
2367 Node* check2 = graph()->NewNode(
2368 machine()->Word32Equal(), 2269 machine()->Word32Equal(),
2369 graph()->NewNode(machine()->Word32And(), lsubject_instance_type, 2270 graph()->NewNode(machine()->Word32And(), lsubject_instance_type,
2370 jsgraph()->Int32Constant(kStringRepresentationMask)), 2271 jsgraph()->Int32Constant(kStringRepresentationMask)),
2371 jsgraph()->Int32Constant(kExternalStringTag)); 2272 jsgraph()->Int32Constant(kSeqStringTag));
2372 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kTrue), 2273 Node* branch0 = graph()->NewNode(common()->Branch(), check0, control);
2373 check2, if_false1); 2274
2374 2275 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
2375 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); 2276 Node* etrue0 = effect;
2376 Node* etrue2 = efalse1; 2277 Node* vtrue0;
2377 Node* vtrue2; 2278 {
2279 // Check if the {lsubject} is a TwoByteSeqString or a OneByteSeqString.
2280 Node* check1 = graph()->NewNode(
2281 machine()->Word32Equal(),
2282 graph()->NewNode(machine()->Word32And(), lsubject_instance_type,
2283 jsgraph()->Int32Constant(kStringEncodingMask)),
2284 jsgraph()->Int32Constant(kTwoByteStringTag));
2285 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
2286
2287 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
2288 Node* etrue1 = etrue0;
2289 Node* vtrue1 = etrue1 =
2290 graph()->NewNode(simplified()->LoadElement(
2291 AccessBuilder::ForSeqTwoByteStringCharacter()),
2292 lsubject, lindex, etrue1, if_true1);
2293
2294 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
2295 Node* efalse1 = etrue0;
2296 Node* vfalse1 = efalse1 =
2297 graph()->NewNode(simplified()->LoadElement(
2298 AccessBuilder::ForSeqOneByteStringCharacter()),
2299 lsubject, lindex, efalse1, if_false1);
2300
2301 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
2302 etrue0 =
2303 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_true0);
2304 vtrue0 =
2305 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
2306 vtrue1, vfalse1, if_true0);
2307 }
2308
2309 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
2310 Node* efalse0 = effect;
2311 Node* vfalse0;
2312 {
2313 // Check if the {lsubject} is a ConsString.
2314 Node* check1 = graph()->NewNode(
2315 machine()->Word32Equal(),
2316 graph()->NewNode(
2317 machine()->Word32And(), lsubject_instance_type,
2318 jsgraph()->Int32Constant(kStringRepresentationMask)),
2319 jsgraph()->Int32Constant(kConsStringTag));
2320 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
2321
2322 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
2323 Node* etrue1 = efalse0;
2324 {
2325 // Load the right hand side of the {lsubject} ConsString.
2326 Node* lsubject_second = etrue1 = graph()->NewNode(
2327 simplified()->LoadField(AccessBuilder::ForConsStringSecond()),
2328 lsubject, etrue1, if_true1);
2329
2330 // Check whether the right hand side is the empty string (i.e. if
2331 // this is really a flat string in a cons string). If that is not
2332 // the case we flatten the string first.
2333 Node* check2 =
2334 graph()->NewNode(machine()->WordEqual(), lsubject_second,
2335 jsgraph()->EmptyStringConstant());
2336 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kTrue),
2337 check2, if_true1);
2338
2339 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
2340 Node* etrue2 = etrue1;
2341 Node* vtrue2 = etrue2 = graph()->NewNode(
2342 simplified()->LoadField(AccessBuilder::ForConsStringFirst()),
2343 lsubject, etrue2, if_true2);
2344
2345 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
2346 Node* efalse2 = etrue1;
2347 Node* vfalse2;
2348 {
2349 // Flatten the {lsubject} ConsString first.
2350 Operator::Properties properties =
2351 Operator::kNoDeopt | Operator::kNoThrow;
2352 Runtime::FunctionId id = Runtime::kFlattenString;
2353 CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor(
2354 graph()->zone(), id, 1, properties, CallDescriptor::kNoFlags);
2355 vfalse2 = efalse2 = graph()->NewNode(
2356 common()->Call(desc), jsgraph()->CEntryStubConstant(1),
2357 lsubject,
2358 jsgraph()->ExternalConstant(ExternalReference(id, isolate())),
2359 jsgraph()->Int32Constant(1), jsgraph()->NoContextConstant(),
2360 efalse2, if_false2);
2361 }
2362
2363 // Retry the {loop} with the new subject.
2364 loop->ReplaceInput(1, if_true2);
2365 lindex->ReplaceInput(1, lindex);
2366 leffect->ReplaceInput(1, etrue2);
2367 lsubject->ReplaceInput(1, vtrue2);
2368 loop->ReplaceInput(2, if_false2);
2369 lindex->ReplaceInput(2, lindex);
2370 leffect->ReplaceInput(2, efalse2);
2371 lsubject->ReplaceInput(2, vfalse2);
2372 }
2373
2374 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
2375 Node* efalse1 = efalse0;
2376 Node* vfalse1;
2377 {
2378 // Check if the {lsubject} is an ExternalString.
2379 Node* check2 = graph()->NewNode(
2380 machine()->Word32Equal(),
2381 graph()->NewNode(
2382 machine()->Word32And(), lsubject_instance_type,
2383 jsgraph()->Int32Constant(kStringRepresentationMask)),
2384 jsgraph()->Int32Constant(kExternalStringTag));
2385 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kTrue),
2386 check2, if_false1);
2387
2388 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
2389 Node* etrue2 = efalse1;
2390 Node* vtrue2;
2391 {
2392 // Check if the {lsubject} is a short external string.
2393 Node* check3 = graph()->NewNode(
2394 machine()->Word32Equal(),
2395 graph()->NewNode(
2396 machine()->Word32And(), lsubject_instance_type,
2397 jsgraph()->Int32Constant(kShortExternalStringMask)),
2398 jsgraph()->Int32Constant(0));
2399 Node* branch3 = graph()->NewNode(
2400 common()->Branch(BranchHint::kTrue), check3, if_true2);
2401
2402 Node* if_true3 = graph()->NewNode(common()->IfTrue(), branch3);
2403 Node* etrue3 = etrue2;
2404 Node* vtrue3;
2405 {
2406 // Load the actual resource data from the {lsubject}.
2407 Node* lsubject_resource_data = etrue3 = graph()->NewNode(
2408 simplified()->LoadField(
2409 AccessBuilder::ForExternalStringResourceData()),
2410 lsubject, etrue3, if_true3);
2411
2412 // Check if the {lsubject} is a TwoByteExternalString or a
2413 // OneByteExternalString.
2414 Node* check4 = graph()->NewNode(
2415 machine()->Word32Equal(),
2416 graph()->NewNode(
2417 machine()->Word32And(), lsubject_instance_type,
2418 jsgraph()->Int32Constant(kStringEncodingMask)),
2419 jsgraph()->Int32Constant(kTwoByteStringTag));
2420 Node* branch4 =
2421 graph()->NewNode(common()->Branch(), check4, if_true3);
2422
2423 Node* if_true4 = graph()->NewNode(common()->IfTrue(), branch4);
2424 Node* etrue4 = etrue3;
2425 Node* vtrue4 = etrue4 = graph()->NewNode(
2426 simplified()->LoadElement(
2427 AccessBuilder::ForExternalTwoByteStringCharacter()),
2428 lsubject_resource_data, lindex, etrue4, if_true4);
2429
2430 Node* if_false4 = graph()->NewNode(common()->IfFalse(), branch4);
2431 Node* efalse4 = etrue3;
2432 Node* vfalse4 = efalse4 = graph()->NewNode(
2433 simplified()->LoadElement(
2434 AccessBuilder::ForExternalOneByteStringCharacter()),
2435 lsubject_resource_data, lindex, efalse4, if_false4);
2436
2437 if_true3 =
2438 graph()->NewNode(common()->Merge(2), if_true4, if_false4);
2439 etrue3 = graph()->NewNode(common()->EffectPhi(2), etrue4, efalse4,
2440 if_true3);
2441 vtrue3 = graph()->NewNode(
2442 common()->Phi(MachineRepresentation::kWord32, 2), vtrue4,
2443 vfalse4, if_true3);
2444 }
2445
2446 Node* if_false3 = graph()->NewNode(common()->IfFalse(), branch3);
2447 Node* efalse3 = etrue2;
2448 Node* vfalse3;
2449 {
2450 // The {lsubject} might be compressed, call the runtime.
2451 Operator::Properties properties =
2452 Operator::kNoDeopt | Operator::kNoThrow;
2453 Runtime::FunctionId id = Runtime::kExternalStringGetChar;
2454 CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor(
2455 graph()->zone(), id, 2, properties, CallDescriptor::kNoFlags);
2456 vfalse3 = efalse3 = graph()->NewNode(
2457 common()->Call(desc), jsgraph()->CEntryStubConstant(1),
2458 lsubject, ChangeInt32ToSmi(lindex),
2459 jsgraph()->ExternalConstant(ExternalReference(id, isolate())),
2460 jsgraph()->Int32Constant(2), jsgraph()->NoContextConstant(),
2461 efalse3, if_false3);
2462 vfalse3 = ChangeSmiToInt32(vfalse3);
2463 }
2464
2465 if_true2 =
2466 graph()->NewNode(common()->Merge(2), if_true3, if_false3);
2467 etrue2 = graph()->NewNode(common()->EffectPhi(2), etrue3, efalse3,
2468 if_true2);
2469 vtrue2 = graph()->NewNode(
2470 common()->Phi(MachineRepresentation::kWord32, 2), vtrue3,
2471 vfalse3, if_true2);
2472 }
2473
2474 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
2475 Node* efalse2 = efalse1;
2476 {
2477 // The {lsubject} is a SlicedString, continue with its parent.
2478 Node* lsubject_parent = efalse2 = graph()->NewNode(
2479 simplified()->LoadField(AccessBuilder::ForSlicedStringParent()),
2480 lsubject, efalse2, if_false2);
2481 Node* lsubject_offset = efalse2 = graph()->NewNode(
2482 simplified()->LoadField(AccessBuilder::ForSlicedStringOffset()),
2483 lsubject, efalse2, if_false2);
2484 Node* lsubject_index =
2485 graph()->NewNode(machine()->Int32Add(), lindex,
2486 ChangeSmiToInt32(lsubject_offset));
2487
2488 // Retry the {loop} with the parent subject.
2489 loop->ReplaceInput(3, if_false2);
2490 leffect->ReplaceInput(3, efalse2);
2491 lindex->ReplaceInput(3, lsubject_index);
2492 lsubject->ReplaceInput(3, lsubject_parent);
2493 }
2494
2495 if_false1 = if_true2;
2496 efalse1 = etrue2;
2497 vfalse1 = vtrue2;
2498 }
2499
2500 if_false0 = if_false1;
2501 efalse0 = efalse1;
2502 vfalse0 = vfalse1;
2503 }
2504
2505 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
2506 effect =
2507 graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
2508 value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
2509 vtrue0, vfalse0, control);
2510 } break;
2511 case StringOperationHint::kSeqStringOrExternalString: {
2512 // We may need to loop several times for ConsString/SlicedString
2513 // {subject}s.
2514 Node* loop = graph()->NewNode(common()->Loop(4), control, control,
2515 control, control);
2516 Node* lsubject =
2517 graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 4),
2518 subject, subject, subject, subject, loop);
2519 Node* lindex =
2520 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 4),
2521 index, index, index, index, loop);
2522 Node* leffect = graph()->NewNode(common()->EffectPhi(4), effect, effect,
2523 effect, effect, loop);
2524
2525 control = loop;
2526 effect = leffect;
2527
2528 // Determine the instance type of {lsubject}.
2529 Node* lsubject_map = effect =
2530 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
2531 lsubject, effect, control);
2532 Node* lsubject_instance_type = effect = graph()->NewNode(
2533 simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
2534 lsubject_map, effect, control);
2535
2536 // Check if {lsubject} is a SeqString.
2537 Node* check0 = graph()->NewNode(
2538 machine()->Word32Equal(),
2539 graph()->NewNode(machine()->Word32And(), lsubject_instance_type,
2540 jsgraph()->Int32Constant(kStringRepresentationMask)),
2541 jsgraph()->Int32Constant(kSeqStringTag));
2542 Node* branch0 = graph()->NewNode(common()->Branch(), check0, control);
2543
2544 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
2545 Node* etrue0 = effect;
2546 Node* vtrue0;
2547 {
2548 // Check if the {lsubject} is a TwoByteSeqString or a OneByteSeqString.
2549 Node* check1 = graph()->NewNode(
2550 machine()->Word32Equal(),
2551 graph()->NewNode(machine()->Word32And(), lsubject_instance_type,
2552 jsgraph()->Int32Constant(kStringEncodingMask)),
2553 jsgraph()->Int32Constant(kTwoByteStringTag));
2554 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
2555
2556 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
2557 Node* etrue1 = etrue0;
2558 Node* vtrue1 = etrue1 =
2559 graph()->NewNode(simplified()->LoadElement(
2560 AccessBuilder::ForSeqTwoByteStringCharacter()),
2561 lsubject, lindex, etrue1, if_true1);
2562
2563 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
2564 Node* efalse1 = etrue0;
2565 Node* vfalse1 = efalse1 =
2566 graph()->NewNode(simplified()->LoadElement(
2567 AccessBuilder::ForSeqOneByteStringCharacter()),
2568 lsubject, lindex, efalse1, if_false1);
2569
2570 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
2571 etrue0 =
2572 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_true0);
2573 vtrue0 =
2574 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
2575 vtrue1, vfalse1, if_true0);
2576 }
2577
2578 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
2579 Node* efalse0 = effect;
2580 Node* vfalse0;
2378 { 2581 {
2379 // Check if the {lsubject} is a short external string. 2582 // Check if the {lsubject} is a short external string.
2380 Node* check3 = graph()->NewNode( 2583 Node* check1 = graph()->NewNode(
2381 machine()->Word32Equal(), 2584 machine()->Word32Equal(),
2382 graph()->NewNode( 2585 graph()->NewNode(
2383 machine()->Word32And(), lsubject_instance_type, 2586 machine()->Word32And(), lsubject_instance_type,
2384 jsgraph()->Int32Constant(kShortExternalStringMask)), 2587 jsgraph()->Int32Constant(kShortExternalStringMask)),
2385 jsgraph()->Int32Constant(0)); 2588 jsgraph()->Int32Constant(0));
2386 Node* branch3 = graph()->NewNode(common()->Branch(BranchHint::kTrue), 2589 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kTrue),
2387 check3, if_true2); 2590 check1, if_false0);
2388 2591
2389 Node* if_true3 = graph()->NewNode(common()->IfTrue(), branch3); 2592 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
2390 Node* etrue3 = etrue2; 2593 Node* etrue1 = efalse0;
2391 Node* vtrue3; 2594 Node* vtrue1;
2392 { 2595 {
2393 // Load the actual resource data from the {lsubject}. 2596 // Load the actual resource data from the {lsubject}.
2394 Node* lsubject_resource_data = etrue3 = graph()->NewNode( 2597 Node* lsubject_resource_data = etrue1 = graph()->NewNode(
2395 simplified()->LoadField( 2598 simplified()->LoadField(
2396 AccessBuilder::ForExternalStringResourceData()), 2599 AccessBuilder::ForExternalStringResourceData()),
2397 lsubject, etrue3, if_true3); 2600 lsubject, etrue1, if_true1);
2398 2601
2399 // Check if the {lsubject} is a TwoByteExternalString or a 2602 // Check if the {lsubject} is a TwoByteExternalString or a
2400 // OneByteExternalString. 2603 // OneByteExternalString.
2401 Node* check4 = graph()->NewNode( 2604 Node* check2 = graph()->NewNode(
2402 machine()->Word32Equal(), 2605 machine()->Word32Equal(),
2403 graph()->NewNode(machine()->Word32And(), lsubject_instance_type, 2606 graph()->NewNode(machine()->Word32And(), lsubject_instance_type,
2404 jsgraph()->Int32Constant(kStringEncodingMask)), 2607 jsgraph()->Int32Constant(kStringEncodingMask)),
2405 jsgraph()->Int32Constant(kTwoByteStringTag)); 2608 jsgraph()->Int32Constant(kTwoByteStringTag));
2406 Node* branch4 = 2609 Node* branch2 =
2407 graph()->NewNode(common()->Branch(), check4, if_true3); 2610 graph()->NewNode(common()->Branch(), check2, if_true1);
2408 2611
2409 Node* if_true4 = graph()->NewNode(common()->IfTrue(), branch4); 2612 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
2410 Node* etrue4 = etrue3; 2613 Node* etrue2 = etrue1;
2411 Node* vtrue4 = etrue4 = graph()->NewNode( 2614 Node* vtrue2 = etrue2 = graph()->NewNode(
2412 simplified()->LoadElement( 2615 simplified()->LoadElement(
2413 AccessBuilder::ForExternalTwoByteStringCharacter()), 2616 AccessBuilder::ForExternalTwoByteStringCharacter()),
2414 lsubject_resource_data, lindex, etrue4, if_true4); 2617 lsubject_resource_data, index, etrue2, if_true2);
2415 2618
2416 Node* if_false4 = graph()->NewNode(common()->IfFalse(), branch4); 2619 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
2417 Node* efalse4 = etrue3; 2620 Node* efalse2 = etrue1;
2418 Node* vfalse4 = efalse4 = graph()->NewNode( 2621 Node* vfalse2 = efalse2 = graph()->NewNode(
2419 simplified()->LoadElement( 2622 simplified()->LoadElement(
2420 AccessBuilder::ForExternalOneByteStringCharacter()), 2623 AccessBuilder::ForExternalOneByteStringCharacter()),
2421 lsubject_resource_data, lindex, efalse4, if_false4); 2624 lsubject_resource_data, index, efalse2, if_false2);
2422 2625
2423 if_true3 = graph()->NewNode(common()->Merge(2), if_true4, if_false4); 2626 if_true1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
2424 etrue3 = graph()->NewNode(common()->EffectPhi(2), etrue4, efalse4, 2627 etrue1 = graph()->NewNode(common()->EffectPhi(2), etrue2, efalse2,
2425 if_true3); 2628 if_true1);
2426 vtrue3 = 2629 vtrue1 =
2427 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), 2630 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
2428 vtrue4, vfalse4, if_true3); 2631 vtrue2, vfalse2, if_true1);
2429 } 2632 }
2430 2633
2431 Node* if_false3 = graph()->NewNode(common()->IfFalse(), branch3); 2634 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
2432 Node* efalse3 = etrue2; 2635 Node* efalse1 = efalse0;
2433 Node* vfalse3; 2636 Node* vfalse1;
2434 { 2637 {
2435 // The {lsubject} might be compressed, call the runtime. 2638 // The {lsubject} might be compressed, call the runtime.
2436 Operator::Properties properties = 2639 Operator::Properties properties =
2437 Operator::kNoDeopt | Operator::kNoThrow; 2640 Operator::kNoDeopt | Operator::kNoThrow;
2438 Runtime::FunctionId id = Runtime::kExternalStringGetChar; 2641 Runtime::FunctionId id = Runtime::kExternalStringGetChar;
2439 CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor( 2642 CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor(
2440 graph()->zone(), id, 2, properties, CallDescriptor::kNoFlags); 2643 graph()->zone(), id, 2, properties, CallDescriptor::kNoFlags);
2441 vfalse3 = efalse3 = graph()->NewNode( 2644 vfalse1 = efalse1 = graph()->NewNode(
2442 common()->Call(desc), jsgraph()->CEntryStubConstant(1), lsubject, 2645 common()->Call(desc), jsgraph()->CEntryStubConstant(1), lsubject,
2443 ChangeInt32ToSmi(lindex), 2646 ChangeInt32ToSmi(index),
2444 jsgraph()->ExternalConstant(ExternalReference(id, isolate())), 2647 jsgraph()->ExternalConstant(ExternalReference(id, isolate())),
2445 jsgraph()->Int32Constant(2), jsgraph()->NoContextConstant(), 2648 jsgraph()->Int32Constant(2), jsgraph()->NoContextConstant(),
2446 efalse3, if_false3); 2649 efalse1, if_false1);
2447 vfalse3 = ChangeSmiToInt32(vfalse3); 2650 vfalse1 = ChangeSmiToInt32(vfalse1);
2448 } 2651 }
2449 2652
2450 if_true2 = graph()->NewNode(common()->Merge(2), if_true3, if_false3); 2653 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
2451 etrue2 = 2654 efalse0 = graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1,
2452 graph()->NewNode(common()->EffectPhi(2), etrue3, efalse3, if_true2); 2655 if_false0);
2453 vtrue2 = 2656 vfalse0 =
2454 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), 2657 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
2455 vtrue3, vfalse3, if_true2); 2658 vtrue1, vfalse1, if_false0);
2456 } 2659 }
2457 2660
2458 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); 2661 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
2459 Node* efalse2 = efalse1; 2662 effect =
2460 { 2663 graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
2461 // The {lsubject} is a SlicedString, continue with its parent. 2664 value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
2462 Node* lsubject_parent = efalse2 = graph()->NewNode( 2665 vtrue0, vfalse0, control);
2463 simplified()->LoadField(AccessBuilder::ForSlicedStringParent()), 2666 break;
2464 lsubject, efalse2, if_false2);
2465 Node* lsubject_offset = efalse2 = graph()->NewNode(
2466 simplified()->LoadField(AccessBuilder::ForSlicedStringOffset()),
2467 lsubject, efalse2, if_false2);
2468 Node* lsubject_index = graph()->NewNode(
2469 machine()->Int32Add(), lindex, ChangeSmiToInt32(lsubject_offset));
2470
2471 // Retry the {loop} with the parent subject.
2472 loop->ReplaceInput(3, if_false2);
2473 leffect->ReplaceInput(3, efalse2);
2474 lindex->ReplaceInput(3, lsubject_index);
2475 lsubject->ReplaceInput(3, lsubject_parent);
2476 }
2477
2478 if_false1 = if_true2;
2479 efalse1 = etrue2;
2480 vfalse1 = vtrue2;
2481 } 2667 }
2482
2483 if_false0 = if_false1;
2484 efalse0 = efalse1;
2485 vfalse0 = vfalse1;
2486 } 2668 }
2487 2669
2488 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
2489 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
2490 Node* value =
2491 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue0,
2492 vfalse0, control);
2493
2494 return ValueEffectControl(value, effect, control); 2670 return ValueEffectControl(value, effect, control);
2495 } 2671 }
2496 2672
2497 EffectControlLinearizer::ValueEffectControl 2673 EffectControlLinearizer::ValueEffectControl
2498 EffectControlLinearizer::LowerStringFromCharCode(Node* node, Node* effect, 2674 EffectControlLinearizer::LowerStringFromCharCode(Node* node, Node* effect,
2499 Node* control) { 2675 Node* control) {
2500 Node* value = node->InputAt(0); 2676 Node* value = node->InputAt(0);
2501 2677
2502 // Compute the character code. 2678 // Compute the character code.
2503 Node* code = 2679 Node* code =
(...skipping 10 matching lines...) Expand all
2514 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); 2690 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
2515 Node* etrue0 = effect; 2691 Node* etrue0 = effect;
2516 Node* vtrue0; 2692 Node* vtrue0;
2517 { 2693 {
2518 // Load the isolate wide single character string cache. 2694 // Load the isolate wide single character string cache.
2519 Node* cache = 2695 Node* cache =
2520 jsgraph()->HeapConstant(factory()->single_character_string_cache()); 2696 jsgraph()->HeapConstant(factory()->single_character_string_cache());
2521 2697
2522 // Compute the {cache} index for {code}. 2698 // Compute the {cache} index for {code}.
2523 Node* index = 2699 Node* index =
2524 machine()->Is32() ? code : graph()->NewNode( 2700 machine()->Is32()
2525 machine()->ChangeUint32ToUint64(), code); 2701 ? code
2702 : graph()->NewNode(machine()->ChangeUint32ToUint64(), code);
2526 2703
2527 // Check if we have an entry for the {code} in the single character string 2704 // Check if we have an entry for the {code} in the single character string
2528 // cache already. 2705 // cache already.
2529 Node* entry = etrue0 = graph()->NewNode( 2706 Node* entry = etrue0 = graph()->NewNode(
2530 simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()), cache, 2707 simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()), cache,
2531 index, etrue0, if_true0); 2708 index, etrue0, if_true0);
2532 2709
2533 Node* check1 = graph()->NewNode(machine()->WordEqual(), entry, 2710 Node* check1 = graph()->NewNode(machine()->WordEqual(), entry,
2534 jsgraph()->UndefinedConstant()); 2711 jsgraph()->UndefinedConstant());
2535 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse), 2712 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2607 2784
2608 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); 2785 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
2609 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); 2786 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
2610 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), 2787 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
2611 vtrue0, vfalse0, control); 2788 vtrue0, vfalse0, control);
2612 2789
2613 return ValueEffectControl(value, effect, control); 2790 return ValueEffectControl(value, effect, control);
2614 } 2791 }
2615 2792
2616 EffectControlLinearizer::ValueEffectControl 2793 EffectControlLinearizer::ValueEffectControl
2794 EffectControlLinearizer::LowerStringFromCodePoint(Node* node, Node* effect,
2795 Node* control) {
2796 Node* value = node->InputAt(0);
2797 Node* code = value;
2798
2799 Node* etrue0 = effect;
2800 Node* vtrue0;
2801
2802 // Check if the {code} is a single code unit
2803 Node* check0 = graph()->NewNode(machine()->Uint32LessThanOrEqual(), code,
2804 jsgraph()->Uint32Constant(0xFFFF));
2805 Node* branch0 =
2806 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
2807
2808 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
2809
2810 // Check if the {code} is a one byte character
2811 Node* check1 =
2812 graph()->NewNode(machine()->Uint32LessThanOrEqual(), code,
2813 jsgraph()->Uint32Constant(String::kMaxOneByteCharCode));
2814 Node* branch1 =
2815 graph()->NewNode(common()->Branch(BranchHint::kTrue), check1, if_true0);
2816
2817 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
2818 Node* etrue1 = etrue0;
2819 Node* vtrue1;
2820 {
2821 // Load the isolate wide single character string cache.
2822 Node* cache =
2823 jsgraph()->HeapConstant(factory()->single_character_string_cache());
2824
2825 // Compute the {cache} index for {code}.
2826 Node* index =
2827 machine()->Is32()
2828 ? code
2829 : graph()->NewNode(machine()->ChangeUint32ToUint64(), code);
2830
2831 // Check if we have an entry for the {code} in the single character string
2832 // cache already.
2833 Node* entry = etrue1 = graph()->NewNode(
2834 simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()), cache,
2835 index, etrue1, if_true1);
2836
2837 Node* check2 = graph()->NewNode(machine()->WordEqual(), entry,
2838 jsgraph()->UndefinedConstant());
2839 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
2840 check2, if_true1);
2841
2842 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
2843 Node* etrue2 = etrue1;
2844 Node* vtrue2;
2845 {
2846 // Allocate a new SeqOneByteString for {code}.
2847 vtrue2 = etrue2 = graph()->NewNode(
2848 simplified()->Allocate(NOT_TENURED),
2849 jsgraph()->Int32Constant(SeqOneByteString::SizeFor(1)), etrue2,
2850 if_true2);
2851 etrue2 = graph()->NewNode(
2852 simplified()->StoreField(AccessBuilder::ForMap()), vtrue2,
2853 jsgraph()->HeapConstant(factory()->one_byte_string_map()), etrue2,
2854 if_true2);
2855 etrue2 = graph()->NewNode(
2856 simplified()->StoreField(AccessBuilder::ForNameHashField()), vtrue2,
2857 jsgraph()->IntPtrConstant(Name::kEmptyHashField), etrue2, if_true2);
2858 etrue2 = graph()->NewNode(
2859 simplified()->StoreField(AccessBuilder::ForStringLength()), vtrue2,
2860 jsgraph()->SmiConstant(1), etrue2, if_true2);
2861 etrue2 = graph()->NewNode(
2862 machine()->Store(StoreRepresentation(MachineRepresentation::kWord8,
2863 kNoWriteBarrier)),
2864 vtrue2, jsgraph()->IntPtrConstant(SeqOneByteString::kHeaderSize -
2865 kHeapObjectTag),
2866 code, etrue2, if_true2);
2867
2868 // Remember it in the {cache}.
2869 etrue2 = graph()->NewNode(
2870 simplified()->StoreElement(AccessBuilder::ForFixedArrayElement()),
2871 cache, index, vtrue2, etrue2, if_true2);
2872 }
2873
2874 // Use the {entry} from the {cache}.
2875 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
2876 Node* efalse2 = etrue0;
2877 Node* vfalse2 = entry;
2878
2879 if_true1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
2880 etrue1 =
2881 graph()->NewNode(common()->EffectPhi(2), etrue2, efalse2, if_true1);
2882 vtrue1 = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
2883 vtrue2, vfalse2, if_true1);
2884 }
2885
2886 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
2887 Node* efalse1 = effect;
2888 Node* vfalse1;
2889 {
2890 // Allocate a new SeqTwoByteString for {code}.
2891 vfalse1 = efalse1 =
2892 graph()->NewNode(simplified()->Allocate(NOT_TENURED),
2893 jsgraph()->Int32Constant(SeqTwoByteString::SizeFor(1)),
2894 efalse1, if_false1);
2895 efalse1 = graph()->NewNode(
2896 simplified()->StoreField(AccessBuilder::ForMap()), vfalse1,
2897 jsgraph()->HeapConstant(factory()->string_map()), efalse1, if_false1);
2898 efalse1 = graph()->NewNode(
2899 simplified()->StoreField(AccessBuilder::ForNameHashField()), vfalse1,
2900 jsgraph()->IntPtrConstant(Name::kEmptyHashField), efalse1, if_false1);
2901 efalse1 = graph()->NewNode(
2902 simplified()->StoreField(AccessBuilder::ForStringLength()), vfalse1,
2903 jsgraph()->SmiConstant(1), efalse1, if_false1);
2904 efalse1 = graph()->NewNode(
2905 machine()->Store(StoreRepresentation(MachineRepresentation::kWord16,
2906 kNoWriteBarrier)),
2907 vfalse1, jsgraph()->IntPtrConstant(SeqTwoByteString::kHeaderSize -
2908 kHeapObjectTag),
2909 code, efalse1, if_false1);
2910 }
2911
2912 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
2913 etrue0 = graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_true0);
2914 vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
2915 vtrue1, vfalse1, control);
2916
2917 // Generate surrogate pair string
2918 Node* if_false0 = graph()->NewNode(common()->IfTrue(), branch0);
2919 Node* efalse0 = effect;
2920 Node* vfalse0;
2921 {
2922 switch (UnicodeEncodingOf(node->op())) {
2923 case UnicodeEncoding::UTF16:
2924 break;
2925
2926 case UnicodeEncoding::UTF32: {
2927 // Convert UTF32 to UTF16 code units, and store as a 32 bit word.
2928 Node* lead_offset = jsgraph()->Int32Constant(0xD800 - (0x10000 >> 10));
2929
2930 // lead = (codepoint >> 10) + LEAD_OFFSET
2931 Node* lead =
2932 graph()->NewNode(machine()->Int32Add(),
2933 graph()->NewNode(machine()->Word32Shr(), code,
2934 jsgraph()->Int32Constant(10)),
2935 lead_offset);
2936
2937 // trail = (codepoint & 0x3FF) + 0xDC00;
2938 Node* trail =
2939 graph()->NewNode(machine()->Int32Add(),
2940 graph()->NewNode(machine()->Word32And(), code,
2941 jsgraph()->Int32Constant(0x3FF)),
2942 jsgraph()->Int32Constant(0xDC00));
2943
2944 // codpoint = (trail << 16) | lead;
2945 code = efalse1 =
2946 graph()->NewNode(machine()->Word32Or(),
2947 graph()->NewNode(machine()->Word32Shl(), trail,
2948 jsgraph()->Int32Constant(16)),
2949 lead);
2950 break;
2951 }
2952 }
2953
2954 // Allocate a new SeqTwoByteString for {code}.
2955 vfalse0 = efalse0 =
2956 graph()->NewNode(simplified()->Allocate(NOT_TENURED),
2957 jsgraph()->Int32Constant(SeqTwoByteString::SizeFor(2)),
2958 efalse0, if_false0);
2959 efalse0 = graph()->NewNode(
2960 simplified()->StoreField(AccessBuilder::ForMap()), vfalse0,
2961 jsgraph()->HeapConstant(factory()->string_map()), efalse0, if_false0);
2962 efalse0 = graph()->NewNode(
2963 simplified()->StoreField(AccessBuilder::ForNameHashField()), vfalse0,
2964 jsgraph()->IntPtrConstant(Name::kEmptyHashField), efalse0, if_false1);
2965 efalse0 = graph()->NewNode(
2966 simplified()->StoreField(AccessBuilder::ForStringLength()), vfalse0,
2967 jsgraph()->SmiConstant(2), efalse0, if_false0);
2968 efalse0 = graph()->NewNode(
2969 machine()->Store(StoreRepresentation(MachineRepresentation::kWord32,
2970 kNoWriteBarrier)),
2971 vfalse0, jsgraph()->IntPtrConstant(SeqTwoByteString::kHeaderSize -
2972 kHeapObjectTag),
2973 code, efalse0, if_false0);
2974 }
2975
2976 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
2977 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
2978 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
2979 vtrue0, vfalse0, control);
2980
2981 return ValueEffectControl(value, effect, control);
2982 }
2983
2984 EffectControlLinearizer::ValueEffectControl
2617 EffectControlLinearizer::LowerStringComparison(Callable const& callable, 2985 EffectControlLinearizer::LowerStringComparison(Callable const& callable,
2618 Node* node, Node* effect, 2986 Node* node, Node* effect,
2619 Node* control) { 2987 Node* control) {
2620 Operator::Properties properties = Operator::kEliminatable; 2988 Operator::Properties properties = Operator::kEliminatable;
2621 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; 2989 CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
2622 CallDescriptor* desc = Linkage::GetStubCallDescriptor( 2990 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
2623 isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties); 2991 isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties);
2624 node->InsertInput(graph()->zone(), 0, 2992 node->InsertInput(graph()->zone(), 0,
2625 jsgraph()->HeapConstant(callable.code())); 2993 jsgraph()->HeapConstant(callable.code()));
2626 node->AppendInput(graph()->zone(), jsgraph()->NoContextConstant()); 2994 node->AppendInput(graph()->zone(), jsgraph()->NoContextConstant());
(...skipping 928 matching lines...) Expand 10 before | Expand all | Expand 10 after
3555 isolate(), graph()->zone(), callable.descriptor(), 0, flags, 3923 isolate(), graph()->zone(), callable.descriptor(), 0, flags,
3556 Operator::kEliminatable); 3924 Operator::kEliminatable);
3557 to_number_operator_.set(common()->Call(desc)); 3925 to_number_operator_.set(common()->Call(desc));
3558 } 3926 }
3559 return to_number_operator_.get(); 3927 return to_number_operator_.get();
3560 } 3928 }
3561 3929
3562 } // namespace compiler 3930 } // namespace compiler
3563 } // namespace internal 3931 } // namespace internal
3564 } // namespace v8 3932 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698