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

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

Issue 39973003: Merge bleeding_edge. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: again Created 7 years, 1 month 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/code-stubs.cc ('k') | src/codegen.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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 if (FLAG_trace_hydrogen_stubs) { 139 if (FLAG_trace_hydrogen_stubs) {
140 const char* name = CodeStub::MajorName(stub()->MajorKey(), false); 140 const char* name = CodeStub::MajorName(stub()->MajorKey(), false);
141 PrintF("-----------------------------------------------------------\n"); 141 PrintF("-----------------------------------------------------------\n");
142 PrintF("Compiling stub %s using hydrogen\n", name); 142 PrintF("Compiling stub %s using hydrogen\n", name);
143 isolate()->GetHTracer()->TraceCompilation(&info_); 143 isolate()->GetHTracer()->TraceCompilation(&info_);
144 } 144 }
145 145
146 int param_count = descriptor_->register_param_count_; 146 int param_count = descriptor_->register_param_count_;
147 HEnvironment* start_environment = graph()->start_environment(); 147 HEnvironment* start_environment = graph()->start_environment();
148 HBasicBlock* next_block = CreateBasicBlock(start_environment); 148 HBasicBlock* next_block = CreateBasicBlock(start_environment);
149 current_block()->Goto(next_block); 149 Goto(next_block);
150 next_block->SetJoinId(BailoutId::StubEntry()); 150 next_block->SetJoinId(BailoutId::StubEntry());
151 set_current_block(next_block); 151 set_current_block(next_block);
152 152
153 HConstant* undefined_constant =
154 Add<HConstant>(isolate()->factory()->undefined_value());
155 graph()->set_undefined_constant(undefined_constant);
156
157 for (int i = 0; i < param_count; ++i) { 153 for (int i = 0; i < param_count; ++i) {
158 HParameter* param = 154 HParameter* param =
159 Add<HParameter>(i, HParameter::REGISTER_PARAMETER); 155 Add<HParameter>(i, HParameter::REGISTER_PARAMETER);
160 start_environment->Bind(i, param); 156 start_environment->Bind(i, param);
161 parameters_[i] = param; 157 parameters_[i] = param;
162 } 158 }
163 159
164 HInstruction* stack_parameter_count; 160 HInstruction* stack_parameter_count;
165 if (descriptor_->stack_parameter_count_ != NULL) { 161 if (descriptor_->stack_parameter_count_.is_valid()) {
166 ASSERT(descriptor_->environment_length() == (param_count + 1)); 162 ASSERT(descriptor_->environment_length() == (param_count + 1));
167 stack_parameter_count = New<HParameter>(param_count, 163 stack_parameter_count = New<HParameter>(param_count,
168 HParameter::REGISTER_PARAMETER, 164 HParameter::REGISTER_PARAMETER,
169 Representation::Integer32()); 165 Representation::Integer32());
170 stack_parameter_count->set_type(HType::Smi()); 166 stack_parameter_count->set_type(HType::Smi());
171 // It's essential to bind this value to the environment in case of deopt. 167 // It's essential to bind this value to the environment in case of deopt.
172 AddInstruction(stack_parameter_count); 168 AddInstruction(stack_parameter_count);
173 start_environment->Bind(param_count, stack_parameter_count); 169 start_environment->Bind(param_count, stack_parameter_count);
174 arguments_length_ = stack_parameter_count; 170 arguments_length_ = stack_parameter_count;
175 } else { 171 } else {
176 ASSERT(descriptor_->environment_length() == param_count); 172 ASSERT(descriptor_->environment_length() == param_count);
177 stack_parameter_count = graph()->GetConstantMinus1(); 173 stack_parameter_count = graph()->GetConstantMinus1();
178 arguments_length_ = graph()->GetConstant0(); 174 arguments_length_ = graph()->GetConstant0();
179 } 175 }
180 176
181 context_ = New<HContext>(); 177 context_ = Add<HContext>();
182 AddInstruction(context_);
183 start_environment->BindContext(context_); 178 start_environment->BindContext(context_);
184 179
185 Add<HSimulate>(BailoutId::StubEntry()); 180 Add<HSimulate>(BailoutId::StubEntry());
186 181
187 NoObservableSideEffectsScope no_effects(this); 182 NoObservableSideEffectsScope no_effects(this);
188 183
189 HValue* return_value = BuildCodeStub(); 184 HValue* return_value = BuildCodeStub();
190 185
191 // We might have extra expressions to pop from the stack in addition to the 186 // We might have extra expressions to pop from the stack in addition to the
192 // arguments above. 187 // arguments above.
193 HInstruction* stack_pop_count = stack_parameter_count; 188 HInstruction* stack_pop_count = stack_parameter_count;
194 if (descriptor_->function_mode_ == JS_FUNCTION_STUB_MODE) { 189 if (descriptor_->function_mode_ == JS_FUNCTION_STUB_MODE) {
195 if (!stack_parameter_count->IsConstant() && 190 if (!stack_parameter_count->IsConstant() &&
196 descriptor_->hint_stack_parameter_count_ < 0) { 191 descriptor_->hint_stack_parameter_count_ < 0) {
197 HInstruction* amount = graph()->GetConstant1(); 192 HInstruction* amount = graph()->GetConstant1();
198 stack_pop_count = Add<HAdd>(stack_parameter_count, amount); 193 stack_pop_count = Add<HAdd>(stack_parameter_count, amount);
199 stack_pop_count->ChangeRepresentation(Representation::Integer32()); 194 stack_pop_count->ChangeRepresentation(Representation::Integer32());
200 stack_pop_count->ClearFlag(HValue::kCanOverflow); 195 stack_pop_count->ClearFlag(HValue::kCanOverflow);
201 } else { 196 } else {
202 int count = descriptor_->hint_stack_parameter_count_; 197 int count = descriptor_->hint_stack_parameter_count_;
203 stack_pop_count = Add<HConstant>(count); 198 stack_pop_count = Add<HConstant>(count);
204 } 199 }
205 } 200 }
206 201
207 if (current_block() != NULL) { 202 if (current_block() != NULL) {
208 HReturn* hreturn_instruction = New<HReturn>(return_value, 203 HReturn* hreturn_instruction = New<HReturn>(return_value,
209 stack_pop_count); 204 stack_pop_count);
210 current_block()->Finish(hreturn_instruction); 205 FinishCurrentBlock(hreturn_instruction);
211 set_current_block(NULL);
212 } 206 }
213 return true; 207 return true;
214 } 208 }
215 209
216 210
217 template <class Stub> 211 template <class Stub>
218 class CodeStubGraphBuilder: public CodeStubGraphBuilderBase { 212 class CodeStubGraphBuilder: public CodeStubGraphBuilderBase {
219 public: 213 public:
220 explicit CodeStubGraphBuilder(Isolate* isolate, Stub* stub) 214 explicit CodeStubGraphBuilder(Isolate* isolate, Stub* stub)
221 : CodeStubGraphBuilderBase(isolate, stub) {} 215 : CodeStubGraphBuilderBase(isolate, stub) {}
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 CodeStubInterfaceDescriptor* descriptor = 285 CodeStubInterfaceDescriptor* descriptor =
292 isolate->code_stub_interface_descriptor(major_key); 286 isolate->code_stub_interface_descriptor(major_key);
293 if (descriptor->register_param_count_ < 0) { 287 if (descriptor->register_param_count_ < 0) {
294 stub->InitializeInterfaceDescriptor(isolate, descriptor); 288 stub->InitializeInterfaceDescriptor(isolate, descriptor);
295 } 289 }
296 290
297 // If we are uninitialized we can use a light-weight stub to enter 291 // If we are uninitialized we can use a light-weight stub to enter
298 // the runtime that is significantly faster than using the standard 292 // the runtime that is significantly faster than using the standard
299 // stub-failure deopt mechanism. 293 // stub-failure deopt mechanism.
300 if (stub->IsUninitialized() && descriptor->has_miss_handler()) { 294 if (stub->IsUninitialized() && descriptor->has_miss_handler()) {
301 ASSERT(descriptor->stack_parameter_count_ == NULL); 295 ASSERT(!descriptor->stack_parameter_count_.is_valid());
302 return stub->GenerateLightweightMissCode(isolate); 296 return stub->GenerateLightweightMissCode(isolate);
303 } 297 }
304 ElapsedTimer timer; 298 ElapsedTimer timer;
305 if (FLAG_profile_hydrogen_code_stub_compilation) { 299 if (FLAG_profile_hydrogen_code_stub_compilation) {
306 timer.Start(); 300 timer.Start();
307 } 301 }
308 CodeStubGraphBuilder<Stub> builder(isolate, stub); 302 CodeStubGraphBuilder<Stub> builder(isolate, stub);
309 LChunk* chunk = OptimizeGraph(builder.CreateGraph()); 303 LChunk* chunk = OptimizeGraph(builder.CreateGraph());
310 Handle<Code> code = chunk->Codegen(); 304 Handle<Code> code = chunk->Codegen();
311 if (FLAG_profile_hydrogen_code_stub_compilation) { 305 if (FLAG_profile_hydrogen_code_stub_compilation) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 338
345 Handle<Code> ToNumberStub::GenerateCode(Isolate* isolate) { 339 Handle<Code> ToNumberStub::GenerateCode(Isolate* isolate) {
346 return DoGenerateCode(isolate, this); 340 return DoGenerateCode(isolate, this);
347 } 341 }
348 342
349 343
350 template <> 344 template <>
351 HValue* CodeStubGraphBuilder<NumberToStringStub>::BuildCodeStub() { 345 HValue* CodeStubGraphBuilder<NumberToStringStub>::BuildCodeStub() {
352 info()->MarkAsSavesCallerDoubles(); 346 info()->MarkAsSavesCallerDoubles();
353 HValue* number = GetParameter(NumberToStringStub::kNumber); 347 HValue* number = GetParameter(NumberToStringStub::kNumber);
354 return BuildNumberToString(number); 348 return BuildNumberToString(number, handle(Type::Number(), isolate()));
355 } 349 }
356 350
357 351
358 Handle<Code> NumberToStringStub::GenerateCode(Isolate* isolate) { 352 Handle<Code> NumberToStringStub::GenerateCode(Isolate* isolate) {
359 return DoGenerateCode(isolate, this); 353 return DoGenerateCode(isolate, this);
360 } 354 }
361 355
362 356
363 template <> 357 template <>
364 HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() { 358 HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 423
430 Handle<Code> FastCloneShallowArrayStub::GenerateCode(Isolate* isolate) { 424 Handle<Code> FastCloneShallowArrayStub::GenerateCode(Isolate* isolate) {
431 return DoGenerateCode(isolate, this); 425 return DoGenerateCode(isolate, this);
432 } 426 }
433 427
434 428
435 template <> 429 template <>
436 HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() { 430 HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() {
437 HValue* undefined = graph()->GetConstantUndefined(); 431 HValue* undefined = graph()->GetConstantUndefined();
438 432
439 HInstruction* boilerplate = Add<HLoadKeyed>(GetParameter(0), 433 HInstruction* allocation_site = Add<HLoadKeyed>(GetParameter(0),
440 GetParameter(1), 434 GetParameter(1),
441 static_cast<HValue*>(NULL), 435 static_cast<HValue*>(NULL),
442 FAST_ELEMENTS); 436 FAST_ELEMENTS);
443 437
444 IfBuilder checker(this); 438 IfBuilder checker(this);
445 checker.IfNot<HCompareObjectEqAndBranch, HValue*>(boilerplate, 439 checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site,
446 undefined); 440 undefined);
447 checker.And(); 441 checker.And();
448 442
443 HObjectAccess access = HObjectAccess::ForAllocationSiteTransitionInfo();
444 HInstruction* boilerplate = Add<HLoadNamedField>(allocation_site, access);
445
449 int size = JSObject::kHeaderSize + casted_stub()->length() * kPointerSize; 446 int size = JSObject::kHeaderSize + casted_stub()->length() * kPointerSize;
447 int object_size = size;
448 if (FLAG_allocation_site_pretenuring) {
449 size += AllocationMemento::kSize;
450 }
451
450 HValue* boilerplate_map = Add<HLoadNamedField>( 452 HValue* boilerplate_map = Add<HLoadNamedField>(
451 boilerplate, HObjectAccess::ForMap()); 453 boilerplate, HObjectAccess::ForMap());
452 HValue* boilerplate_size = Add<HLoadNamedField>( 454 HValue* boilerplate_size = Add<HLoadNamedField>(
453 boilerplate_map, HObjectAccess::ForMapInstanceSize()); 455 boilerplate_map, HObjectAccess::ForMapInstanceSize());
454 HValue* size_in_words = Add<HConstant>(size >> kPointerSizeLog2); 456 HValue* size_in_words = Add<HConstant>(object_size >> kPointerSizeLog2);
455 checker.If<HCompareNumericAndBranch>(boilerplate_size, 457 checker.If<HCompareNumericAndBranch>(boilerplate_size,
456 size_in_words, Token::EQ); 458 size_in_words, Token::EQ);
457 checker.Then(); 459 checker.Then();
458 460
459 HValue* size_in_bytes = Add<HConstant>(size); 461 HValue* size_in_bytes = Add<HConstant>(size);
460 462
461 HInstruction* object = Add<HAllocate>(size_in_bytes, HType::JSObject(), 463 HInstruction* object = Add<HAllocate>(size_in_bytes, HType::JSObject(),
462 isolate()->heap()->GetPretenureMode(), JS_OBJECT_TYPE); 464 isolate()->heap()->GetPretenureMode(), JS_OBJECT_TYPE);
463 465
464 for (int i = 0; i < size; i += kPointerSize) { 466 for (int i = 0; i < object_size; i += kPointerSize) {
465 HObjectAccess access = HObjectAccess::ForJSObjectOffset(i); 467 HObjectAccess access = HObjectAccess::ForJSObjectOffset(i);
466 Add<HStoreNamedField>(object, access, 468 Add<HStoreNamedField>(object, access,
467 Add<HLoadNamedField>(boilerplate, access)); 469 Add<HLoadNamedField>(boilerplate, access));
468 } 470 }
469 471
472 ASSERT(FLAG_allocation_site_pretenuring || (size == object_size));
473 if (FLAG_allocation_site_pretenuring) {
474 BuildCreateAllocationMemento(object, object_size, allocation_site);
475 }
476
470 environment()->Push(object); 477 environment()->Push(object);
471 checker.ElseDeopt("Uninitialized boilerplate in fast clone"); 478 checker.ElseDeopt("Uninitialized boilerplate in fast clone");
472 checker.End(); 479 checker.End();
473 480
474 return environment()->Pop(); 481 return environment()->Pop();
475 } 482 }
476 483
477 484
478 Handle<Code> FastCloneShallowObjectStub::GenerateCode(Isolate* isolate) { 485 Handle<Code> FastCloneShallowObjectStub::GenerateCode(Isolate* isolate) {
479 return DoGenerateCode(isolate, this); 486 return DoGenerateCode(isolate, this);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 return DoGenerateCode(isolate, this); 559 return DoGenerateCode(isolate, this);
553 } 560 }
554 561
555 562
556 template<> 563 template<>
557 HValue* CodeStubGraphBuilder<LoadFieldStub>::BuildCodeStub() { 564 HValue* CodeStubGraphBuilder<LoadFieldStub>::BuildCodeStub() {
558 Representation rep = casted_stub()->representation(); 565 Representation rep = casted_stub()->representation();
559 HObjectAccess access = casted_stub()->is_inobject() ? 566 HObjectAccess access = casted_stub()->is_inobject() ?
560 HObjectAccess::ForJSObjectOffset(casted_stub()->offset(), rep) : 567 HObjectAccess::ForJSObjectOffset(casted_stub()->offset(), rep) :
561 HObjectAccess::ForBackingStoreOffset(casted_stub()->offset(), rep); 568 HObjectAccess::ForBackingStoreOffset(casted_stub()->offset(), rep);
562 return AddInstruction(BuildLoadNamedField(GetParameter(0), access)); 569 return AddLoadNamedField(GetParameter(0), access);
563 } 570 }
564 571
565 572
566 Handle<Code> LoadFieldStub::GenerateCode(Isolate* isolate) { 573 Handle<Code> LoadFieldStub::GenerateCode(Isolate* isolate) {
567 return DoGenerateCode(isolate, this); 574 return DoGenerateCode(isolate, this);
568 } 575 }
569 576
570 577
571 template<> 578 template<>
572 HValue* CodeStubGraphBuilder<KeyedLoadFieldStub>::BuildCodeStub() { 579 HValue* CodeStubGraphBuilder<KeyedLoadFieldStub>::BuildCodeStub() {
573 Representation rep = casted_stub()->representation(); 580 Representation rep = casted_stub()->representation();
574 HObjectAccess access = casted_stub()->is_inobject() ? 581 HObjectAccess access = casted_stub()->is_inobject() ?
575 HObjectAccess::ForJSObjectOffset(casted_stub()->offset(), rep) : 582 HObjectAccess::ForJSObjectOffset(casted_stub()->offset(), rep) :
576 HObjectAccess::ForBackingStoreOffset(casted_stub()->offset(), rep); 583 HObjectAccess::ForBackingStoreOffset(casted_stub()->offset(), rep);
577 return AddInstruction(BuildLoadNamedField(GetParameter(0), access)); 584 return AddLoadNamedField(GetParameter(0), access);
578 } 585 }
579 586
580 587
581 Handle<Code> KeyedLoadFieldStub::GenerateCode(Isolate* isolate) { 588 Handle<Code> KeyedLoadFieldStub::GenerateCode(Isolate* isolate) {
582 return DoGenerateCode(isolate, this); 589 return DoGenerateCode(isolate, this);
583 } 590 }
584 591
585 592
586 template <> 593 template <>
587 HValue* CodeStubGraphBuilder<KeyedStoreFastElementStub>::BuildCodeStub() { 594 HValue* CodeStubGraphBuilder<KeyedStoreFastElementStub>::BuildCodeStub() {
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 } 680 }
674 681
675 682
676 HValue* CodeStubGraphBuilderBase::BuildArraySingleArgumentConstructor( 683 HValue* CodeStubGraphBuilderBase::BuildArraySingleArgumentConstructor(
677 JSArrayBuilder* array_builder) { 684 JSArrayBuilder* array_builder) {
678 // Smi check and range check on the input arg. 685 // Smi check and range check on the input arg.
679 HValue* constant_one = graph()->GetConstant1(); 686 HValue* constant_one = graph()->GetConstant1();
680 HValue* constant_zero = graph()->GetConstant0(); 687 HValue* constant_zero = graph()->GetConstant0();
681 688
682 HInstruction* elements = Add<HArgumentsElements>(false); 689 HInstruction* elements = Add<HArgumentsElements>(false);
683 HInstruction* argument = AddInstruction( 690 HInstruction* argument = Add<HAccessArgumentsAt>(
684 new(zone()) HAccessArgumentsAt(elements, constant_one, constant_zero)); 691 elements, constant_one, constant_zero);
685 692
686 HConstant* max_alloc_length = 693 HConstant* max_alloc_length =
687 Add<HConstant>(JSObject::kInitialMaxFastElementArray); 694 Add<HConstant>(JSObject::kInitialMaxFastElementArray);
688 const int initial_capacity = JSArray::kPreallocatedArrayElements; 695 const int initial_capacity = JSArray::kPreallocatedArrayElements;
689 HConstant* initial_capacity_node = New<HConstant>(initial_capacity); 696 HConstant* initial_capacity_node = Add<HConstant>(initial_capacity);
690 AddInstruction(initial_capacity_node);
691 697
692 HInstruction* checked_arg = Add<HBoundsCheck>(argument, max_alloc_length); 698 HInstruction* checked_arg = Add<HBoundsCheck>(argument, max_alloc_length);
693 IfBuilder if_builder(this); 699 IfBuilder if_builder(this);
694 if_builder.If<HCompareNumericAndBranch>(checked_arg, constant_zero, 700 if_builder.If<HCompareNumericAndBranch>(checked_arg, constant_zero,
695 Token::EQ); 701 Token::EQ);
696 if_builder.Then(); 702 if_builder.Then();
697 Push(initial_capacity_node); // capacity 703 Push(initial_capacity_node); // capacity
698 Push(constant_zero); // length 704 Push(constant_zero); // length
699 if_builder.Else(); 705 if_builder.Else();
700 Push(checked_arg); // capacity 706 Push(checked_arg); // capacity
(...skipping 22 matching lines...) Expand all
723 HValue* elements = array_builder->GetElementsLocation(); 729 HValue* elements = array_builder->GetElementsLocation();
724 ASSERT(elements != NULL); 730 ASSERT(elements != NULL);
725 731
726 // Now populate the elements correctly. 732 // Now populate the elements correctly.
727 LoopBuilder builder(this, 733 LoopBuilder builder(this,
728 context(), 734 context(),
729 LoopBuilder::kPostIncrement); 735 LoopBuilder::kPostIncrement);
730 HValue* start = graph()->GetConstant0(); 736 HValue* start = graph()->GetConstant0();
731 HValue* key = builder.BeginBody(start, length, Token::LT); 737 HValue* key = builder.BeginBody(start, length, Token::LT);
732 HInstruction* argument_elements = Add<HArgumentsElements>(false); 738 HInstruction* argument_elements = Add<HArgumentsElements>(false);
733 HInstruction* argument = AddInstruction(new(zone()) HAccessArgumentsAt( 739 HInstruction* argument = Add<HAccessArgumentsAt>(
734 argument_elements, length, key)); 740 argument_elements, length, key);
735 741
736 Add<HStoreKeyed>(elements, key, argument, kind); 742 Add<HStoreKeyed>(elements, key, argument, kind);
737 builder.EndBody(); 743 builder.EndBody();
738 return new_object; 744 return new_object;
739 } 745 }
740 746
741 747
742 template <> 748 template <>
743 HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() { 749 HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() {
744 ElementsKind kind = casted_stub()->elements_kind(); 750 ElementsKind kind = casted_stub()->elements_kind();
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
825 } 831 }
826 832
827 833
828 template <> 834 template <>
829 HValue* CodeStubGraphBuilder<CompareNilICStub>::BuildCodeInitializedStub() { 835 HValue* CodeStubGraphBuilder<CompareNilICStub>::BuildCodeInitializedStub() {
830 Isolate* isolate = graph()->isolate(); 836 Isolate* isolate = graph()->isolate();
831 CompareNilICStub* stub = casted_stub(); 837 CompareNilICStub* stub = casted_stub();
832 HIfContinuation continuation; 838 HIfContinuation continuation;
833 Handle<Map> sentinel_map(isolate->heap()->meta_map()); 839 Handle<Map> sentinel_map(isolate->heap()->meta_map());
834 Handle<Type> type = stub->GetType(isolate, sentinel_map); 840 Handle<Type> type = stub->GetType(isolate, sentinel_map);
835 BuildCompareNil(GetParameter(0), type, RelocInfo::kNoPosition, &continuation); 841 BuildCompareNil(GetParameter(0), type, &continuation);
836 IfBuilder if_nil(this, &continuation); 842 IfBuilder if_nil(this, &continuation);
837 if_nil.Then(); 843 if_nil.Then();
838 if (continuation.IsFalseReachable()) { 844 if (continuation.IsFalseReachable()) {
839 if_nil.Else(); 845 if_nil.Else();
840 if_nil.Return(graph()->GetConstant0()); 846 if_nil.Return(graph()->GetConstant0());
841 } 847 }
842 if_nil.End(); 848 if_nil.End();
843 return continuation.IsTrueReachable() 849 return continuation.IsTrueReachable()
844 ? graph()->GetConstant1() 850 ? graph()->GetConstant1()
845 : graph()->GetConstantUndefined(); 851 : graph()->GetConstantUndefined();
(...skipping 15 matching lines...) Expand all
861 Handle<Type> right_type = stub->GetRightType(isolate()); 867 Handle<Type> right_type = stub->GetRightType(isolate());
862 Handle<Type> result_type = stub->GetResultType(isolate()); 868 Handle<Type> result_type = stub->GetResultType(isolate());
863 869
864 ASSERT(!left_type->Is(Type::None()) && !right_type->Is(Type::None()) && 870 ASSERT(!left_type->Is(Type::None()) && !right_type->Is(Type::None()) &&
865 (stub->HasSideEffects(isolate()) || !result_type->Is(Type::None()))); 871 (stub->HasSideEffects(isolate()) || !result_type->Is(Type::None())));
866 872
867 HValue* result = NULL; 873 HValue* result = NULL;
868 if (stub->operation() == Token::ADD && 874 if (stub->operation() == Token::ADD &&
869 (left_type->Maybe(Type::String()) || right_type->Maybe(Type::String())) && 875 (left_type->Maybe(Type::String()) || right_type->Maybe(Type::String())) &&
870 !left_type->Is(Type::String()) && !right_type->Is(Type::String())) { 876 !left_type->Is(Type::String()) && !right_type->Is(Type::String())) {
871 // For the generic add stub a fast case for String add is performance 877 // For the generic add stub a fast case for string addition is performance
872 // critical. 878 // critical.
873 if (left_type->Maybe(Type::String())) { 879 if (left_type->Maybe(Type::String())) {
874 IfBuilder left_string(this); 880 IfBuilder if_leftisstring(this);
875 left_string.IfNot<HIsSmiAndBranch>(left); 881 if_leftisstring.If<HIsStringAndBranch>(left);
876 left_string.AndIf<HIsStringAndBranch>(left); 882 if_leftisstring.Then();
877 left_string.Then(); 883 {
878 Push(Add<HStringAdd>(left, right, STRING_ADD_CHECK_RIGHT)); 884 Push(AddInstruction(BuildBinaryOperation(
879 left_string.Else(); 885 stub->operation(), left, right,
880 Push(AddInstruction(BuildBinaryOperation(stub->operation(), 886 handle(Type::String(), isolate()), right_type,
881 left, right, left_type, right_type, result_type, 887 result_type, stub->fixed_right_arg(), true)));
882 stub->fixed_right_arg(), true))); 888 }
883 left_string.End(); 889 if_leftisstring.Else();
890 {
891 Push(AddInstruction(BuildBinaryOperation(
892 stub->operation(), left, right,
893 left_type, right_type, result_type,
894 stub->fixed_right_arg(), true)));
895 }
896 if_leftisstring.End();
884 result = Pop(); 897 result = Pop();
885 } else { 898 } else {
886 IfBuilder right_string(this); 899 IfBuilder if_rightisstring(this);
887 right_string.IfNot<HIsSmiAndBranch>(right); 900 if_rightisstring.If<HIsStringAndBranch>(right);
888 right_string.AndIf<HIsStringAndBranch>(right); 901 if_rightisstring.Then();
889 right_string.Then(); 902 {
890 Push(Add<HStringAdd>(left, right, STRING_ADD_CHECK_LEFT)); 903 Push(AddInstruction(BuildBinaryOperation(
891 right_string.Else(); 904 stub->operation(), left, right,
892 Push(AddInstruction(BuildBinaryOperation(stub->operation(), 905 left_type, handle(Type::String(), isolate()),
893 left, right, left_type, right_type, result_type, 906 result_type, stub->fixed_right_arg(), true)));
894 stub->fixed_right_arg(), true))); 907 }
895 right_string.End(); 908 if_rightisstring.Else();
909 {
910 Push(AddInstruction(BuildBinaryOperation(
911 stub->operation(), left, right,
912 left_type, right_type, result_type,
913 stub->fixed_right_arg(), true)));
914 }
915 if_rightisstring.End();
896 result = Pop(); 916 result = Pop();
897 } 917 }
898 } else { 918 } else {
899 result = AddInstruction(BuildBinaryOperation(stub->operation(), 919 result = AddInstruction(BuildBinaryOperation(
900 left, right, left_type, right_type, result_type, 920 stub->operation(), left, right,
901 stub->fixed_right_arg(), true)); 921 left_type, right_type, result_type,
922 stub->fixed_right_arg(), true));
902 } 923 }
903 924
904 // If we encounter a generic argument, the number conversion is 925 // If we encounter a generic argument, the number conversion is
905 // observable, thus we cannot afford to bail out after the fact. 926 // observable, thus we cannot afford to bail out after the fact.
906 if (!stub->HasSideEffects(isolate())) { 927 if (!stub->HasSideEffects(isolate())) {
907 if (result_type->Is(Type::Smi())) { 928 if (result_type->Is(Type::Smi())) {
908 if (stub->operation() == Token::SHR) { 929 if (stub->operation() == Token::SHR) {
909 // TODO(olivf) Replace this by a SmiTagU Instruction. 930 // TODO(olivf) Replace this by a SmiTagU Instruction.
910 // 0x40000000: this number would convert to negative when interpreting 931 // 0x40000000: this number would convert to negative when interpreting
911 // the register as signed value; 932 // the register as signed value;
912 IfBuilder if_of(this); 933 IfBuilder if_of(this);
913 if_of.IfNot<HCompareNumericAndBranch>(result, 934 if_of.IfNot<HCompareNumericAndBranch>(result,
914 Add<HConstant>(static_cast<int>(SmiValuesAre32Bits() 935 Add<HConstant>(static_cast<int>(SmiValuesAre32Bits()
915 ? 0x80000000 : 0x40000000)), Token::EQ_STRICT); 936 ? 0x80000000 : 0x40000000)), Token::EQ_STRICT);
916 if_of.Then(); 937 if_of.Then();
917 if_of.ElseDeopt("UInt->Smi oveflow"); 938 if_of.ElseDeopt("UInt->Smi oveflow");
918 if_of.End(); 939 if_of.End();
919 } 940 }
920 } 941 }
921 result = EnforceNumberType(result, result_type); 942 result = EnforceNumberType(result, result_type);
922 } 943 }
923 944
924 // Reuse the double box if we are allowed to (i.e. chained binops). 945 // Reuse the double box of one of the operands if we are allowed to (i.e.
946 // chained binops).
925 if (stub->CanReuseDoubleBox()) { 947 if (stub->CanReuseDoubleBox()) {
926 HValue* reuse = (stub->mode() == OVERWRITE_LEFT) ? left : right; 948 HValue* operand = (stub->mode() == OVERWRITE_LEFT) ? left : right;
927 IfBuilder if_heap_number(this); 949 IfBuilder if_heap_number(this);
928 if_heap_number.IfNot<HIsSmiAndBranch>(reuse); 950 if_heap_number.IfNot<HIsSmiAndBranch>(operand);
929 if_heap_number.Then(); 951 if_heap_number.Then();
930 HValue* res_val = Add<HForceRepresentation>(result, 952 Add<HStoreNamedField>(operand, HObjectAccess::ForHeapNumberValue(), result);
931 Representation::Double()); 953 Push(operand);
932 HObjectAccess access = HObjectAccess::ForHeapNumberValue();
933 Add<HStoreNamedField>(reuse, access, res_val);
934 Push(reuse);
935 if_heap_number.Else(); 954 if_heap_number.Else();
936 Push(result); 955 Push(result);
937 if_heap_number.End(); 956 if_heap_number.End();
938 result = Pop(); 957 result = Pop();
939 } 958 }
940 959
941 return result; 960 return result;
942 } 961 }
943 962
944 963
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
1140 restore_check.If<HCompareNumericAndBranch>(key, second_entry_index, 1159 restore_check.If<HCompareNumericAndBranch>(key, second_entry_index,
1141 Token::EQ); 1160 Token::EQ);
1142 restore_check.Then(); 1161 restore_check.Then();
1143 { 1162 {
1144 // Store the unoptimized code 1163 // Store the unoptimized code
1145 BuildInstallCode(js_function, shared_info); 1164 BuildInstallCode(js_function, shared_info);
1146 loop_builder.Break(); 1165 loop_builder.Break();
1147 } 1166 }
1148 restore_check.Else(); 1167 restore_check.Else();
1149 { 1168 {
1150 HValue* keyed_minus = AddInstruction(HSub::New(zone(), context(), key, 1169 HValue* keyed_minus = AddUncasted<HSub>(
1151 shared_function_entry_length)); 1170 key, shared_function_entry_length);
1152 HInstruction* keyed_lookup = Add<HLoadKeyed>(optimized_map, 1171 HInstruction* keyed_lookup = Add<HLoadKeyed>(optimized_map,
1153 keyed_minus, static_cast<HValue*>(NULL), FAST_ELEMENTS); 1172 keyed_minus, static_cast<HValue*>(NULL), FAST_ELEMENTS);
1154 IfBuilder done_check(this); 1173 IfBuilder done_check(this);
1155 done_check.If<HCompareObjectEqAndBranch>(native_context, 1174 done_check.If<HCompareObjectEqAndBranch>(native_context,
1156 keyed_lookup); 1175 keyed_lookup);
1157 done_check.Then(); 1176 done_check.Then();
1158 { 1177 {
1159 // Hit: fetch the optimized code. 1178 // Hit: fetch the optimized code.
1160 HValue* keyed_plus = AddInstruction(HAdd::New(zone(), context(), 1179 HValue* keyed_plus = AddUncasted<HAdd>(
1161 keyed_minus, graph()->GetConstant1())); 1180 keyed_minus, graph()->GetConstant1());
1162 HValue* code_object = Add<HLoadKeyed>(optimized_map, 1181 HValue* code_object = Add<HLoadKeyed>(optimized_map,
1163 keyed_plus, static_cast<HValue*>(NULL), FAST_ELEMENTS); 1182 keyed_plus, static_cast<HValue*>(NULL), FAST_ELEMENTS);
1164 BuildInstallOptimizedCode(js_function, native_context, code_object); 1183 BuildInstallOptimizedCode(js_function, native_context, code_object);
1165 1184
1166 // Fall out of the loop 1185 // Fall out of the loop
1167 loop_builder.Break(); 1186 loop_builder.Break();
1168 } 1187 }
1169 done_check.Else(); 1188 done_check.Else();
1170 done_check.End(); 1189 done_check.End();
1171 } 1190 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 return js_function; 1252 return js_function;
1234 } 1253 }
1235 1254
1236 1255
1237 Handle<Code> FastNewClosureStub::GenerateCode(Isolate* isolate) { 1256 Handle<Code> FastNewClosureStub::GenerateCode(Isolate* isolate) {
1238 return DoGenerateCode(isolate, this); 1257 return DoGenerateCode(isolate, this);
1239 } 1258 }
1240 1259
1241 1260
1242 } } // namespace v8::internal 1261 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/code-stubs.cc ('k') | src/codegen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698