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

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: Review feedback 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') | 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 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 Add<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 Add<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_ = New<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 = New<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 426
438 HInstruction* object = AddInstruction(new(zone) 427 HInstruction* object = Add<HAllocate>(size_in_bytes, HType::JSObject(),
439 HAllocate(context(), size_in_bytes, HType::JSObject(), 428 isolate()->heap()->ShouldGloballyPretenure());
440 isolate()->heap()->ShouldGloballyPretenure()));
441 429
442 for (int i = 0; i < size; i += kPointerSize) { 430 for (int i = 0; i < size; i += kPointerSize) {
443 HObjectAccess access = HObjectAccess::ForJSObjectOffset(i); 431 HObjectAccess access = HObjectAccess::ForJSObjectOffset(i);
444 AddStore(object, access, AddLoad(boilerplate, access)); 432 Add<HStoreNamedField>(object, access,
433 Add<HLoadNamedField>(boilerplate, access));
445 } 434 }
446 435
447 environment()->Push(object); 436 environment()->Push(object);
448 checker.ElseDeopt(); 437 checker.ElseDeopt();
449 checker.End(); 438 checker.End();
450 439
451 return environment()->Pop(); 440 return environment()->Pop();
452 } 441 }
453 442
454 443
455 Handle<Code> FastCloneShallowObjectStub::GenerateCode() { 444 Handle<Code> FastCloneShallowObjectStub::GenerateCode() {
456 return DoGenerateCode(this); 445 return DoGenerateCode(this);
457 } 446 }
458 447
459 448
460 template <> 449 template <>
461 HValue* CodeStubGraphBuilder<CreateAllocationSiteStub>::BuildCodeStub() { 450 HValue* CodeStubGraphBuilder<CreateAllocationSiteStub>::BuildCodeStub() {
462 HValue* size = Add<HConstant>(AllocationSite::kSize); 451 HValue* size = Add<HConstant>(AllocationSite::kSize);
463 HInstruction* object = Add<HAllocate>( 452 HInstruction* object = Add<HAllocate>(size, HType::JSObject(), true);
464 context(), size, HType::JSObject(), true);
465 453
466 // Store the map 454 // Store the map
467 Handle<Map> allocation_site_map(isolate()->heap()->allocation_site_map(), 455 Handle<Map> allocation_site_map(isolate()->heap()->allocation_site_map(),
468 isolate()); 456 isolate());
469 AddStoreMapConstant(object, allocation_site_map); 457 AddStoreMapConstant(object, allocation_site_map);
470 458
471 // Store the payload (smi elements kind) 459 // Store the payload (smi elements kind)
472 HValue* initial_elements_kind = Add<HConstant>(GetInitialFastElementsKind()); 460 HValue* initial_elements_kind = Add<HConstant>(GetInitialFastElementsKind());
473 Add<HStoreNamedField>(object, 461 Add<HStoreNamedField>(object,
474 HObjectAccess::ForAllocationSiteTransitionInfo(), 462 HObjectAccess::ForAllocationSiteTransitionInfo(),
475 initial_elements_kind); 463 initial_elements_kind);
476 464
477 // Link the object to the allocation site list 465 // Link the object to the allocation site list
478 HValue* site_list = Add<HConstant>( 466 HValue* site_list = Add<HConstant>(
479 ExternalReference::allocation_sites_list_address(isolate())); 467 ExternalReference::allocation_sites_list_address(isolate()));
480 HValue* site = AddLoad(site_list, HObjectAccess::ForAllocationSiteList()); 468 HValue* site = Add<HLoadNamedField>(site_list,
469 HObjectAccess::ForAllocationSiteList());
481 HStoreNamedField* store = 470 HStoreNamedField* store =
482 AddStore(object, HObjectAccess::ForAllocationSiteWeakNext(), site); 471 Add<HStoreNamedField>(object, HObjectAccess::ForAllocationSiteWeakNext(),
472 site);
483 store->SkipWriteBarrier(); 473 store->SkipWriteBarrier();
484 AddStore(site_list, HObjectAccess::ForAllocationSiteList(), object); 474 Add<HStoreNamedField>(site_list, HObjectAccess::ForAllocationSiteList(),
475 object);
485 476
486 // We use a hammer (SkipWriteBarrier()) to indicate that we know the input 477 // We use a hammer (SkipWriteBarrier()) to indicate that we know the input
487 // cell is really a Cell, and so no write barrier is needed. 478 // cell is really a Cell, and so no write barrier is needed.
488 // TODO(mvstanton): Add a debug_code check to verify the input cell is really 479 // TODO(mvstanton): Add a debug_code check to verify the input cell is really
489 // a cell. (perhaps with a new instruction, HAssert). 480 // a cell. (perhaps with a new instruction, HAssert).
490 HInstruction* cell = GetParameter(0); 481 HInstruction* cell = GetParameter(0);
491 HObjectAccess access = HObjectAccess::ForCellValue(); 482 HObjectAccess access = HObjectAccess::ForCellValue();
492 store = AddStore(cell, access, object); 483 store = Add<HStoreNamedField>(cell, access, object);
493 store->SkipWriteBarrier(); 484 store->SkipWriteBarrier();
494 return cell; 485 return cell;
495 } 486 }
496 487
497 488
498 Handle<Code> CreateAllocationSiteStub::GenerateCode() { 489 Handle<Code> CreateAllocationSiteStub::GenerateCode() {
499 return DoGenerateCode(this); 490 return DoGenerateCode(this);
500 } 491 }
501 492
502 493
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 return DoGenerateCode(this); 570 return DoGenerateCode(this);
580 } 571 }
581 572
582 HValue* CodeStubGraphBuilderBase::BuildArrayConstructor( 573 HValue* CodeStubGraphBuilderBase::BuildArrayConstructor(
583 ElementsKind kind, 574 ElementsKind kind,
584 ContextCheckMode context_mode, 575 ContextCheckMode context_mode,
585 AllocationSiteOverrideMode override_mode, 576 AllocationSiteOverrideMode override_mode,
586 ArgumentClass argument_class) { 577 ArgumentClass argument_class) {
587 HValue* constructor = GetParameter(ArrayConstructorStubBase::kConstructor); 578 HValue* constructor = GetParameter(ArrayConstructorStubBase::kConstructor);
588 if (context_mode == CONTEXT_CHECK_REQUIRED) { 579 if (context_mode == CONTEXT_CHECK_REQUIRED) {
589 HInstruction* array_function = BuildGetArrayFunction(context()); 580 HInstruction* array_function = BuildGetArrayFunction();
590 ArrayContextChecker checker(this, constructor, array_function); 581 ArrayContextChecker checker(this, constructor, array_function);
591 } 582 }
592 583
593 HValue* property_cell = GetParameter(ArrayConstructorStubBase::kPropertyCell); 584 HValue* property_cell = GetParameter(ArrayConstructorStubBase::kPropertyCell);
594 // Walk through the property cell to the AllocationSite 585 // Walk through the property cell to the AllocationSite
595 HValue* alloc_site = AddInstruction(new(zone()) HLoadNamedField(property_cell, 586 HValue* alloc_site = Add<HLoadNamedField>(property_cell,
596 HObjectAccess::ForCellValue())); 587 HObjectAccess::ForCellValue());
597 JSArrayBuilder array_builder(this, kind, alloc_site, constructor, 588 JSArrayBuilder array_builder(this, kind, alloc_site, constructor,
598 override_mode); 589 override_mode);
599 HValue* result = NULL; 590 HValue* result = NULL;
600 switch (argument_class) { 591 switch (argument_class) {
601 case NONE: 592 case NONE:
602 result = array_builder.AllocateEmptyArray(); 593 result = array_builder.AllocateEmptyArray();
603 break; 594 break;
604 case SINGLE: 595 case SINGLE:
605 result = BuildArraySingleArgumentConstructor(&array_builder); 596 result = BuildArraySingleArgumentConstructor(&array_builder);
606 break; 597 break;
(...skipping 27 matching lines...) Expand all
634 return result; 625 return result;
635 } 626 }
636 627
637 628
638 HValue* CodeStubGraphBuilderBase::BuildArraySingleArgumentConstructor( 629 HValue* CodeStubGraphBuilderBase::BuildArraySingleArgumentConstructor(
639 JSArrayBuilder* array_builder) { 630 JSArrayBuilder* array_builder) {
640 // Smi check and range check on the input arg. 631 // Smi check and range check on the input arg.
641 HValue* constant_one = graph()->GetConstant1(); 632 HValue* constant_one = graph()->GetConstant1();
642 HValue* constant_zero = graph()->GetConstant0(); 633 HValue* constant_zero = graph()->GetConstant0();
643 634
644 HInstruction* elements = AddInstruction( 635 HInstruction* elements = Add<HArgumentsElements>(false);
645 new(zone()) HArgumentsElements(false));
646 HInstruction* argument = AddInstruction( 636 HInstruction* argument = AddInstruction(
647 new(zone()) HAccessArgumentsAt(elements, constant_one, constant_zero)); 637 new(zone()) HAccessArgumentsAt(elements, constant_one, constant_zero));
648 638
649 HConstant* max_alloc_length = 639 HConstant* max_alloc_length =
650 new(zone()) HConstant(JSObject::kInitialMaxFastElementArray); 640 Add<HConstant>(JSObject::kInitialMaxFastElementArray);
651 AddInstruction(max_alloc_length);
652 const int initial_capacity = JSArray::kPreallocatedArrayElements; 641 const int initial_capacity = JSArray::kPreallocatedArrayElements;
653 HConstant* initial_capacity_node = new(zone()) HConstant(initial_capacity); 642 HConstant* initial_capacity_node = New<HConstant>(initial_capacity);
654 AddInstruction(initial_capacity_node); 643 AddInstruction(initial_capacity_node);
655 644
656 HBoundsCheck* checked_arg = Add<HBoundsCheck>(argument, max_alloc_length); 645 HInstruction* checked_arg = Add<HBoundsCheck>(argument, max_alloc_length);
657 IfBuilder if_builder(this); 646 IfBuilder if_builder(this);
658 if_builder.If<HCompareNumericAndBranch>(checked_arg, constant_zero, 647 if_builder.If<HCompareNumericAndBranch>(checked_arg, constant_zero,
659 Token::EQ); 648 Token::EQ);
660 if_builder.Then(); 649 if_builder.Then();
661 Push(initial_capacity_node); // capacity 650 Push(initial_capacity_node); // capacity
662 Push(constant_zero); // length 651 Push(constant_zero); // length
663 if_builder.Else(); 652 if_builder.Else();
664 Push(checked_arg); // capacity 653 Push(checked_arg); // capacity
665 Push(checked_arg); // length 654 Push(checked_arg); // length
666 if_builder.End(); 655 if_builder.End();
(...skipping 19 matching lines...) Expand all
686 fill_with_hole); 675 fill_with_hole);
687 HValue* elements = array_builder->GetElementsLocation(); 676 HValue* elements = array_builder->GetElementsLocation();
688 ASSERT(elements != NULL); 677 ASSERT(elements != NULL);
689 678
690 // Now populate the elements correctly. 679 // Now populate the elements correctly.
691 LoopBuilder builder(this, 680 LoopBuilder builder(this,
692 context(), 681 context(),
693 LoopBuilder::kPostIncrement); 682 LoopBuilder::kPostIncrement);
694 HValue* start = graph()->GetConstant0(); 683 HValue* start = graph()->GetConstant0();
695 HValue* key = builder.BeginBody(start, length, Token::LT); 684 HValue* key = builder.BeginBody(start, length, Token::LT);
696 HInstruction* argument_elements = AddInstruction( 685 HInstruction* argument_elements = Add<HArgumentsElements>(false);
697 new(zone()) HArgumentsElements(false));
698 HInstruction* argument = AddInstruction(new(zone()) HAccessArgumentsAt( 686 HInstruction* argument = AddInstruction(new(zone()) HAccessArgumentsAt(
699 argument_elements, length, key)); 687 argument_elements, length, key));
700 688
701 AddInstruction(new(zone()) HStoreKeyed(elements, key, argument, kind)); 689 Add<HStoreKeyed>(elements, key, argument, kind);
702 builder.EndBody(); 690 builder.EndBody();
703 return new_object; 691 return new_object;
704 } 692 }
705 693
706 694
707 template <> 695 template <>
708 HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() { 696 HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() {
709 ElementsKind kind = casted_stub()->elements_kind(); 697 ElementsKind kind = casted_stub()->elements_kind();
710 ContextCheckMode context_mode = casted_stub()->context_mode(); 698 ContextCheckMode context_mode = casted_stub()->context_mode();
711 AllocationSiteOverrideMode override_mode = casted_stub()->override_mode(); 699 AllocationSiteOverrideMode override_mode = casted_stub()->override_mode();
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
814 802
815 template <> 803 template <>
816 HValue* CodeStubGraphBuilder<UnaryOpStub>::BuildCodeInitializedStub() { 804 HValue* CodeStubGraphBuilder<UnaryOpStub>::BuildCodeInitializedStub() {
817 UnaryOpStub* stub = casted_stub(); 805 UnaryOpStub* stub = casted_stub();
818 Handle<Type> type = stub->GetType(graph()->isolate()); 806 Handle<Type> type = stub->GetType(graph()->isolate());
819 HValue* input = GetParameter(0); 807 HValue* input = GetParameter(0);
820 808
821 // Prevent unwanted HChange being inserted to ensure that the stub 809 // Prevent unwanted HChange being inserted to ensure that the stub
822 // deopts on newly encountered types. 810 // deopts on newly encountered types.
823 if (!type->Maybe(Type::Double())) { 811 if (!type->Maybe(Type::Double())) {
824 input = AddInstruction(new(zone()) 812 input = Add<HForceRepresentation>(input, Representation::Smi());
825 HForceRepresentation(input, Representation::Smi()));
826 } 813 }
827 814
828 if (!type->Is(Type::Number())) { 815 if (!type->Is(Type::Number())) {
829 // If we expect to see other things than Numbers, we will create a generic 816 // If we expect to see other things than Numbers, we will create a generic
830 // stub, which handles all numbers and calls into the runtime for the rest. 817 // stub, which handles all numbers and calls into the runtime for the rest.
831 IfBuilder if_number(this); 818 IfBuilder if_number(this);
832 if_number.If<HIsNumberAndBranch>(input); 819 if_number.If<HIsNumberAndBranch>(input);
833 if_number.Then(); 820 if_number.Then();
834 HInstruction* res = BuildUnaryMathOp(input, type, stub->operation()); 821 HInstruction* res = BuildUnaryMathOp(input, type, stub->operation());
835 if_number.Return(AddInstruction(res)); 822 if_number.Return(AddInstruction(res));
836 if_number.Else(); 823 if_number.Else();
837 HValue* function = AddLoadJSBuiltin(stub->ToJSBuiltin(), context()); 824 HValue* function = AddLoadJSBuiltin(stub->ToJSBuiltin());
838 Add<HPushArgument>(GetParameter(0)); 825 Add<HPushArgument>(GetParameter(0));
839 HValue* result = Add<HInvokeFunction>(context(), function, 1); 826 HValue* result = Add<HInvokeFunction>(function, 1);
840 if_number.Return(result); 827 if_number.Return(result);
841 if_number.End(); 828 if_number.End();
842 return graph()->GetConstantUndefined(); 829 return graph()->GetConstantUndefined();
843 } 830 }
844 831
845 return AddInstruction(BuildUnaryMathOp(input, type, stub->operation())); 832 return AddInstruction(BuildUnaryMathOp(input, type, stub->operation()));
846 } 833 }
847 834
848 835
849 Handle<Code> UnaryOpStub::GenerateCode() { 836 Handle<Code> UnaryOpStub::GenerateCode() {
(...skipping 27 matching lines...) Expand all
877 Handle<Object> placeholer_value(Smi::FromInt(0), isolate()); 864 Handle<Object> placeholer_value(Smi::FromInt(0), isolate());
878 Handle<PropertyCell> placeholder_cell = 865 Handle<PropertyCell> placeholder_cell =
879 isolate()->factory()->NewPropertyCell(placeholer_value); 866 isolate()->factory()->NewPropertyCell(placeholer_value);
880 867
881 HParameter* receiver = GetParameter(0); 868 HParameter* receiver = GetParameter(0);
882 HParameter* value = GetParameter(2); 869 HParameter* value = GetParameter(2);
883 870
884 // Check that the map of the global has not changed: use a placeholder map 871 // Check that the map of the global has not changed: use a placeholder map
885 // that will be replaced later with the global object's map. 872 // that will be replaced later with the global object's map.
886 Handle<Map> placeholder_map = isolate()->factory()->meta_map(); 873 Handle<Map> placeholder_map = isolate()->factory()->meta_map();
887 AddInstruction(HCheckMaps::New( 874 Add<HCheckMaps>(receiver, placeholder_map, top_info());
888 receiver, placeholder_map, zone(), top_info()));
889 875
890 HValue* cell = Add<HConstant>(placeholder_cell, Representation::Tagged()); 876 HValue* cell = Add<HConstant>(placeholder_cell);
891 HObjectAccess access(HObjectAccess::ForCellPayload(isolate())); 877 HObjectAccess access(HObjectAccess::ForCellPayload(isolate()));
892 HValue* cell_contents = Add<HLoadNamedField>(cell, access); 878 HValue* cell_contents = Add<HLoadNamedField>(cell, access);
893 879
894 if (stub->is_constant()) { 880 if (stub->is_constant()) {
895 IfBuilder builder(this); 881 IfBuilder builder(this);
896 builder.If<HCompareObjectEqAndBranch>(cell_contents, value); 882 builder.If<HCompareObjectEqAndBranch>(cell_contents, value);
897 builder.Then(); 883 builder.Then();
898 builder.ElseDeopt(); 884 builder.ElseDeopt();
899 builder.End(); 885 builder.End();
900 } else { 886 } else {
901 // Load the payload of the global parameter cell. A hole indicates that the 887 // Load the payload of the global parameter cell. A hole indicates that the
902 // property has been deleted and that the store must be handled by the 888 // property has been deleted and that the store must be handled by the
903 // runtime. 889 // runtime.
904 IfBuilder builder(this); 890 IfBuilder builder(this);
905 HValue* hole_value = Add<HConstant>(hole, Representation::Tagged()); 891 HValue* hole_value = Add<HConstant>(hole);
906 builder.If<HCompareObjectEqAndBranch>(cell_contents, hole_value); 892 builder.If<HCompareObjectEqAndBranch>(cell_contents, hole_value);
907 builder.Then(); 893 builder.Then();
908 builder.Deopt(); 894 builder.Deopt();
909 builder.Else(); 895 builder.Else();
910 Add<HStoreNamedField>(cell, access, value); 896 Add<HStoreNamedField>(cell, access, value);
911 builder.End(); 897 builder.End();
912 } 898 }
913 899
914 return value; 900 return value;
915 } 901 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
948 return value; 934 return value;
949 } 935 }
950 936
951 937
952 Handle<Code> ElementsTransitionAndStoreStub::GenerateCode() { 938 Handle<Code> ElementsTransitionAndStoreStub::GenerateCode() {
953 return DoGenerateCode(this); 939 return DoGenerateCode(this);
954 } 940 }
955 941
956 942
957 } } // namespace v8::internal 943 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/hydrogen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698