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

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 15302004: Convert ToBooleanStub to a HydrogenStub. Currently just using HBranch, which is still fully impleme… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: fix Created 7 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « src/hydrogen-instructions.h ('k') | src/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 CodeStubInterfaceDescriptor* descriptor) { 173 CodeStubInterfaceDescriptor* descriptor) {
174 static Register registers[] = { eax }; 174 static Register registers[] = { eax };
175 descriptor->register_param_count_ = 1; 175 descriptor->register_param_count_ = 1;
176 descriptor->register_params_ = registers; 176 descriptor->register_params_ = registers;
177 descriptor->deoptimization_handler_ = 177 descriptor->deoptimization_handler_ =
178 FUNCTION_ADDR(CompareNilIC_Miss); 178 FUNCTION_ADDR(CompareNilIC_Miss);
179 descriptor->SetMissHandler( 179 descriptor->SetMissHandler(
180 ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate)); 180 ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate));
181 } 181 }
182 182
183 void ToBooleanStub::InitializeInterfaceDescriptor(
184 Isolate* isolate,
185 CodeStubInterfaceDescriptor* descriptor) {
186 static Register registers[] = { eax };
187 descriptor->register_param_count_ = 1;
188 descriptor->register_params_ = registers;
189 descriptor->deoptimization_handler_ =
190 FUNCTION_ADDR(ToBooleanIC_Miss);
191 descriptor->SetMissHandler(
192 ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate));
193 }
194
183 195
184 #define __ ACCESS_MASM(masm) 196 #define __ ACCESS_MASM(masm)
185 197
186 198
187 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { 199 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
188 // Update the static counter each time a new code stub is generated. 200 // Update the static counter each time a new code stub is generated.
189 Isolate* isolate = masm->isolate(); 201 Isolate* isolate = masm->isolate();
190 isolate->counters()->code_stubs()->Increment(); 202 isolate->counters()->code_stubs()->Increment();
191 203
192 CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(isolate); 204 CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(isolate);
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 // Return and remove the on-stack parameters. 474 // Return and remove the on-stack parameters.
463 __ mov(esi, eax); 475 __ mov(esi, eax);
464 __ ret(2 * kPointerSize); 476 __ ret(2 * kPointerSize);
465 477
466 // Need to collect. Call into runtime system. 478 // Need to collect. Call into runtime system.
467 __ bind(&gc); 479 __ bind(&gc);
468 __ TailCallRuntime(Runtime::kPushBlockContext, 2, 1); 480 __ TailCallRuntime(Runtime::kPushBlockContext, 2, 1);
469 } 481 }
470 482
471 483
472 // The stub expects its argument on the stack and returns its result in tos_:
473 // zero for false, and a non-zero value for true.
474 void ToBooleanStub::Generate(MacroAssembler* masm) {
475 // This stub overrides SometimesSetsUpAFrame() to return false. That means
476 // we cannot call anything that could cause a GC from this stub.
477 Label patch;
478 Factory* factory = masm->isolate()->factory();
479 const Register argument = eax;
480 const Register map = edx;
481
482 if (!types_.IsEmpty()) {
483 __ mov(argument, Operand(esp, 1 * kPointerSize));
484 }
485
486 // undefined -> false
487 CheckOddball(masm, UNDEFINED, Heap::kUndefinedValueRootIndex, false);
488
489 // Boolean -> its value
490 CheckOddball(masm, BOOLEAN, Heap::kFalseValueRootIndex, false);
491 CheckOddball(masm, BOOLEAN, Heap::kTrueValueRootIndex, true);
492
493 // 'null' -> false.
494 CheckOddball(masm, NULL_TYPE, Heap::kNullValueRootIndex, false);
495
496 if (types_.Contains(SMI)) {
497 // Smis: 0 -> false, all other -> true
498 Label not_smi;
499 __ JumpIfNotSmi(argument, &not_smi, Label::kNear);
500 // argument contains the correct return value already.
501 if (!tos_.is(argument)) {
502 __ mov(tos_, argument);
503 }
504 __ ret(1 * kPointerSize);
505 __ bind(&not_smi);
506 } else if (types_.NeedsMap()) {
507 // If we need a map later and have a Smi -> patch.
508 __ JumpIfSmi(argument, &patch, Label::kNear);
509 }
510
511 if (types_.NeedsMap()) {
512 __ mov(map, FieldOperand(argument, HeapObject::kMapOffset));
513
514 if (types_.CanBeUndetectable()) {
515 __ test_b(FieldOperand(map, Map::kBitFieldOffset),
516 1 << Map::kIsUndetectable);
517 // Undetectable -> false.
518 Label not_undetectable;
519 __ j(zero, &not_undetectable, Label::kNear);
520 __ Set(tos_, Immediate(0));
521 __ ret(1 * kPointerSize);
522 __ bind(&not_undetectable);
523 }
524 }
525
526 if (types_.Contains(SPEC_OBJECT)) {
527 // spec object -> true.
528 Label not_js_object;
529 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
530 __ j(below, &not_js_object, Label::kNear);
531 // argument contains the correct return value already.
532 if (!tos_.is(argument)) {
533 __ Set(tos_, Immediate(1));
534 }
535 __ ret(1 * kPointerSize);
536 __ bind(&not_js_object);
537 }
538
539 if (types_.Contains(STRING)) {
540 // String value -> false iff empty.
541 Label not_string;
542 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE);
543 __ j(above_equal, &not_string, Label::kNear);
544 __ mov(tos_, FieldOperand(argument, String::kLengthOffset));
545 __ ret(1 * kPointerSize); // the string length is OK as the return value
546 __ bind(&not_string);
547 }
548
549 if (types_.Contains(SYMBOL)) {
550 // Symbol value -> true.
551 Label not_symbol;
552 __ CmpInstanceType(map, SYMBOL_TYPE);
553 __ j(not_equal, &not_symbol, Label::kNear);
554 __ bind(&not_symbol);
555 }
556
557 if (types_.Contains(HEAP_NUMBER)) {
558 // heap number -> false iff +0, -0, or NaN.
559 Label not_heap_number, false_result;
560 __ cmp(map, factory->heap_number_map());
561 __ j(not_equal, &not_heap_number, Label::kNear);
562 __ fldz();
563 __ fld_d(FieldOperand(argument, HeapNumber::kValueOffset));
564 __ FCmp();
565 __ j(zero, &false_result, Label::kNear);
566 // argument contains the correct return value already.
567 if (!tos_.is(argument)) {
568 __ Set(tos_, Immediate(1));
569 }
570 __ ret(1 * kPointerSize);
571 __ bind(&false_result);
572 __ Set(tos_, Immediate(0));
573 __ ret(1 * kPointerSize);
574 __ bind(&not_heap_number);
575 }
576
577 __ bind(&patch);
578 GenerateTypeTransition(masm);
579 }
580
581
582 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { 484 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
583 // We don't allow a GC during a store buffer overflow so there is no need to 485 // We don't allow a GC during a store buffer overflow so there is no need to
584 // store the registers in any particular way, but we do have to store and 486 // store the registers in any particular way, but we do have to store and
585 // restore them. 487 // restore them.
586 __ pushad(); 488 __ pushad();
587 if (save_doubles_ == kSaveFPRegs) { 489 if (save_doubles_ == kSaveFPRegs) {
588 CpuFeatureScope scope(masm, SSE2); 490 CpuFeatureScope scope(masm, SSE2);
589 __ sub(esp, Immediate(kDoubleSize * XMMRegister::kNumRegisters)); 491 __ sub(esp, Immediate(kDoubleSize * XMMRegister::kNumRegisters));
590 for (int i = 0; i < XMMRegister::kNumRegisters; i++) { 492 for (int i = 0; i < XMMRegister::kNumRegisters; i++) {
591 XMMRegister reg = XMMRegister::from_code(i); 493 XMMRegister reg = XMMRegister::from_code(i);
(...skipping 15 matching lines...) Expand all
607 XMMRegister reg = XMMRegister::from_code(i); 509 XMMRegister reg = XMMRegister::from_code(i);
608 __ movdbl(reg, Operand(esp, i * kDoubleSize)); 510 __ movdbl(reg, Operand(esp, i * kDoubleSize));
609 } 511 }
610 __ add(esp, Immediate(kDoubleSize * XMMRegister::kNumRegisters)); 512 __ add(esp, Immediate(kDoubleSize * XMMRegister::kNumRegisters));
611 } 513 }
612 __ popad(); 514 __ popad();
613 __ ret(0); 515 __ ret(0);
614 } 516 }
615 517
616 518
617 void ToBooleanStub::CheckOddball(MacroAssembler* masm,
618 Type type,
619 Heap::RootListIndex value,
620 bool result) {
621 const Register argument = eax;
622 if (types_.Contains(type)) {
623 // If we see an expected oddball, return its ToBoolean value tos_.
624 Label different_value;
625 __ CompareRoot(argument, value);
626 __ j(not_equal, &different_value, Label::kNear);
627 if (!result) {
628 // If we have to return zero, there is no way around clearing tos_.
629 __ Set(tos_, Immediate(0));
630 } else if (!tos_.is(argument)) {
631 // If we have to return non-zero, we can re-use the argument if it is the
632 // same register as the result, because we never see Smi-zero here.
633 __ Set(tos_, Immediate(1));
634 }
635 __ ret(1 * kPointerSize);
636 __ bind(&different_value);
637 }
638 }
639
640
641 void ToBooleanStub::GenerateTypeTransition(MacroAssembler* masm) {
642 __ pop(ecx); // Get return address, operand is now on top of stack.
643 __ push(Immediate(Smi::FromInt(tos_.code())));
644 __ push(Immediate(Smi::FromInt(types_.ToByte())));
645 __ push(ecx); // Push return address.
646 // Patch the caller to an appropriate specialized stub and return the
647 // operation result to the caller of the stub.
648 __ TailCallExternalReference(
649 ExternalReference(IC_Utility(IC::kToBoolean_Patch), masm->isolate()),
650 3,
651 1);
652 }
653
654
655 class FloatingPointHelper : public AllStatic { 519 class FloatingPointHelper : public AllStatic {
656 public: 520 public:
657 enum ArgLocation { 521 enum ArgLocation {
658 ARGS_ON_STACK, 522 ARGS_ON_STACK,
659 ARGS_IN_REGISTERS 523 ARGS_IN_REGISTERS
660 }; 524 };
661 525
662 // Code pattern for loading a floating point value. Input value must 526 // Code pattern for loading a floating point value. Input value must
663 // be either a smi or a heap number object (fp value). Requirements: 527 // be either a smi or a heap number object (fp value). Requirements:
664 // operand in register number. Returns operand as floating point number 528 // operand in register number. Returns operand as floating point number
(...skipping 7398 matching lines...) Expand 10 before | Expand all | Expand 10 after
8063 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); 7927 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
8064 } 7928 }
8065 } 7929 }
8066 7930
8067 7931
8068 #undef __ 7932 #undef __
8069 7933
8070 } } // namespace v8::internal 7934 } } // namespace v8::internal
8071 7935
8072 #endif // V8_TARGET_ARCH_IA32 7936 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/hydrogen-instructions.h ('k') | src/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698