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

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

Issue 21356002: Improve instruction creating/adding shorthand in HGraphBuilder (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 4 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 | « no previous file | src/hydrogen.h » ('j') | src/hydrogen.h » ('J')
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 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 // Update the static counter each time a new code stub is generated. 129 // Update the static counter each time a new code stub is generated.
130 isolate()->counters()->code_stubs()->Increment(); 130 isolate()->counters()->code_stubs()->Increment();
131 131
132 if (FLAG_trace_hydrogen_stubs) { 132 if (FLAG_trace_hydrogen_stubs) {
133 const char* name = CodeStub::MajorName(stub()->MajorKey(), false); 133 const char* name = CodeStub::MajorName(stub()->MajorKey(), false);
134 PrintF("-----------------------------------------------------------\n"); 134 PrintF("-----------------------------------------------------------\n");
135 PrintF("Compiling stub %s using hydrogen\n", name); 135 PrintF("Compiling stub %s using hydrogen\n", name);
136 isolate()->GetHTracer()->TraceCompilation(&info_); 136 isolate()->GetHTracer()->TraceCompilation(&info_);
137 } 137 }
138 138
139 Zone* zone = this->zone();
140 int param_count = descriptor_->register_param_count_; 139 int param_count = descriptor_->register_param_count_;
141 HEnvironment* start_environment = graph()->start_environment(); 140 HEnvironment* start_environment = graph()->start_environment();
142 HBasicBlock* next_block = CreateBasicBlock(start_environment); 141 HBasicBlock* next_block = CreateBasicBlock(start_environment);
143 current_block()->Goto(next_block); 142 current_block()->Goto(next_block);
144 next_block->SetJoinId(BailoutId::StubEntry()); 143 next_block->SetJoinId(BailoutId::StubEntry());
145 set_current_block(next_block); 144 set_current_block(next_block);
146 145
147 HConstant* undefined_constant = new(zone) HConstant( 146 HConstant* undefined_constant =
148 isolate()->factory()->undefined_value()); 147 AddAndCast<HConstant>(isolate()->factory()->undefined_value());
149 AddInstruction(undefined_constant);
150 graph()->set_undefined_constant(undefined_constant); 148 graph()->set_undefined_constant(undefined_constant);
151 149
152 for (int i = 0; i < param_count; ++i) { 150 for (int i = 0; i < param_count; ++i) {
153 HParameter* param = 151 HParameter* param =
154 new(zone) HParameter(i, HParameter::REGISTER_PARAMETER); 152 AddAndCast<HParameter>(i, HParameter::REGISTER_PARAMETER);
155 AddInstruction(param);
156 start_environment->Bind(i, param); 153 start_environment->Bind(i, param);
157 parameters_[i] = param; 154 parameters_[i] = param;
158 } 155 }
159 156
160 HInstruction* stack_parameter_count; 157 HInstruction* stack_parameter_count;
161 if (descriptor_->stack_parameter_count_ != NULL) { 158 if (descriptor_->stack_parameter_count_ != NULL) {
162 ASSERT(descriptor_->environment_length() == (param_count + 1)); 159 ASSERT(descriptor_->environment_length() == (param_count + 1));
163 stack_parameter_count = new(zone) HParameter(param_count, 160 stack_parameter_count = New<HParameter>(param_count,
164 HParameter::REGISTER_PARAMETER, 161 HParameter::REGISTER_PARAMETER,
165 Representation::Integer32()); 162 Representation::Integer32());
166 stack_parameter_count->set_type(HType::Smi()); 163 stack_parameter_count->set_type(HType::Smi());
167 // It's essential to bind this value to the environment in case of deopt. 164 // It's essential to bind this value to the environment in case of deopt.
168 AddInstruction(stack_parameter_count); 165 AddInstruction(stack_parameter_count);
169 start_environment->Bind(param_count, stack_parameter_count); 166 start_environment->Bind(param_count, stack_parameter_count);
170 arguments_length_ = stack_parameter_count; 167 arguments_length_ = stack_parameter_count;
171 } else { 168 } else {
172 ASSERT(descriptor_->environment_length() == param_count); 169 ASSERT(descriptor_->environment_length() == param_count);
173 stack_parameter_count = graph()->GetConstantMinus1(); 170 stack_parameter_count = graph()->GetConstantMinus1();
174 arguments_length_ = graph()->GetConstant0(); 171 arguments_length_ = graph()->GetConstant0();
175 } 172 }
176 173
177 context_ = new(zone) HContext(); 174 context_ = NewAndCast<HContext>();
178 AddInstruction(context_); 175 AddInstruction(context_);
179 start_environment->BindContext(context_); 176 start_environment->BindContext(context_);
180 177
181 Add<HSimulate>(BailoutId::StubEntry()); 178 Add<HSimulate>(BailoutId::StubEntry());
182 179
183 NoObservableSideEffectsScope no_effects(this); 180 NoObservableSideEffectsScope no_effects(this);
184 181
185 HValue* return_value = BuildCodeStub(); 182 HValue* return_value = BuildCodeStub();
186 183
187 // We might have extra expressions to pop from the stack in addition to the 184 // We might have extra expressions to pop from the stack in addition to the
188 // arguments above. 185 // arguments above.
189 HInstruction* stack_pop_count = stack_parameter_count; 186 HInstruction* stack_pop_count = stack_parameter_count;
190 if (descriptor_->function_mode_ == JS_FUNCTION_STUB_MODE) { 187 if (descriptor_->function_mode_ == JS_FUNCTION_STUB_MODE) {
191 if (!stack_parameter_count->IsConstant() && 188 if (!stack_parameter_count->IsConstant() &&
192 descriptor_->hint_stack_parameter_count_ < 0) { 189 descriptor_->hint_stack_parameter_count_ < 0) {
193 HInstruction* amount = graph()->GetConstant1(); 190 HInstruction* amount = graph()->GetConstant1();
194 stack_pop_count = AddInstruction( 191 stack_pop_count = Add<HAdd>(stack_parameter_count, amount);
195 HAdd::New(zone, context_, stack_parameter_count, amount));
196 stack_pop_count->ChangeRepresentation(Representation::Integer32()); 192 stack_pop_count->ChangeRepresentation(Representation::Integer32());
197 stack_pop_count->ClearFlag(HValue::kCanOverflow); 193 stack_pop_count->ClearFlag(HValue::kCanOverflow);
198 } else { 194 } else {
199 int count = descriptor_->hint_stack_parameter_count_; 195 int count = descriptor_->hint_stack_parameter_count_;
200 stack_pop_count = AddInstruction(new(zone) HConstant(count)); 196 stack_pop_count = Add<HConstant>(count);
201 } 197 }
202 } 198 }
203 199
204 if (current_block() != NULL) { 200 if (current_block() != NULL) {
205 HReturn* hreturn_instruction = new(zone) HReturn(return_value, 201 HReturn* hreturn_instruction = NewAndCast<HReturn>(return_value,
206 context_, 202 stack_pop_count);
207 stack_pop_count);
208 current_block()->Finish(hreturn_instruction); 203 current_block()->Finish(hreturn_instruction);
209 set_current_block(NULL); 204 set_current_block(NULL);
210 } 205 }
211 return true; 206 return true;
212 } 207 }
213 208
214 209
215 template <class Stub> 210 template <class Stub>
216 class CodeStubGraphBuilder: public CodeStubGraphBuilderBase { 211 class CodeStubGraphBuilder: public CodeStubGraphBuilderBase {
217 public: 212 public:
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 if_number.If<HIsSmiAndBranch>(value); 310 if_number.If<HIsSmiAndBranch>(value);
316 if_number.OrIf<HCompareMap>(value, isolate()->factory()->heap_number_map()); 311 if_number.OrIf<HCompareMap>(value, isolate()->factory()->heap_number_map());
317 if_number.Then(); 312 if_number.Then();
318 313
319 // Return the number. 314 // Return the number.
320 Push(value); 315 Push(value);
321 316
322 if_number.Else(); 317 if_number.Else();
323 318
324 // Convert the parameter to number using the builtin. 319 // Convert the parameter to number using the builtin.
325 HValue* function = AddLoadJSBuiltin(Builtins::TO_NUMBER, context()); 320 HValue* function = AddLoadJSBuiltin(Builtins::TO_NUMBER);
326 Add<HPushArgument>(value); 321 Add<HPushArgument>(value);
327 Push(Add<HInvokeFunction>(context(), function, 1)); 322 Push(Add<HInvokeFunction>(function, 1));
328 323
329 if_number.End(); 324 if_number.End();
330 325
331 return Pop(); 326 return Pop();
332 } 327 }
333 328
334 329
335 Handle<Code> ToNumberStub::GenerateCode() { 330 Handle<Code> ToNumberStub::GenerateCode() {
336 return DoGenerateCode(this); 331 return DoGenerateCode(this);
337 } 332 }
338 333
339 334
340 template <> 335 template <>
341 HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() { 336 HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() {
342 Zone* zone = this->zone();
343 Factory* factory = isolate()->factory(); 337 Factory* factory = isolate()->factory();
344 HValue* undefined = graph()->GetConstantUndefined(); 338 HValue* undefined = graph()->GetConstantUndefined();
345 AllocationSiteMode alloc_site_mode = casted_stub()->allocation_site_mode(); 339 AllocationSiteMode alloc_site_mode = casted_stub()->allocation_site_mode();
346 FastCloneShallowArrayStub::Mode mode = casted_stub()->mode(); 340 FastCloneShallowArrayStub::Mode mode = casted_stub()->mode();
347 int length = casted_stub()->length(); 341 int length = casted_stub()->length();
348 342
349 HInstruction* allocation_site = 343 HInstruction* allocation_site = Add<HLoadKeyed>(GetParameter(0),
350 AddInstruction(new(zone) HLoadKeyed(GetParameter(0), 344 GetParameter(1),
351 GetParameter(1), 345 static_cast<HValue*>(NULL),
352 NULL, 346 FAST_ELEMENTS);
353 FAST_ELEMENTS));
354 IfBuilder checker(this); 347 IfBuilder checker(this);
355 checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site, undefined); 348 checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site,
349 undefined);
356 checker.Then(); 350 checker.Then();
357 351
358 HObjectAccess access = HObjectAccess::ForAllocationSiteTransitionInfo(); 352 HObjectAccess access = HObjectAccess::ForAllocationSiteTransitionInfo();
359 HInstruction* boilerplate = AddLoad(allocation_site, access); 353 HInstruction* boilerplate = Add<HLoadNamedField>(allocation_site, access);
360 if (mode == FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS) { 354 if (mode == FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS) {
361 HValue* elements = AddLoadElements(boilerplate); 355 HValue* elements = AddLoadElements(boilerplate);
362 356
363 IfBuilder if_fixed_cow(this); 357 IfBuilder if_fixed_cow(this);
364 if_fixed_cow.If<HCompareMap>(elements, factory->fixed_cow_array_map()); 358 if_fixed_cow.If<HCompareMap>(elements, factory->fixed_cow_array_map());
365 if_fixed_cow.Then(); 359 if_fixed_cow.Then();
366 environment()->Push(BuildCloneShallowArray(context(), 360 environment()->Push(BuildCloneShallowArray(boilerplate,
367 boilerplate,
368 allocation_site, 361 allocation_site,
369 alloc_site_mode, 362 alloc_site_mode,
370 FAST_ELEMENTS, 363 FAST_ELEMENTS,
371 0/*copy-on-write*/)); 364 0/*copy-on-write*/));
372 if_fixed_cow.Else(); 365 if_fixed_cow.Else();
373 366
374 IfBuilder if_fixed(this); 367 IfBuilder if_fixed(this);
375 if_fixed.If<HCompareMap>(elements, factory->fixed_array_map()); 368 if_fixed.If<HCompareMap>(elements, factory->fixed_array_map());
376 if_fixed.Then(); 369 if_fixed.Then();
377 environment()->Push(BuildCloneShallowArray(context(), 370 environment()->Push(BuildCloneShallowArray(boilerplate,
378 boilerplate,
379 allocation_site, 371 allocation_site,
380 alloc_site_mode, 372 alloc_site_mode,
381 FAST_ELEMENTS, 373 FAST_ELEMENTS,
382 length)); 374 length));
383 if_fixed.Else(); 375 if_fixed.Else();
384 environment()->Push(BuildCloneShallowArray(context(), 376 environment()->Push(BuildCloneShallowArray(boilerplate,
385 boilerplate,
386 allocation_site, 377 allocation_site,
387 alloc_site_mode, 378 alloc_site_mode,
388 FAST_DOUBLE_ELEMENTS, 379 FAST_DOUBLE_ELEMENTS,
389 length)); 380 length));
390 } else { 381 } else {
391 ElementsKind elements_kind = casted_stub()->ComputeElementsKind(); 382 ElementsKind elements_kind = casted_stub()->ComputeElementsKind();
392 environment()->Push(BuildCloneShallowArray(context(), 383 environment()->Push(BuildCloneShallowArray(boilerplate,
393 boilerplate,
394 allocation_site, 384 allocation_site,
395 alloc_site_mode, 385 alloc_site_mode,
396 elements_kind, 386 elements_kind,
397 length)); 387 length));
398 } 388 }
399 389
400 checker.ElseDeopt(); 390 checker.ElseDeopt();
401 checker.End(); 391 checker.End();
402 392
403 return environment()->Pop(); 393 return environment()->Pop();
404 } 394 }
405 395
406 396
407 Handle<Code> FastCloneShallowArrayStub::GenerateCode() { 397 Handle<Code> FastCloneShallowArrayStub::GenerateCode() {
408 return DoGenerateCode(this); 398 return DoGenerateCode(this);
409 } 399 }
410 400
411 401
412 template <> 402 template <>
413 HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() { 403 HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() {
414 Zone* zone = this->zone(); 404 Zone* zone = this->zone();
415 HValue* undefined = graph()->GetConstantUndefined(); 405 HValue* undefined = graph()->GetConstantUndefined();
416 406
417 HInstruction* boilerplate = 407 HInstruction* boilerplate = Add<HLoadKeyed>(GetParameter(0),
418 AddInstruction(new(zone) HLoadKeyed(GetParameter(0), 408 GetParameter(1),
419 GetParameter(1), 409 static_cast<HValue*>(NULL),
420 NULL, 410 FAST_ELEMENTS);
421 FAST_ELEMENTS));
422 411
423 IfBuilder checker(this); 412 IfBuilder checker(this);
424 checker.IfNot<HCompareObjectEqAndBranch, HValue*>(boilerplate, undefined); 413 checker.IfNot<HCompareObjectEqAndBranch, HValue*>(boilerplate,
414 undefined);
425 checker.And(); 415 checker.And();
426 416
427 int size = JSObject::kHeaderSize + casted_stub()->length() * kPointerSize; 417 int size = JSObject::kHeaderSize + casted_stub()->length() * kPointerSize;
428 HValue* boilerplate_size = 418 HValue* boilerplate_size =
429 AddInstruction(new(zone) HInstanceSize(boilerplate)); 419 AddInstruction(new(zone) HInstanceSize(boilerplate));
430 HValue* size_in_words = 420 HValue* size_in_words = Add<HConstant>(size >> kPointerSizeLog2);
431 AddInstruction(new(zone) HConstant(size >> kPointerSizeLog2));
432 checker.If<HCompareNumericAndBranch>(boilerplate_size, 421 checker.If<HCompareNumericAndBranch>(boilerplate_size,
433 size_in_words, Token::EQ); 422 size_in_words, Token::EQ);
434 checker.Then(); 423 checker.Then();
435 424
436 HValue* size_in_bytes = AddInstruction(new(zone) HConstant(size)); 425 HValue* size_in_bytes = Add<HConstant>(size);
437 HAllocate::Flags flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE; 426 HAllocate::Flags flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE;
438 if (isolate()->heap()->ShouldGloballyPretenure()) { 427 if (isolate()->heap()->ShouldGloballyPretenure()) {
439 flags = static_cast<HAllocate::Flags>( 428 flags = static_cast<HAllocate::Flags>(
440 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); 429 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE);
441 } 430 }
442 431
443 HInstruction* object = AddInstruction(new(zone) 432 HValue* object = Add<HAllocate>(size_in_bytes, HType::JSObject(), flags);
444 HAllocate(context(), size_in_bytes, HType::JSObject(), flags));
445 433
446 for (int i = 0; i < size; i += kPointerSize) { 434 for (int i = 0; i < size; i += kPointerSize) {
447 HObjectAccess access = HObjectAccess::ForJSObjectOffset(i); 435 HObjectAccess access = HObjectAccess::ForJSObjectOffset(i);
448 AddStore(object, access, AddLoad(boilerplate, access)); 436 Add<HStoreNamedField>(object, access,
437 Add<HLoadNamedField>(boilerplate, access));
449 } 438 }
450 439
451 environment()->Push(object); 440 environment()->Push(object);
452 checker.ElseDeopt(); 441 checker.ElseDeopt();
453 checker.End(); 442 checker.End();
454 443
455 return environment()->Pop(); 444 return environment()->Pop();
456 } 445 }
457 446
458 447
459 Handle<Code> FastCloneShallowObjectStub::GenerateCode() { 448 Handle<Code> FastCloneShallowObjectStub::GenerateCode() {
460 return DoGenerateCode(this); 449 return DoGenerateCode(this);
461 } 450 }
462 451
463 452
464 template <> 453 template <>
465 HValue* CodeStubGraphBuilder<CreateAllocationSiteStub>::BuildCodeStub() { 454 HValue* CodeStubGraphBuilder<CreateAllocationSiteStub>::BuildCodeStub() {
466 Zone* zone = this->zone(); 455 HValue* size = Add<HConstant>(AllocationSite::kSize);
467
468 HValue* size = AddInstruction(new(zone) HConstant(AllocationSite::kSize));
469 HAllocate::Flags flags = HAllocate::DefaultFlags(); 456 HAllocate::Flags flags = HAllocate::DefaultFlags();
470 flags = static_cast<HAllocate::Flags>( 457 flags = static_cast<HAllocate::Flags>(
471 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); 458 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE);
472 HInstruction* object = AddInstruction(new(zone) 459 HInstruction* object = Add<HAllocate>(size, HType::JSObject(), flags);
473 HAllocate(context(), size, HType::JSObject(), flags));
474 460
475 // Store the map 461 // Store the map
476 Handle<Map> allocation_site_map(isolate()->heap()->allocation_site_map(), 462 Handle<Map> allocation_site_map(isolate()->heap()->allocation_site_map(),
477 isolate()); 463 isolate());
478 AddStoreMapConstant(object, allocation_site_map); 464 AddStoreMapConstant(object, allocation_site_map);
479 465
480 // Store the payload (smi elements kind) 466 // Store the payload (smi elements kind)
481 HValue* initial_elements_kind = AddInstruction(new(zone) HConstant( 467 HValue* initial_elements_kind = Add<HConstant>(GetInitialFastElementsKind());
482 GetInitialFastElementsKind()));
483 Add<HStoreNamedField>(object, 468 Add<HStoreNamedField>(object,
484 HObjectAccess::ForAllocationSiteTransitionInfo(), 469 HObjectAccess::ForAllocationSiteTransitionInfo(),
485 initial_elements_kind); 470 initial_elements_kind);
486 471
487 Add<HLinkObjectInList>(object, HObjectAccess::ForAllocationSiteWeakNext(), 472 Add<HLinkObjectInList>(object, HObjectAccess::ForAllocationSiteWeakNext(),
488 HLinkObjectInList::ALLOCATION_SITE_LIST); 473 HLinkObjectInList::ALLOCATION_SITE_LIST);
489 474
490 // We use a hammer (SkipWriteBarrier()) to indicate that we know the input 475 // We use a hammer (SkipWriteBarrier()) to indicate that we know the input
491 // cell is really a Cell, and so no write barrier is needed. 476 // cell is really a Cell, and so no write barrier is needed.
492 // TODO(mvstanton): Add a debug_code check to verify the input cell is really 477 // TODO(mvstanton): Add a debug_code check to verify the input cell is really
493 // a cell. (perhaps with a new instruction, HAssert). 478 // a cell. (perhaps with a new instruction, HAssert).
494 HInstruction* cell = GetParameter(0); 479 HInstruction* cell = GetParameter(0);
495 HObjectAccess access = HObjectAccess::ForCellValue(); 480 HObjectAccess access = HObjectAccess::ForCellValue();
496 HStoreNamedField* store = AddStore(cell, access, object); 481 HStoreNamedField* store = AddAndCast<HStoreNamedField>(cell, access, object);
497 store->SkipWriteBarrier(); 482 store->SkipWriteBarrier();
498 return cell; 483 return cell;
499 } 484 }
500 485
501 486
502 Handle<Code> CreateAllocationSiteStub::GenerateCode() { 487 Handle<Code> CreateAllocationSiteStub::GenerateCode() {
503 return DoGenerateCode(this); 488 return DoGenerateCode(this);
504 } 489 }
505 490
506 491
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 return DoGenerateCode(this); 568 return DoGenerateCode(this);
584 } 569 }
585 570
586 HValue* CodeStubGraphBuilderBase::BuildArrayConstructor( 571 HValue* CodeStubGraphBuilderBase::BuildArrayConstructor(
587 ElementsKind kind, 572 ElementsKind kind,
588 ContextCheckMode context_mode, 573 ContextCheckMode context_mode,
589 AllocationSiteOverrideMode override_mode, 574 AllocationSiteOverrideMode override_mode,
590 ArgumentClass argument_class) { 575 ArgumentClass argument_class) {
591 HValue* constructor = GetParameter(ArrayConstructorStubBase::kConstructor); 576 HValue* constructor = GetParameter(ArrayConstructorStubBase::kConstructor);
592 if (context_mode == CONTEXT_CHECK_REQUIRED) { 577 if (context_mode == CONTEXT_CHECK_REQUIRED) {
593 HInstruction* array_function = BuildGetArrayFunction(context()); 578 HInstruction* array_function = BuildGetArrayFunction();
594 ArrayContextChecker checker(this, constructor, array_function); 579 ArrayContextChecker checker(this, constructor, array_function);
595 } 580 }
596 581
597 HValue* property_cell = GetParameter(ArrayConstructorStubBase::kPropertyCell); 582 HValue* property_cell = GetParameter(ArrayConstructorStubBase::kPropertyCell);
598 // Walk through the property cell to the AllocationSite 583 // Walk through the property cell to the AllocationSite
599 HValue* alloc_site = AddInstruction(new(zone()) HLoadNamedField(property_cell, 584 HValue* alloc_site = Add<HLoadNamedField>(property_cell,
600 HObjectAccess::ForCellValue())); 585 HObjectAccess::ForCellValue());
601 JSArrayBuilder array_builder(this, kind, alloc_site, constructor, 586 JSArrayBuilder array_builder(this, kind, alloc_site, constructor,
602 override_mode); 587 override_mode);
603 HValue* result = NULL; 588 HValue* result = NULL;
604 switch (argument_class) { 589 switch (argument_class) {
605 case NONE: 590 case NONE:
606 result = array_builder.AllocateEmptyArray(); 591 result = array_builder.AllocateEmptyArray();
607 break; 592 break;
608 case SINGLE: 593 case SINGLE:
609 result = BuildArraySingleArgumentConstructor(&array_builder); 594 result = BuildArraySingleArgumentConstructor(&array_builder);
610 break; 595 break;
(...skipping 27 matching lines...) Expand all
638 return result; 623 return result;
639 } 624 }
640 625
641 626
642 HValue* CodeStubGraphBuilderBase::BuildArraySingleArgumentConstructor( 627 HValue* CodeStubGraphBuilderBase::BuildArraySingleArgumentConstructor(
643 JSArrayBuilder* array_builder) { 628 JSArrayBuilder* array_builder) {
644 // Smi check and range check on the input arg. 629 // Smi check and range check on the input arg.
645 HValue* constant_one = graph()->GetConstant1(); 630 HValue* constant_one = graph()->GetConstant1();
646 HValue* constant_zero = graph()->GetConstant0(); 631 HValue* constant_zero = graph()->GetConstant0();
647 632
648 HInstruction* elements = AddInstruction( 633 HInstruction* elements = Add<HArgumentsElements>(false);
649 new(zone()) HArgumentsElements(false));
650 HInstruction* argument = AddInstruction( 634 HInstruction* argument = AddInstruction(
651 new(zone()) HAccessArgumentsAt(elements, constant_one, constant_zero)); 635 new(zone()) HAccessArgumentsAt(elements, constant_one, constant_zero));
652 636
653 HConstant* max_alloc_length = 637 HConstant* max_alloc_length =
654 new(zone()) HConstant(JSObject::kInitialMaxFastElementArray); 638 AddAndCast<HConstant>(JSObject::kInitialMaxFastElementArray);
655 AddInstruction(max_alloc_length);
656 const int initial_capacity = JSArray::kPreallocatedArrayElements; 639 const int initial_capacity = JSArray::kPreallocatedArrayElements;
657 HConstant* initial_capacity_node = new(zone()) HConstant(initial_capacity); 640 HConstant* initial_capacity_node = NewAndCast<HConstant>(initial_capacity);
658 AddInstruction(initial_capacity_node); 641 AddInstruction(initial_capacity_node);
659 642
660 HBoundsCheck* checked_arg = Add<HBoundsCheck>(argument, max_alloc_length); 643 HInstruction* checked_arg = Add<HBoundsCheck>(argument, max_alloc_length);
661 IfBuilder if_builder(this); 644 IfBuilder if_builder(this);
662 if_builder.If<HCompareNumericAndBranch>(checked_arg, constant_zero, 645 if_builder.If<HCompareNumericAndBranch>(checked_arg, constant_zero,
663 Token::EQ); 646 Token::EQ);
664 if_builder.Then(); 647 if_builder.Then();
665 Push(initial_capacity_node); // capacity 648 Push(initial_capacity_node); // capacity
666 Push(constant_zero); // length 649 Push(constant_zero); // length
667 if_builder.Else(); 650 if_builder.Else();
668 Push(checked_arg); // capacity 651 Push(checked_arg); // capacity
669 Push(checked_arg); // length 652 Push(checked_arg); // length
670 if_builder.End(); 653 if_builder.End();
(...skipping 19 matching lines...) Expand all
690 fill_with_hole); 673 fill_with_hole);
691 HValue* elements = array_builder->GetElementsLocation(); 674 HValue* elements = array_builder->GetElementsLocation();
692 ASSERT(elements != NULL); 675 ASSERT(elements != NULL);
693 676
694 // Now populate the elements correctly. 677 // Now populate the elements correctly.
695 LoopBuilder builder(this, 678 LoopBuilder builder(this,
696 context(), 679 context(),
697 LoopBuilder::kPostIncrement); 680 LoopBuilder::kPostIncrement);
698 HValue* start = graph()->GetConstant0(); 681 HValue* start = graph()->GetConstant0();
699 HValue* key = builder.BeginBody(start, length, Token::LT); 682 HValue* key = builder.BeginBody(start, length, Token::LT);
700 HInstruction* argument_elements = AddInstruction( 683 HInstruction* argument_elements = Add<HArgumentsElements>(false);
701 new(zone()) HArgumentsElements(false));
702 HInstruction* argument = AddInstruction(new(zone()) HAccessArgumentsAt( 684 HInstruction* argument = AddInstruction(new(zone()) HAccessArgumentsAt(
703 argument_elements, length, key)); 685 argument_elements, length, key));
704 686
705 AddInstruction(new(zone()) HStoreKeyed(elements, key, argument, kind)); 687 Add<HStoreKeyed>(elements, key, argument, kind);
706 builder.EndBody(); 688 builder.EndBody();
707 return new_object; 689 return new_object;
708 } 690 }
709 691
710 692
711 template <> 693 template <>
712 HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() { 694 HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() {
713 ElementsKind kind = casted_stub()->elements_kind(); 695 ElementsKind kind = casted_stub()->elements_kind();
714 ContextCheckMode context_mode = casted_stub()->context_mode(); 696 ContextCheckMode context_mode = casted_stub()->context_mode();
715 AllocationSiteOverrideMode override_mode = casted_stub()->override_mode(); 697 AllocationSiteOverrideMode override_mode = casted_stub()->override_mode();
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 800
819 template <> 801 template <>
820 HValue* CodeStubGraphBuilder<UnaryOpStub>::BuildCodeInitializedStub() { 802 HValue* CodeStubGraphBuilder<UnaryOpStub>::BuildCodeInitializedStub() {
821 UnaryOpStub* stub = casted_stub(); 803 UnaryOpStub* stub = casted_stub();
822 Handle<Type> type = stub->GetType(graph()->isolate()); 804 Handle<Type> type = stub->GetType(graph()->isolate());
823 HValue* input = GetParameter(0); 805 HValue* input = GetParameter(0);
824 806
825 // Prevent unwanted HChange being inserted to ensure that the stub 807 // Prevent unwanted HChange being inserted to ensure that the stub
826 // deopts on newly encountered types. 808 // deopts on newly encountered types.
827 if (!type->Maybe(Type::Double())) { 809 if (!type->Maybe(Type::Double())) {
828 input = AddInstruction(new(zone()) 810 input = Add<HForceRepresentation>(input, Representation::Smi());
829 HForceRepresentation(input, Representation::Smi()));
830 } 811 }
831 812
832 if (!type->Is(Type::Number())) { 813 if (!type->Is(Type::Number())) {
833 // If we expect to see other things than Numbers, we will create a generic 814 // If we expect to see other things than Numbers, we will create a generic
834 // stub, which handles all numbers and calls into the runtime for the rest. 815 // stub, which handles all numbers and calls into the runtime for the rest.
835 IfBuilder if_number(this); 816 IfBuilder if_number(this);
836 if_number.If<HIsNumberAndBranch>(input); 817 if_number.If<HIsNumberAndBranch>(input);
837 if_number.Then(); 818 if_number.Then();
838 HInstruction* res = BuildUnaryMathOp(input, type, stub->operation()); 819 HInstruction* res = BuildUnaryMathOp(input, type, stub->operation());
839 if_number.Return(AddInstruction(res)); 820 if_number.Return(AddInstruction(res));
840 if_number.Else(); 821 if_number.Else();
841 HValue* function = AddLoadJSBuiltin(stub->ToJSBuiltin(), context()); 822 HValue* function = AddLoadJSBuiltin(stub->ToJSBuiltin());
842 Add<HPushArgument>(GetParameter(0)); 823 Add<HPushArgument>(GetParameter(0));
843 HValue* result = Add<HInvokeFunction>(context(), function, 1); 824 HValue* result = Add<HInvokeFunction>(function, 1);
844 if_number.Return(result); 825 if_number.Return(result);
845 if_number.End(); 826 if_number.End();
846 return graph()->GetConstantUndefined(); 827 return graph()->GetConstantUndefined();
847 } 828 }
848 829
849 return AddInstruction(BuildUnaryMathOp(input, type, stub->operation())); 830 return AddInstruction(BuildUnaryMathOp(input, type, stub->operation()));
850 } 831 }
851 832
852 833
853 Handle<Code> UnaryOpStub::GenerateCode() { 834 Handle<Code> UnaryOpStub::GenerateCode() {
(...skipping 30 matching lines...) Expand all
884 865
885 HParameter* receiver = GetParameter(0); 866 HParameter* receiver = GetParameter(0);
886 HParameter* value = GetParameter(2); 867 HParameter* value = GetParameter(2);
887 868
888 // Check that the map of the global has not changed: use a placeholder map 869 // Check that the map of the global has not changed: use a placeholder map
889 // that will be replaced later with the global object's map. 870 // that will be replaced later with the global object's map.
890 Handle<Map> placeholder_map = isolate()->factory()->meta_map(); 871 Handle<Map> placeholder_map = isolate()->factory()->meta_map();
891 AddInstruction(HCheckMaps::New( 872 AddInstruction(HCheckMaps::New(
892 receiver, placeholder_map, zone(), top_info())); 873 receiver, placeholder_map, zone(), top_info()));
893 874
894 HValue* cell = Add<HConstant>(placeholder_cell, Representation::Tagged()); 875 HValue* cell = Add<HConstant>(placeholder_cell);
895 HObjectAccess access(HObjectAccess::ForCellPayload(isolate())); 876 HObjectAccess access(HObjectAccess::ForCellPayload(isolate()));
896 HValue* cell_contents = Add<HLoadNamedField>(cell, access); 877 HValue* cell_contents = Add<HLoadNamedField>(cell, access);
897 878
898 if (stub->is_constant()) { 879 if (stub->is_constant()) {
899 IfBuilder builder(this); 880 IfBuilder builder(this);
900 builder.If<HCompareObjectEqAndBranch>(cell_contents, value); 881 builder.If<HCompareObjectEqAndBranch>(cell_contents, value);
901 builder.Then(); 882 builder.Then();
902 builder.ElseDeopt(); 883 builder.ElseDeopt();
903 builder.End(); 884 builder.End();
904 } else { 885 } else {
905 // Load the payload of the global parameter cell. A hole indicates that the 886 // Load the payload of the global parameter cell. A hole indicates that the
906 // property has been deleted and that the store must be handled by the 887 // property has been deleted and that the store must be handled by the
907 // runtime. 888 // runtime.
908 IfBuilder builder(this); 889 IfBuilder builder(this);
909 HValue* hole_value = Add<HConstant>(hole, Representation::Tagged()); 890 HValue* hole_value = Add<HConstant>(hole);
910 builder.If<HCompareObjectEqAndBranch>(cell_contents, hole_value); 891 builder.If<HCompareObjectEqAndBranch>(cell_contents, hole_value);
911 builder.Then(); 892 builder.Then();
912 builder.Deopt(); 893 builder.Deopt();
913 builder.Else(); 894 builder.Else();
914 Add<HStoreNamedField>(cell, access, value); 895 Add<HStoreNamedField>(cell, access, value);
915 builder.End(); 896 builder.End();
916 } 897 }
917 898
918 return value; 899 return value;
919 } 900 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 return value; 933 return value;
953 } 934 }
954 935
955 936
956 Handle<Code> ElementsTransitionAndStoreStub::GenerateCode() { 937 Handle<Code> ElementsTransitionAndStoreStub::GenerateCode() {
957 return DoGenerateCode(this); 938 return DoGenerateCode(this);
958 } 939 }
959 940
960 941
961 } } // namespace v8::internal 942 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/hydrogen.h » ('j') | src/hydrogen.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698