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