OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |