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

Side by Side Diff: src/code-stub-assembler.cc

Issue 2327703003: [builtins] Migrate ToNumber to TurboFan. (Closed)
Patch Set: Created 4 years, 3 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 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/code-stub-assembler.h" 5 #include "src/code-stub-assembler.h"
6 #include "src/code-factory.h" 6 #include "src/code-factory.h"
7 #include "src/frames-inl.h" 7 #include "src/frames-inl.h"
8 #include "src/frames.h" 8 #include "src/frames.h"
9 #include "src/ic/handler-configuration.h" 9 #include "src/ic/handler-configuration.h"
10 #include "src/ic/stub-cache.h" 10 #include "src/ic/stub-cache.h"
(...skipping 2342 matching lines...) Expand 10 before | Expand all | Expand 10 after
2353 Bind(&runtime); 2353 Bind(&runtime);
2354 { 2354 {
2355 var_result.Bind(CallRuntime(Runtime::kStringToNumber, context, input)); 2355 var_result.Bind(CallRuntime(Runtime::kStringToNumber, context, input));
2356 Goto(&end); 2356 Goto(&end);
2357 } 2357 }
2358 2358
2359 Bind(&end); 2359 Bind(&end);
2360 return var_result.value(); 2360 return var_result.value();
2361 } 2361 }
2362 2362
2363 Node* CodeStubAssembler::NonNumberToNumber(Node* context, Node* input) {
2364 // Assert input is a HeapObject (not smi or heap number)
2365 Assert(Word32BinaryNot(WordIsSmi(input)));
2366 Assert(
2367 Word32NotEqual(LoadInstanceType(input), Int32Constant(HEAP_NUMBER_TYPE)));
Igor Sheludko 2016/09/09 11:33:15 How about doing a map check here?
2368
2369 // We might need to loop once here due to ToPrimitive conversions.
2370 Variable var_input(this, MachineRepresentation::kTagged);
2371 Variable var_result(this, MachineRepresentation::kTagged);
2372 Label loop(this, &var_input);
2373 Label end(this);
2374 var_input.Bind(input);
2375 Goto(&loop);
2376 Bind(&loop);
2377 {
2378 // Load the current {input} value (known to be a HeapObject).
2379 Node* input = var_input.value();
2380
2381 // Dispatch on the {input} instance type.
2382 Node* input_instance_type = LoadInstanceType(input);
2383 Label if_inputisstring(this), if_inputisoddball(this),
2384 if_inputisreceiver(this, Label::kDeferred),
2385 if_inputisother(this, Label::kDeferred);
2386 GotoIf(
2387 Int32LessThan(input_instance_type, Int32Constant(FIRST_NONSTRING_TYPE)),
2388 &if_inputisstring);
2389 GotoIf(Word32Equal(input_instance_type, Int32Constant(ODDBALL_TYPE)),
2390 &if_inputisoddball);
2391 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
2392 Branch(Int32GreaterThanOrEqual(input_instance_type,
2393 Int32Constant(FIRST_JS_RECEIVER_TYPE)),
2394 &if_inputisreceiver, &if_inputisother);
2395
2396 Bind(&if_inputisstring);
2397 {
2398 // The {input} is a String, use the fast stub to convert it to a Number.
2399 var_result.Bind(StringToNumber(context, input));
2400 Goto(&end);
2401 }
2402
2403 Bind(&if_inputisoddball);
2404 {
2405 // The {input} is an Oddball, we just need to load the Number value of it.
2406 var_result.Bind(LoadObjectField(input, Oddball::kToNumberOffset));
2407 Goto(&end);
2408 }
2409
2410 Bind(&if_inputisreceiver);
2411 {
2412 // The {input} is a JSReceiver, we need to convert it to a Primitive first
2413 // using the ToPrimitive type conversion, preferably yielding a Number.
2414 Callable callable = CodeFactory::NonPrimitiveToPrimitive(
2415 isolate(), ToPrimitiveHint::kNumber);
2416 Node* result = CallStub(callable, context, input);
2417
2418 // Check if the {result} is already a Number.
2419 Label if_resultisnumber(this), if_resultisnotnumber(this);
2420 GotoIf(WordIsSmi(result), &if_resultisnumber);
2421 Node* result_map = LoadMap(result);
2422 Branch(WordEqual(result_map, HeapNumberMapConstant()), &if_resultisnumber,
2423 &if_resultisnotnumber);
2424
2425 Bind(&if_resultisnumber);
2426 {
2427 // The ToPrimitive conversion already gave us a Number, so we're done.
2428 var_result.Bind(result);
2429 Goto(&end);
2430 }
2431
2432 Bind(&if_resultisnotnumber);
2433 {
2434 // We now have a Primitive {result}, but it's not yet a Number.
2435 var_input.Bind(result);
2436 Goto(&loop);
2437 }
2438 }
2439
2440 Bind(&if_inputisother);
2441 {
2442 // The {input} is something else (i.e. Symbol or Simd128Value), let the
2443 // runtime figure out the correct exception.
2444 // Note: We cannot tail call to the runtime here, as js-to-wasm
2445 // trampolines also use this code currently, and they declare all
2446 // outgoing parameters as untagged, while we would push a tagged
2447 // object here.
2448 var_result.Bind(CallRuntime(Runtime::kToNumber, context, input));
2449 Goto(&end);
2450 }
2451 }
2452
2453 Bind(&end);
2454 return var_result.value();
2455 }
2456
2457 Node* CodeStubAssembler::ToNumber(Node* context, Node* input) {
2458 Variable var_result(this, MachineRepresentation::kTagged);
2459 Label end(this);
2460
2461 Label not_smi(this, Label::kDeferred);
2462 GotoUnless(WordIsSmi(input), &not_smi);
2463 var_result.Bind(input);
2464 Goto(&end);
2465
2466 Bind(&not_smi);
2467 {
2468 Label not_heap_number(this, Label::kDeferred);
2469 Node* input_instance_type = LoadInstanceType(input);
2470 GotoIf(Word32NotEqual(input_instance_type, Int32Constant(HEAP_NUMBER_TYPE)),
Igor Sheludko 2016/09/09 11:33:15 While we are here, how about doing a map check ins
2471 &not_heap_number);
2472
2473 var_result.Bind(input);
2474 Goto(&end);
2475
2476 Bind(&not_heap_number);
2477 {
2478 var_result.Bind(NonNumberToNumber(context, input));
2479 Goto(&end);
2480 }
2481 }
2482
2483 Bind(&end);
2484 return var_result.value();
2485 }
2486
2363 Node* CodeStubAssembler::BitFieldDecode(Node* word32, uint32_t shift, 2487 Node* CodeStubAssembler::BitFieldDecode(Node* word32, uint32_t shift,
2364 uint32_t mask) { 2488 uint32_t mask) {
2365 return Word32Shr(Word32And(word32, Int32Constant(mask)), 2489 return Word32Shr(Word32And(word32, Int32Constant(mask)),
2366 static_cast<int>(shift)); 2490 static_cast<int>(shift));
2367 } 2491 }
2368 2492
2369 void CodeStubAssembler::SetCounter(StatsCounter* counter, int value) { 2493 void CodeStubAssembler::SetCounter(StatsCounter* counter, int value) {
2370 if (FLAG_native_code_counters && counter->Enabled()) { 2494 if (FLAG_native_code_counters && counter->Enabled()) {
2371 Node* counter_address = ExternalConstant(ExternalReference(counter)); 2495 Node* counter_address = ExternalConstant(ExternalReference(counter));
2372 StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address, 2496 StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address,
(...skipping 1948 matching lines...) Expand 10 before | Expand all | Expand 10 after
4321 Heap::kTheHoleValueRootIndex); 4445 Heap::kTheHoleValueRootIndex);
4322 4446
4323 // Store the WeakCell in the feedback vector. 4447 // Store the WeakCell in the feedback vector.
4324 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, 4448 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER,
4325 CodeStubAssembler::SMI_PARAMETERS); 4449 CodeStubAssembler::SMI_PARAMETERS);
4326 return cell; 4450 return cell;
4327 } 4451 }
4328 4452
4329 } // namespace internal 4453 } // namespace internal
4330 } // namespace v8 4454 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698