| 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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 HValue* GetArgumentsLength() { | 74 HValue* GetArgumentsLength() { |
| 75 // This is initialized in BuildGraph() | 75 // This is initialized in BuildGraph() |
| 76 ASSERT(arguments_length_ != NULL); | 76 ASSERT(arguments_length_ != NULL); |
| 77 return arguments_length_; | 77 return arguments_length_; |
| 78 } | 78 } |
| 79 CompilationInfo* info() { return &info_; } | 79 CompilationInfo* info() { return &info_; } |
| 80 HydrogenCodeStub* stub() { return info_.code_stub(); } | 80 HydrogenCodeStub* stub() { return info_.code_stub(); } |
| 81 HContext* context() { return context_; } | 81 HContext* context() { return context_; } |
| 82 Isolate* isolate() { return info_.isolate(); } | 82 Isolate* isolate() { return info_.isolate(); } |
| 83 | 83 |
| 84 HLoadNamedField* BuildLoadNamedField(HValue* object, |
| 85 Representation representation, |
| 86 int offset, |
| 87 bool is_inobject); |
| 88 |
| 84 enum ArgumentClass { | 89 enum ArgumentClass { |
| 85 NONE, | 90 NONE, |
| 86 SINGLE, | 91 SINGLE, |
| 87 MULTIPLE | 92 MULTIPLE |
| 88 }; | 93 }; |
| 89 | 94 |
| 90 HValue* BuildArrayConstructor(ElementsKind kind, | 95 HValue* BuildArrayConstructor(ElementsKind kind, |
| 91 AllocationSiteOverrideMode override_mode, | 96 AllocationSiteOverrideMode override_mode, |
| 92 ArgumentClass argument_class); | 97 ArgumentClass argument_class); |
| 93 HValue* BuildInternalArrayConstructor(ElementsKind kind, | 98 HValue* BuildInternalArrayConstructor(ElementsKind kind, |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 | 245 |
| 241 // Create the code object. | 246 // Create the code object. |
| 242 CodeDesc desc; | 247 CodeDesc desc; |
| 243 masm.GetCode(&desc); | 248 masm.GetCode(&desc); |
| 244 | 249 |
| 245 // Copy the generated code into a heap object. | 250 // Copy the generated code into a heap object. |
| 246 Code::Flags flags = Code::ComputeFlags( | 251 Code::Flags flags = Code::ComputeFlags( |
| 247 GetCodeKind(), | 252 GetCodeKind(), |
| 248 GetICState(), | 253 GetICState(), |
| 249 GetExtraICState(), | 254 GetExtraICState(), |
| 250 GetStubType(), | 255 GetStubType()); |
| 251 GetStubFlags()); | |
| 252 Handle<Code> new_object = factory->NewCode( | 256 Handle<Code> new_object = factory->NewCode( |
| 253 desc, flags, masm.CodeObject(), NeedsImmovableCode()); | 257 desc, flags, masm.CodeObject(), NeedsImmovableCode()); |
| 254 return new_object; | 258 return new_object; |
| 255 } | 259 } |
| 256 | 260 |
| 257 | 261 |
| 258 template <class Stub> | 262 template <class Stub> |
| 259 static Handle<Code> DoGenerateCode(Isolate* isolate, Stub* stub) { | 263 static Handle<Code> DoGenerateCode(Isolate* isolate, Stub* stub) { |
| 260 CodeStub::Major major_key = | 264 CodeStub::Major major_key = |
| 261 static_cast<HydrogenCodeStub*>(stub)->MajorKey(); | 265 static_cast<HydrogenCodeStub*>(stub)->MajorKey(); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 | 320 |
| 317 Handle<Code> ToNumberStub::GenerateCode(Isolate* isolate) { | 321 Handle<Code> ToNumberStub::GenerateCode(Isolate* isolate) { |
| 318 return DoGenerateCode(isolate, this); | 322 return DoGenerateCode(isolate, this); |
| 319 } | 323 } |
| 320 | 324 |
| 321 | 325 |
| 322 template <> | 326 template <> |
| 323 HValue* CodeStubGraphBuilder<NumberToStringStub>::BuildCodeStub() { | 327 HValue* CodeStubGraphBuilder<NumberToStringStub>::BuildCodeStub() { |
| 324 info()->MarkAsSavesCallerDoubles(); | 328 info()->MarkAsSavesCallerDoubles(); |
| 325 HValue* number = GetParameter(NumberToStringStub::kNumber); | 329 HValue* number = GetParameter(NumberToStringStub::kNumber); |
| 326 return BuildNumberToString(number, Type::Number(isolate())); | 330 return BuildNumberToString(number, Type::Number(zone())); |
| 327 } | 331 } |
| 328 | 332 |
| 329 | 333 |
| 330 Handle<Code> NumberToStringStub::GenerateCode(Isolate* isolate) { | 334 Handle<Code> NumberToStringStub::GenerateCode(Isolate* isolate) { |
| 331 return DoGenerateCode(isolate, this); | 335 return DoGenerateCode(isolate, this); |
| 332 } | 336 } |
| 333 | 337 |
| 334 | 338 |
| 335 template <> | 339 template <> |
| 336 HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() { | 340 HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() { |
| 337 Factory* factory = isolate()->factory(); | 341 Factory* factory = isolate()->factory(); |
| 338 HValue* undefined = graph()->GetConstantUndefined(); | 342 HValue* undefined = graph()->GetConstantUndefined(); |
| 339 AllocationSiteMode alloc_site_mode = casted_stub()->allocation_site_mode(); | 343 AllocationSiteMode alloc_site_mode = casted_stub()->allocation_site_mode(); |
| 340 FastCloneShallowArrayStub::Mode mode = casted_stub()->mode(); | 344 FastCloneShallowArrayStub::Mode mode = casted_stub()->mode(); |
| 341 int length = casted_stub()->length(); | 345 int length = casted_stub()->length(); |
| 342 | 346 |
| 343 HInstruction* allocation_site = Add<HLoadKeyed>(GetParameter(0), | 347 HInstruction* allocation_site = Add<HLoadKeyed>(GetParameter(0), |
| 344 GetParameter(1), | 348 GetParameter(1), |
| 345 static_cast<HValue*>(NULL), | 349 static_cast<HValue*>(NULL), |
| 346 FAST_ELEMENTS); | 350 FAST_ELEMENTS); |
| 347 IfBuilder checker(this); | 351 IfBuilder checker(this); |
| 348 checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site, | 352 checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site, |
| 349 undefined); | 353 undefined); |
| 350 checker.Then(); | 354 checker.Then(); |
| 351 | 355 |
| 352 HObjectAccess access = HObjectAccess::ForAllocationSiteOffset( | 356 HObjectAccess access = HObjectAccess::ForAllocationSiteOffset( |
| 353 AllocationSite::kTransitionInfoOffset); | 357 AllocationSite::kTransitionInfoOffset); |
| 354 HInstruction* boilerplate = Add<HLoadNamedField>(allocation_site, access); | 358 HInstruction* boilerplate = Add<HLoadNamedField>( |
| 359 allocation_site, static_cast<HValue*>(NULL), access); |
| 355 HValue* push_value; | 360 HValue* push_value; |
| 356 if (mode == FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS) { | 361 if (mode == FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS) { |
| 357 HValue* elements = AddLoadElements(boilerplate); | 362 HValue* elements = AddLoadElements(boilerplate); |
| 358 | 363 |
| 359 IfBuilder if_fixed_cow(this); | 364 IfBuilder if_fixed_cow(this); |
| 360 if_fixed_cow.If<HCompareMap>(elements, factory->fixed_cow_array_map()); | 365 if_fixed_cow.If<HCompareMap>(elements, factory->fixed_cow_array_map()); |
| 361 if_fixed_cow.Then(); | 366 if_fixed_cow.Then(); |
| 362 push_value = BuildCloneShallowArray(boilerplate, | 367 push_value = BuildCloneShallowArray(boilerplate, |
| 363 allocation_site, | 368 allocation_site, |
| 364 alloc_site_mode, | 369 alloc_site_mode, |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 static_cast<HValue*>(NULL), | 419 static_cast<HValue*>(NULL), |
| 415 FAST_ELEMENTS); | 420 FAST_ELEMENTS); |
| 416 | 421 |
| 417 IfBuilder checker(this); | 422 IfBuilder checker(this); |
| 418 checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site, | 423 checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site, |
| 419 undefined); | 424 undefined); |
| 420 checker.And(); | 425 checker.And(); |
| 421 | 426 |
| 422 HObjectAccess access = HObjectAccess::ForAllocationSiteOffset( | 427 HObjectAccess access = HObjectAccess::ForAllocationSiteOffset( |
| 423 AllocationSite::kTransitionInfoOffset); | 428 AllocationSite::kTransitionInfoOffset); |
| 424 HInstruction* boilerplate = Add<HLoadNamedField>(allocation_site, access); | 429 HInstruction* boilerplate = Add<HLoadNamedField>( |
| 430 allocation_site, static_cast<HValue*>(NULL), access); |
| 425 | 431 |
| 426 int size = JSObject::kHeaderSize + casted_stub()->length() * kPointerSize; | 432 int size = JSObject::kHeaderSize + casted_stub()->length() * kPointerSize; |
| 427 int object_size = size; | 433 int object_size = size; |
| 428 if (FLAG_allocation_site_pretenuring) { | 434 if (FLAG_allocation_site_pretenuring) { |
| 429 size += AllocationMemento::kSize; | 435 size += AllocationMemento::kSize; |
| 430 } | 436 } |
| 431 | 437 |
| 432 HValue* boilerplate_map = Add<HLoadNamedField>( | 438 HValue* boilerplate_map = Add<HLoadNamedField>( |
| 433 boilerplate, HObjectAccess::ForMap()); | 439 boilerplate, static_cast<HValue*>(NULL), |
| 440 HObjectAccess::ForMap()); |
| 434 HValue* boilerplate_size = Add<HLoadNamedField>( | 441 HValue* boilerplate_size = Add<HLoadNamedField>( |
| 435 boilerplate_map, HObjectAccess::ForMapInstanceSize()); | 442 boilerplate_map, static_cast<HValue*>(NULL), |
| 443 HObjectAccess::ForMapInstanceSize()); |
| 436 HValue* size_in_words = Add<HConstant>(object_size >> kPointerSizeLog2); | 444 HValue* size_in_words = Add<HConstant>(object_size >> kPointerSizeLog2); |
| 437 checker.If<HCompareNumericAndBranch>(boilerplate_size, | 445 checker.If<HCompareNumericAndBranch>(boilerplate_size, |
| 438 size_in_words, Token::EQ); | 446 size_in_words, Token::EQ); |
| 439 checker.Then(); | 447 checker.Then(); |
| 440 | 448 |
| 441 HValue* size_in_bytes = Add<HConstant>(size); | 449 HValue* size_in_bytes = Add<HConstant>(size); |
| 442 | 450 |
| 443 HInstruction* object = Add<HAllocate>(size_in_bytes, HType::JSObject(), | 451 HInstruction* object = Add<HAllocate>(size_in_bytes, HType::JSObject(), |
| 444 NOT_TENURED, JS_OBJECT_TYPE); | 452 NOT_TENURED, JS_OBJECT_TYPE); |
| 445 | 453 |
| 446 for (int i = 0; i < object_size; i += kPointerSize) { | 454 for (int i = 0; i < object_size; i += kPointerSize) { |
| 447 HObjectAccess access = HObjectAccess::ForJSObjectOffset(i); | 455 HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset(i); |
| 448 Add<HStoreNamedField>(object, access, | 456 Add<HStoreNamedField>( |
| 449 Add<HLoadNamedField>(boilerplate, access)); | 457 object, access, Add<HLoadNamedField>( |
| 458 boilerplate, static_cast<HValue*>(NULL), access)); |
| 450 } | 459 } |
| 451 | 460 |
| 452 ASSERT(FLAG_allocation_site_pretenuring || (size == object_size)); | 461 ASSERT(FLAG_allocation_site_pretenuring || (size == object_size)); |
| 453 if (FLAG_allocation_site_pretenuring) { | 462 if (FLAG_allocation_site_pretenuring) { |
| 454 BuildCreateAllocationMemento( | 463 BuildCreateAllocationMemento( |
| 455 object, Add<HConstant>(object_size), allocation_site); | 464 object, Add<HConstant>(object_size), allocation_site); |
| 456 } | 465 } |
| 457 | 466 |
| 458 environment()->Push(object); | 467 environment()->Push(object); |
| 459 checker.ElseDeopt("Uninitialized boilerplate in fast clone"); | 468 checker.ElseDeopt("Uninitialized boilerplate in fast clone"); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 508 Add<HConstant>(isolate()->factory()->empty_fixed_array()); | 517 Add<HConstant>(isolate()->factory()->empty_fixed_array()); |
| 509 HStoreNamedField* store = Add<HStoreNamedField>( | 518 HStoreNamedField* store = Add<HStoreNamedField>( |
| 510 object, | 519 object, |
| 511 HObjectAccess::ForAllocationSiteOffset( | 520 HObjectAccess::ForAllocationSiteOffset( |
| 512 AllocationSite::kDependentCodeOffset), | 521 AllocationSite::kDependentCodeOffset), |
| 513 empty_fixed_array); | 522 empty_fixed_array); |
| 514 | 523 |
| 515 // Link the object to the allocation site list | 524 // Link the object to the allocation site list |
| 516 HValue* site_list = Add<HConstant>( | 525 HValue* site_list = Add<HConstant>( |
| 517 ExternalReference::allocation_sites_list_address(isolate())); | 526 ExternalReference::allocation_sites_list_address(isolate())); |
| 518 HValue* site = Add<HLoadNamedField>(site_list, | 527 HValue* site = Add<HLoadNamedField>( |
| 519 HObjectAccess::ForAllocationSiteList()); | 528 site_list, static_cast<HValue*>(NULL), |
| 529 HObjectAccess::ForAllocationSiteList()); |
| 520 store = Add<HStoreNamedField>(object, | 530 store = Add<HStoreNamedField>(object, |
| 521 HObjectAccess::ForAllocationSiteOffset(AllocationSite::kWeakNextOffset), | 531 HObjectAccess::ForAllocationSiteOffset(AllocationSite::kWeakNextOffset), |
| 522 site); | 532 site); |
| 523 store->SkipWriteBarrier(); | 533 store->SkipWriteBarrier(); |
| 524 Add<HStoreNamedField>(site_list, HObjectAccess::ForAllocationSiteList(), | 534 Add<HStoreNamedField>(site_list, HObjectAccess::ForAllocationSiteList(), |
| 525 object); | 535 object); |
| 526 | 536 |
| 527 // We use a hammer (SkipWriteBarrier()) to indicate that we know the input | 537 HInstruction* feedback_vector = GetParameter(0); |
| 528 // cell is really a Cell, and so no write barrier is needed. | 538 HInstruction* slot = GetParameter(1); |
| 529 // TODO(mvstanton): Add a debug_code check to verify the input cell is really | 539 Add<HStoreKeyed>(feedback_vector, slot, object, FAST_ELEMENTS, |
| 530 // a cell. (perhaps with a new instruction, HAssert). | 540 INITIALIZING_STORE); |
| 531 HInstruction* cell = GetParameter(0); | 541 return feedback_vector; |
| 532 HObjectAccess access = HObjectAccess::ForCellValue(); | |
| 533 store = Add<HStoreNamedField>(cell, access, object); | |
| 534 store->SkipWriteBarrier(); | |
| 535 return cell; | |
| 536 } | 542 } |
| 537 | 543 |
| 538 | 544 |
| 539 Handle<Code> CreateAllocationSiteStub::GenerateCode(Isolate* isolate) { | 545 Handle<Code> CreateAllocationSiteStub::GenerateCode(Isolate* isolate) { |
| 540 return DoGenerateCode(isolate, this); | 546 return DoGenerateCode(isolate, this); |
| 541 } | 547 } |
| 542 | 548 |
| 543 | 549 |
| 544 template <> | 550 template <> |
| 545 HValue* CodeStubGraphBuilder<KeyedLoadFastElementStub>::BuildCodeStub() { | 551 HValue* CodeStubGraphBuilder<KeyedLoadFastElementStub>::BuildCodeStub() { |
| 546 HInstruction* load = BuildUncheckedMonomorphicElementAccess( | 552 HInstruction* load = BuildUncheckedMonomorphicElementAccess( |
| 547 GetParameter(0), GetParameter(1), NULL, | 553 GetParameter(0), GetParameter(1), NULL, |
| 548 casted_stub()->is_js_array(), casted_stub()->elements_kind(), | 554 casted_stub()->is_js_array(), casted_stub()->elements_kind(), |
| 549 false, NEVER_RETURN_HOLE, STANDARD_STORE); | 555 LOAD, NEVER_RETURN_HOLE, STANDARD_STORE); |
| 550 return load; | 556 return load; |
| 551 } | 557 } |
| 552 | 558 |
| 553 | 559 |
| 554 Handle<Code> KeyedLoadFastElementStub::GenerateCode(Isolate* isolate) { | 560 Handle<Code> KeyedLoadFastElementStub::GenerateCode(Isolate* isolate) { |
| 555 return DoGenerateCode(isolate, this); | 561 return DoGenerateCode(isolate, this); |
| 556 } | 562 } |
| 557 | 563 |
| 558 | 564 |
| 565 HLoadNamedField* CodeStubGraphBuilderBase::BuildLoadNamedField( |
| 566 HValue* object, |
| 567 Representation representation, |
| 568 int offset, |
| 569 bool is_inobject) { |
| 570 HObjectAccess access = is_inobject |
| 571 ? HObjectAccess::ForObservableJSObjectOffset(offset, representation) |
| 572 : HObjectAccess::ForBackingStoreOffset(offset, representation); |
| 573 if (representation.IsDouble()) { |
| 574 // Load the heap number. |
| 575 object = Add<HLoadNamedField>( |
| 576 object, static_cast<HValue*>(NULL), |
| 577 access.WithRepresentation(Representation::Tagged())); |
| 578 // Load the double value from it. |
| 579 access = HObjectAccess::ForHeapNumberValue(); |
| 580 } |
| 581 return Add<HLoadNamedField>(object, static_cast<HValue*>(NULL), access); |
| 582 } |
| 583 |
| 584 |
| 559 template<> | 585 template<> |
| 560 HValue* CodeStubGraphBuilder<LoadFieldStub>::BuildCodeStub() { | 586 HValue* CodeStubGraphBuilder<LoadFieldStub>::BuildCodeStub() { |
| 561 Representation rep = casted_stub()->representation(); | 587 return BuildLoadNamedField(GetParameter(0), |
| 562 HObjectAccess access = casted_stub()->is_inobject() ? | 588 casted_stub()->representation(), |
| 563 HObjectAccess::ForJSObjectOffset(casted_stub()->offset(), rep) : | 589 casted_stub()->offset(), |
| 564 HObjectAccess::ForBackingStoreOffset(casted_stub()->offset(), rep); | 590 casted_stub()->is_inobject()); |
| 565 return AddLoadNamedField(GetParameter(0), access); | |
| 566 } | 591 } |
| 567 | 592 |
| 568 | 593 |
| 569 Handle<Code> LoadFieldStub::GenerateCode(Isolate* isolate) { | 594 Handle<Code> LoadFieldStub::GenerateCode(Isolate* isolate) { |
| 570 return DoGenerateCode(isolate, this); | 595 return DoGenerateCode(isolate, this); |
| 571 } | 596 } |
| 572 | 597 |
| 573 | 598 |
| 574 template<> | 599 template<> |
| 575 HValue* CodeStubGraphBuilder<KeyedLoadFieldStub>::BuildCodeStub() { | 600 HValue* CodeStubGraphBuilder<KeyedLoadFieldStub>::BuildCodeStub() { |
| 576 Representation rep = casted_stub()->representation(); | 601 return BuildLoadNamedField(GetParameter(0), |
| 577 HObjectAccess access = casted_stub()->is_inobject() ? | 602 casted_stub()->representation(), |
| 578 HObjectAccess::ForJSObjectOffset(casted_stub()->offset(), rep) : | 603 casted_stub()->offset(), |
| 579 HObjectAccess::ForBackingStoreOffset(casted_stub()->offset(), rep); | 604 casted_stub()->is_inobject()); |
| 580 return AddLoadNamedField(GetParameter(0), access); | |
| 581 } | 605 } |
| 582 | 606 |
| 583 | 607 |
| 584 Handle<Code> KeyedLoadFieldStub::GenerateCode(Isolate* isolate) { | 608 Handle<Code> KeyedLoadFieldStub::GenerateCode(Isolate* isolate) { |
| 585 return DoGenerateCode(isolate, this); | 609 return DoGenerateCode(isolate, this); |
| 586 } | 610 } |
| 587 | 611 |
| 588 | 612 |
| 589 template<> | |
| 590 HValue* CodeStubGraphBuilder<KeyedArrayCallStub>::BuildCodeStub() { | |
| 591 int argc = casted_stub()->argc() + 1; | |
| 592 info()->set_parameter_count(argc); | |
| 593 | |
| 594 HValue* receiver = Add<HParameter>(1); | |
| 595 BuildCheckHeapObject(receiver); | |
| 596 | |
| 597 // Load the expected initial array map from the context. | |
| 598 JSArrayBuilder array_builder(this, casted_stub()->elements_kind()); | |
| 599 HValue* map = array_builder.EmitMapCode(); | |
| 600 | |
| 601 HValue* checked_receiver = Add<HCheckMapValue>(receiver, map); | |
| 602 | |
| 603 HValue* function = BuildUncheckedMonomorphicElementAccess( | |
| 604 checked_receiver, GetParameter(0), | |
| 605 NULL, true, casted_stub()->elements_kind(), | |
| 606 false, NEVER_RETURN_HOLE, STANDARD_STORE); | |
| 607 return Add<HCallFunction>(function, argc, TAIL_CALL); | |
| 608 } | |
| 609 | |
| 610 | |
| 611 Handle<Code> KeyedArrayCallStub::GenerateCode(Isolate* isolate) { | |
| 612 return DoGenerateCode(isolate, this); | |
| 613 } | |
| 614 | |
| 615 | |
| 616 template <> | 613 template <> |
| 617 HValue* CodeStubGraphBuilder<KeyedStoreFastElementStub>::BuildCodeStub() { | 614 HValue* CodeStubGraphBuilder<KeyedStoreFastElementStub>::BuildCodeStub() { |
| 618 BuildUncheckedMonomorphicElementAccess( | 615 BuildUncheckedMonomorphicElementAccess( |
| 619 GetParameter(0), GetParameter(1), GetParameter(2), | 616 GetParameter(0), GetParameter(1), GetParameter(2), |
| 620 casted_stub()->is_js_array(), casted_stub()->elements_kind(), | 617 casted_stub()->is_js_array(), casted_stub()->elements_kind(), |
| 621 true, NEVER_RETURN_HOLE, casted_stub()->store_mode()); | 618 STORE, NEVER_RETURN_HOLE, casted_stub()->store_mode()); |
| 622 | 619 |
| 623 return GetParameter(2); | 620 return GetParameter(2); |
| 624 } | 621 } |
| 625 | 622 |
| 626 | 623 |
| 627 Handle<Code> KeyedStoreFastElementStub::GenerateCode(Isolate* isolate) { | 624 Handle<Code> KeyedStoreFastElementStub::GenerateCode(Isolate* isolate) { |
| 628 return DoGenerateCode(isolate, this); | 625 return DoGenerateCode(isolate, this); |
| 629 } | 626 } |
| 630 | 627 |
| 631 | 628 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 645 | 642 |
| 646 Handle<Code> TransitionElementsKindStub::GenerateCode(Isolate* isolate) { | 643 Handle<Code> TransitionElementsKindStub::GenerateCode(Isolate* isolate) { |
| 647 return DoGenerateCode(isolate, this); | 644 return DoGenerateCode(isolate, this); |
| 648 } | 645 } |
| 649 | 646 |
| 650 HValue* CodeStubGraphBuilderBase::BuildArrayConstructor( | 647 HValue* CodeStubGraphBuilderBase::BuildArrayConstructor( |
| 651 ElementsKind kind, | 648 ElementsKind kind, |
| 652 AllocationSiteOverrideMode override_mode, | 649 AllocationSiteOverrideMode override_mode, |
| 653 ArgumentClass argument_class) { | 650 ArgumentClass argument_class) { |
| 654 HValue* constructor = GetParameter(ArrayConstructorStubBase::kConstructor); | 651 HValue* constructor = GetParameter(ArrayConstructorStubBase::kConstructor); |
| 655 HValue* property_cell = GetParameter(ArrayConstructorStubBase::kPropertyCell); | 652 HValue* alloc_site = GetParameter(ArrayConstructorStubBase::kAllocationSite); |
| 656 // Walk through the property cell to the AllocationSite | |
| 657 HValue* alloc_site = Add<HLoadNamedField>(property_cell, | |
| 658 HObjectAccess::ForCellValue()); | |
| 659 JSArrayBuilder array_builder(this, kind, alloc_site, constructor, | 653 JSArrayBuilder array_builder(this, kind, alloc_site, constructor, |
| 660 override_mode); | 654 override_mode); |
| 661 HValue* result = NULL; | 655 HValue* result = NULL; |
| 662 switch (argument_class) { | 656 switch (argument_class) { |
| 663 case NONE: | 657 case NONE: |
| 664 result = array_builder.AllocateEmptyArray(); | 658 result = array_builder.AllocateEmptyArray(); |
| 665 break; | 659 break; |
| 666 case SINGLE: | 660 case SINGLE: |
| 667 result = BuildArraySingleArgumentConstructor(&array_builder); | 661 result = BuildArraySingleArgumentConstructor(&array_builder); |
| 668 break; | 662 break; |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 837 return DoGenerateCode(isolate, this); | 831 return DoGenerateCode(isolate, this); |
| 838 } | 832 } |
| 839 | 833 |
| 840 | 834 |
| 841 template <> | 835 template <> |
| 842 HValue* CodeStubGraphBuilder<CompareNilICStub>::BuildCodeInitializedStub() { | 836 HValue* CodeStubGraphBuilder<CompareNilICStub>::BuildCodeInitializedStub() { |
| 843 Isolate* isolate = graph()->isolate(); | 837 Isolate* isolate = graph()->isolate(); |
| 844 CompareNilICStub* stub = casted_stub(); | 838 CompareNilICStub* stub = casted_stub(); |
| 845 HIfContinuation continuation; | 839 HIfContinuation continuation; |
| 846 Handle<Map> sentinel_map(isolate->heap()->meta_map()); | 840 Handle<Map> sentinel_map(isolate->heap()->meta_map()); |
| 847 Handle<Type> type = stub->GetType(isolate, sentinel_map); | 841 Type* type = stub->GetType(zone(), sentinel_map); |
| 848 BuildCompareNil(GetParameter(0), type, &continuation); | 842 BuildCompareNil(GetParameter(0), type, &continuation); |
| 849 IfBuilder if_nil(this, &continuation); | 843 IfBuilder if_nil(this, &continuation); |
| 850 if_nil.Then(); | 844 if_nil.Then(); |
| 851 if (continuation.IsFalseReachable()) { | 845 if (continuation.IsFalseReachable()) { |
| 852 if_nil.Else(); | 846 if_nil.Else(); |
| 853 if_nil.Return(graph()->GetConstant0()); | 847 if_nil.Return(graph()->GetConstant0()); |
| 854 } | 848 } |
| 855 if_nil.End(); | 849 if_nil.End(); |
| 856 return continuation.IsTrueReachable() | 850 return continuation.IsTrueReachable() |
| 857 ? graph()->GetConstant1() | 851 ? graph()->GetConstant1() |
| 858 : graph()->GetConstantUndefined(); | 852 : graph()->GetConstantUndefined(); |
| 859 } | 853 } |
| 860 | 854 |
| 861 | 855 |
| 862 Handle<Code> CompareNilICStub::GenerateCode(Isolate* isolate) { | 856 Handle<Code> CompareNilICStub::GenerateCode(Isolate* isolate) { |
| 863 return DoGenerateCode(isolate, this); | 857 return DoGenerateCode(isolate, this); |
| 864 } | 858 } |
| 865 | 859 |
| 866 | 860 |
| 867 template <> | 861 template <> |
| 868 HValue* CodeStubGraphBuilder<BinaryOpICStub>::BuildCodeInitializedStub() { | 862 HValue* CodeStubGraphBuilder<BinaryOpICStub>::BuildCodeInitializedStub() { |
| 869 BinaryOpIC::State state = casted_stub()->state(); | 863 BinaryOpIC::State state = casted_stub()->state(); |
| 870 | 864 |
| 871 HValue* left = GetParameter(BinaryOpICStub::kLeft); | 865 HValue* left = GetParameter(BinaryOpICStub::kLeft); |
| 872 HValue* right = GetParameter(BinaryOpICStub::kRight); | 866 HValue* right = GetParameter(BinaryOpICStub::kRight); |
| 873 | 867 |
| 874 Handle<Type> left_type = state.GetLeftType(isolate()); | 868 Type* left_type = state.GetLeftType(zone()); |
| 875 Handle<Type> right_type = state.GetRightType(isolate()); | 869 Type* right_type = state.GetRightType(zone()); |
| 876 Handle<Type> result_type = state.GetResultType(isolate()); | 870 Type* result_type = state.GetResultType(zone()); |
| 877 | 871 |
| 878 ASSERT(!left_type->Is(Type::None()) && !right_type->Is(Type::None()) && | 872 ASSERT(!left_type->Is(Type::None()) && !right_type->Is(Type::None()) && |
| 879 (state.HasSideEffects() || !result_type->Is(Type::None()))); | 873 (state.HasSideEffects() || !result_type->Is(Type::None()))); |
| 880 | 874 |
| 881 HValue* result = NULL; | 875 HValue* result = NULL; |
| 882 HAllocationMode allocation_mode(NOT_TENURED); | 876 HAllocationMode allocation_mode(NOT_TENURED); |
| 883 if (state.op() == Token::ADD && | 877 if (state.op() == Token::ADD && |
| 884 (left_type->Maybe(Type::String()) || right_type->Maybe(Type::String())) && | 878 (left_type->Maybe(Type::String()) || right_type->Maybe(Type::String())) && |
| 885 !left_type->Is(Type::String()) && !right_type->Is(Type::String())) { | 879 !left_type->Is(Type::String()) && !right_type->Is(Type::String())) { |
| 886 // For the generic add stub a fast case for string addition is performance | 880 // For the generic add stub a fast case for string addition is performance |
| 887 // critical. | 881 // critical. |
| 888 if (left_type->Maybe(Type::String())) { | 882 if (left_type->Maybe(Type::String())) { |
| 889 IfBuilder if_leftisstring(this); | 883 IfBuilder if_leftisstring(this); |
| 890 if_leftisstring.If<HIsStringAndBranch>(left); | 884 if_leftisstring.If<HIsStringAndBranch>(left); |
| 891 if_leftisstring.Then(); | 885 if_leftisstring.Then(); |
| 892 { | 886 { |
| 893 Push(BuildBinaryOperation( | 887 Push(BuildBinaryOperation( |
| 894 state.op(), left, right, | 888 state.op(), left, right, |
| 895 Type::String(isolate()), right_type, | 889 Type::String(zone()), right_type, |
| 896 result_type, state.fixed_right_arg(), | 890 result_type, state.fixed_right_arg(), |
| 897 allocation_mode)); | 891 allocation_mode)); |
| 898 } | 892 } |
| 899 if_leftisstring.Else(); | 893 if_leftisstring.Else(); |
| 900 { | 894 { |
| 901 Push(BuildBinaryOperation( | 895 Push(BuildBinaryOperation( |
| 902 state.op(), left, right, | 896 state.op(), left, right, |
| 903 left_type, right_type, result_type, | 897 left_type, right_type, result_type, |
| 904 state.fixed_right_arg(), allocation_mode)); | 898 state.fixed_right_arg(), allocation_mode)); |
| 905 } | 899 } |
| 906 if_leftisstring.End(); | 900 if_leftisstring.End(); |
| 907 result = Pop(); | 901 result = Pop(); |
| 908 } else { | 902 } else { |
| 909 IfBuilder if_rightisstring(this); | 903 IfBuilder if_rightisstring(this); |
| 910 if_rightisstring.If<HIsStringAndBranch>(right); | 904 if_rightisstring.If<HIsStringAndBranch>(right); |
| 911 if_rightisstring.Then(); | 905 if_rightisstring.Then(); |
| 912 { | 906 { |
| 913 Push(BuildBinaryOperation( | 907 Push(BuildBinaryOperation( |
| 914 state.op(), left, right, | 908 state.op(), left, right, |
| 915 left_type, Type::String(isolate()), | 909 left_type, Type::String(zone()), |
| 916 result_type, state.fixed_right_arg(), | 910 result_type, state.fixed_right_arg(), |
| 917 allocation_mode)); | 911 allocation_mode)); |
| 918 } | 912 } |
| 919 if_rightisstring.Else(); | 913 if_rightisstring.Else(); |
| 920 { | 914 { |
| 921 Push(BuildBinaryOperation( | 915 Push(BuildBinaryOperation( |
| 922 state.op(), left, right, | 916 state.op(), left, right, |
| 923 left_type, right_type, result_type, | 917 left_type, right_type, result_type, |
| 924 state.fixed_right_arg(), allocation_mode)); | 918 state.fixed_right_arg(), allocation_mode)); |
| 925 } | 919 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 979 | 973 |
| 980 template <> | 974 template <> |
| 981 HValue* CodeStubGraphBuilder<BinaryOpWithAllocationSiteStub>::BuildCodeStub() { | 975 HValue* CodeStubGraphBuilder<BinaryOpWithAllocationSiteStub>::BuildCodeStub() { |
| 982 BinaryOpIC::State state = casted_stub()->state(); | 976 BinaryOpIC::State state = casted_stub()->state(); |
| 983 | 977 |
| 984 HValue* allocation_site = GetParameter( | 978 HValue* allocation_site = GetParameter( |
| 985 BinaryOpWithAllocationSiteStub::kAllocationSite); | 979 BinaryOpWithAllocationSiteStub::kAllocationSite); |
| 986 HValue* left = GetParameter(BinaryOpWithAllocationSiteStub::kLeft); | 980 HValue* left = GetParameter(BinaryOpWithAllocationSiteStub::kLeft); |
| 987 HValue* right = GetParameter(BinaryOpWithAllocationSiteStub::kRight); | 981 HValue* right = GetParameter(BinaryOpWithAllocationSiteStub::kRight); |
| 988 | 982 |
| 989 Handle<Type> left_type = state.GetLeftType(isolate()); | 983 Type* left_type = state.GetLeftType(zone()); |
| 990 Handle<Type> right_type = state.GetRightType(isolate()); | 984 Type* right_type = state.GetRightType(zone()); |
| 991 Handle<Type> result_type = state.GetResultType(isolate()); | 985 Type* result_type = state.GetResultType(zone()); |
| 992 HAllocationMode allocation_mode(allocation_site); | 986 HAllocationMode allocation_mode(allocation_site); |
| 993 | 987 |
| 994 return BuildBinaryOperation(state.op(), left, right, | 988 return BuildBinaryOperation(state.op(), left, right, |
| 995 left_type, right_type, result_type, | 989 left_type, right_type, result_type, |
| 996 state.fixed_right_arg(), allocation_mode); | 990 state.fixed_right_arg(), allocation_mode); |
| 997 } | 991 } |
| 998 | 992 |
| 999 | 993 |
| 1000 Handle<Code> BinaryOpWithAllocationSiteStub::GenerateCode(Isolate* isolate) { | 994 Handle<Code> BinaryOpWithAllocationSiteStub::GenerateCode(Isolate* isolate) { |
| 1001 return DoGenerateCode(isolate, this); | 995 return DoGenerateCode(isolate, this); |
| 1002 } | 996 } |
| 1003 | 997 |
| 1004 | 998 |
| 1005 template <> | 999 template <> |
| 1006 HValue* CodeStubGraphBuilder<NewStringAddStub>::BuildCodeInitializedStub() { | 1000 HValue* CodeStubGraphBuilder<StringAddStub>::BuildCodeInitializedStub() { |
| 1007 NewStringAddStub* stub = casted_stub(); | 1001 StringAddStub* stub = casted_stub(); |
| 1008 StringAddFlags flags = stub->flags(); | 1002 StringAddFlags flags = stub->flags(); |
| 1009 PretenureFlag pretenure_flag = stub->pretenure_flag(); | 1003 PretenureFlag pretenure_flag = stub->pretenure_flag(); |
| 1010 | 1004 |
| 1011 HValue* left = GetParameter(NewStringAddStub::kLeft); | 1005 HValue* left = GetParameter(StringAddStub::kLeft); |
| 1012 HValue* right = GetParameter(NewStringAddStub::kRight); | 1006 HValue* right = GetParameter(StringAddStub::kRight); |
| 1013 | 1007 |
| 1014 // Make sure that both arguments are strings if not known in advance. | 1008 // Make sure that both arguments are strings if not known in advance. |
| 1015 if ((flags & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT) { | 1009 if ((flags & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT) { |
| 1016 left = BuildCheckString(left); | 1010 left = BuildCheckString(left); |
| 1017 } | 1011 } |
| 1018 if ((flags & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT) { | 1012 if ((flags & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT) { |
| 1019 right = BuildCheckString(right); | 1013 right = BuildCheckString(right); |
| 1020 } | 1014 } |
| 1021 | 1015 |
| 1022 return BuildStringAdd(left, right, HAllocationMode(pretenure_flag)); | 1016 return BuildStringAdd(left, right, HAllocationMode(pretenure_flag)); |
| 1023 } | 1017 } |
| 1024 | 1018 |
| 1025 | 1019 |
| 1026 Handle<Code> NewStringAddStub::GenerateCode(Isolate* isolate) { | 1020 Handle<Code> StringAddStub::GenerateCode(Isolate* isolate) { |
| 1027 return DoGenerateCode(isolate, this); | 1021 return DoGenerateCode(isolate, this); |
| 1028 } | 1022 } |
| 1029 | 1023 |
| 1030 | 1024 |
| 1031 template <> | 1025 template <> |
| 1032 HValue* CodeStubGraphBuilder<ToBooleanStub>::BuildCodeInitializedStub() { | 1026 HValue* CodeStubGraphBuilder<ToBooleanStub>::BuildCodeInitializedStub() { |
| 1033 ToBooleanStub* stub = casted_stub(); | 1027 ToBooleanStub* stub = casted_stub(); |
| 1034 | 1028 |
| 1035 IfBuilder if_true(this); | 1029 IfBuilder if_true(this); |
| 1036 if_true.If<HBranch>(GetParameter(0), stub->GetTypes()); | 1030 if_true.If<HBranch>(GetParameter(0), stub->GetTypes()); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1058 HParameter* receiver = GetParameter(0); | 1052 HParameter* receiver = GetParameter(0); |
| 1059 HParameter* value = GetParameter(2); | 1053 HParameter* value = GetParameter(2); |
| 1060 | 1054 |
| 1061 // Check that the map of the global has not changed: use a placeholder map | 1055 // Check that the map of the global has not changed: use a placeholder map |
| 1062 // that will be replaced later with the global object's map. | 1056 // that will be replaced later with the global object's map. |
| 1063 Handle<Map> placeholder_map = isolate()->factory()->meta_map(); | 1057 Handle<Map> placeholder_map = isolate()->factory()->meta_map(); |
| 1064 Add<HCheckMaps>(receiver, placeholder_map, top_info()); | 1058 Add<HCheckMaps>(receiver, placeholder_map, top_info()); |
| 1065 | 1059 |
| 1066 HValue* cell = Add<HConstant>(placeholder_cell); | 1060 HValue* cell = Add<HConstant>(placeholder_cell); |
| 1067 HObjectAccess access(HObjectAccess::ForCellPayload(isolate())); | 1061 HObjectAccess access(HObjectAccess::ForCellPayload(isolate())); |
| 1068 HValue* cell_contents = Add<HLoadNamedField>(cell, access); | 1062 HValue* cell_contents = Add<HLoadNamedField>( |
| 1063 cell, static_cast<HValue*>(NULL), access); |
| 1069 | 1064 |
| 1070 if (stub->is_constant()) { | 1065 if (stub->is_constant()) { |
| 1071 IfBuilder builder(this); | 1066 IfBuilder builder(this); |
| 1072 builder.If<HCompareObjectEqAndBranch>(cell_contents, value); | 1067 builder.If<HCompareObjectEqAndBranch>(cell_contents, value); |
| 1073 builder.Then(); | 1068 builder.Then(); |
| 1074 builder.ElseDeopt("Unexpected cell contents in constant global store"); | 1069 builder.ElseDeopt("Unexpected cell contents in constant global store"); |
| 1075 builder.End(); | 1070 builder.End(); |
| 1076 } else { | 1071 } else { |
| 1077 // Load the payload of the global parameter cell. A hole indicates that the | 1072 // Load the payload of the global parameter cell. A hole indicates that the |
| 1078 // property has been deleted and that the store must be handled by the | 1073 // property has been deleted and that the store must be handled by the |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1110 info()->MarkAsSavesCallerDoubles(); | 1105 info()->MarkAsSavesCallerDoubles(); |
| 1111 | 1106 |
| 1112 BuildTransitionElementsKind(object, map, | 1107 BuildTransitionElementsKind(object, map, |
| 1113 casted_stub()->from_kind(), | 1108 casted_stub()->from_kind(), |
| 1114 casted_stub()->to_kind(), | 1109 casted_stub()->to_kind(), |
| 1115 casted_stub()->is_jsarray()); | 1110 casted_stub()->is_jsarray()); |
| 1116 | 1111 |
| 1117 BuildUncheckedMonomorphicElementAccess(object, key, value, | 1112 BuildUncheckedMonomorphicElementAccess(object, key, value, |
| 1118 casted_stub()->is_jsarray(), | 1113 casted_stub()->is_jsarray(), |
| 1119 casted_stub()->to_kind(), | 1114 casted_stub()->to_kind(), |
| 1120 true, ALLOW_RETURN_HOLE, | 1115 STORE, ALLOW_RETURN_HOLE, |
| 1121 casted_stub()->store_mode()); | 1116 casted_stub()->store_mode()); |
| 1122 } | 1117 } |
| 1123 | 1118 |
| 1124 return value; | 1119 return value; |
| 1125 } | 1120 } |
| 1126 | 1121 |
| 1127 | 1122 |
| 1128 Handle<Code> ElementsTransitionAndStoreStub::GenerateCode(Isolate* isolate) { | 1123 Handle<Code> ElementsTransitionAndStoreStub::GenerateCode(Isolate* isolate) { |
| 1129 return DoGenerateCode(isolate, this); | 1124 return DoGenerateCode(isolate, this); |
| 1130 } | 1125 } |
| 1131 | 1126 |
| 1132 | 1127 |
| 1133 void CodeStubGraphBuilderBase::BuildInstallOptimizedCode( | 1128 void CodeStubGraphBuilderBase::BuildInstallOptimizedCode( |
| 1134 HValue* js_function, | 1129 HValue* js_function, |
| 1135 HValue* native_context, | 1130 HValue* native_context, |
| 1136 HValue* code_object) { | 1131 HValue* code_object) { |
| 1137 Counters* counters = isolate()->counters(); | 1132 Counters* counters = isolate()->counters(); |
| 1138 AddIncrementCounter(counters->fast_new_closure_install_optimized()); | 1133 AddIncrementCounter(counters->fast_new_closure_install_optimized()); |
| 1139 | 1134 |
| 1140 // TODO(fschneider): Idea: store proper code pointers in the optimized code | 1135 // TODO(fschneider): Idea: store proper code pointers in the optimized code |
| 1141 // map and either unmangle them on marking or do nothing as the whole map is | 1136 // map and either unmangle them on marking or do nothing as the whole map is |
| 1142 // discarded on major GC anyway. | 1137 // discarded on major GC anyway. |
| 1143 Add<HStoreCodeEntry>(js_function, code_object); | 1138 Add<HStoreCodeEntry>(js_function, code_object); |
| 1144 | 1139 |
| 1145 // Now link a function into a list of optimized functions. | 1140 // Now link a function into a list of optimized functions. |
| 1146 HValue* optimized_functions_list = Add<HLoadNamedField>(native_context, | 1141 HValue* optimized_functions_list = Add<HLoadNamedField>( |
| 1142 native_context, static_cast<HValue*>(NULL), |
| 1147 HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST)); | 1143 HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST)); |
| 1148 Add<HStoreNamedField>(js_function, | 1144 Add<HStoreNamedField>(js_function, |
| 1149 HObjectAccess::ForNextFunctionLinkPointer(), | 1145 HObjectAccess::ForNextFunctionLinkPointer(), |
| 1150 optimized_functions_list); | 1146 optimized_functions_list); |
| 1151 | 1147 |
| 1152 // This store is the only one that should have a write barrier. | 1148 // This store is the only one that should have a write barrier. |
| 1153 Add<HStoreNamedField>(native_context, | 1149 Add<HStoreNamedField>(native_context, |
| 1154 HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST), | 1150 HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST), |
| 1155 js_function); | 1151 js_function); |
| 1156 } | 1152 } |
| 1157 | 1153 |
| 1158 | 1154 |
| 1159 void CodeStubGraphBuilderBase::BuildInstallCode(HValue* js_function, | 1155 void CodeStubGraphBuilderBase::BuildInstallCode(HValue* js_function, |
| 1160 HValue* shared_info) { | 1156 HValue* shared_info) { |
| 1161 Add<HStoreNamedField>(js_function, | 1157 Add<HStoreNamedField>(js_function, |
| 1162 HObjectAccess::ForNextFunctionLinkPointer(), | 1158 HObjectAccess::ForNextFunctionLinkPointer(), |
| 1163 graph()->GetConstantUndefined()); | 1159 graph()->GetConstantUndefined()); |
| 1164 HValue* code_object = Add<HLoadNamedField>(shared_info, | 1160 HValue* code_object = Add<HLoadNamedField>( |
| 1165 HObjectAccess::ForCodeOffset()); | 1161 shared_info, static_cast<HValue*>(NULL), HObjectAccess::ForCodeOffset()); |
| 1166 Add<HStoreCodeEntry>(js_function, code_object); | 1162 Add<HStoreCodeEntry>(js_function, code_object); |
| 1167 } | 1163 } |
| 1168 | 1164 |
| 1169 | 1165 |
| 1170 void CodeStubGraphBuilderBase::BuildInstallFromOptimizedCodeMap( | 1166 void CodeStubGraphBuilderBase::BuildInstallFromOptimizedCodeMap( |
| 1171 HValue* js_function, | 1167 HValue* js_function, |
| 1172 HValue* shared_info, | 1168 HValue* shared_info, |
| 1173 HValue* native_context) { | 1169 HValue* native_context) { |
| 1174 Counters* counters = isolate()->counters(); | 1170 Counters* counters = isolate()->counters(); |
| 1175 IfBuilder is_optimized(this); | 1171 IfBuilder is_optimized(this); |
| 1176 HInstruction* optimized_map = Add<HLoadNamedField>(shared_info, | 1172 HInstruction* optimized_map = Add<HLoadNamedField>( |
| 1173 shared_info, static_cast<HValue*>(NULL), |
| 1177 HObjectAccess::ForOptimizedCodeMap()); | 1174 HObjectAccess::ForOptimizedCodeMap()); |
| 1178 HValue* null_constant = Add<HConstant>(0); | 1175 HValue* null_constant = Add<HConstant>(0); |
| 1179 is_optimized.If<HCompareObjectEqAndBranch>(optimized_map, null_constant); | 1176 is_optimized.If<HCompareObjectEqAndBranch>(optimized_map, null_constant); |
| 1180 is_optimized.Then(); | 1177 is_optimized.Then(); |
| 1181 { | 1178 { |
| 1182 BuildInstallCode(js_function, shared_info); | 1179 BuildInstallCode(js_function, shared_info); |
| 1183 } | 1180 } |
| 1184 is_optimized.Else(); | 1181 is_optimized.Else(); |
| 1185 { | 1182 { |
| 1186 AddIncrementCounter(counters->fast_new_closure_try_optimized()); | 1183 AddIncrementCounter(counters->fast_new_closure_try_optimized()); |
| 1187 // optimized_map points to fixed array of 3-element entries | 1184 // optimized_map points to fixed array of 3-element entries |
| 1188 // (native context, optimized code, literals). | 1185 // (native context, optimized code, literals). |
| 1189 // Map must never be empty, so check the first elements. | 1186 // Map must never be empty, so check the first elements. |
| 1190 Label install_optimized; | 1187 Label install_optimized; |
| 1191 HValue* first_context_slot = Add<HLoadNamedField>(optimized_map, | 1188 HValue* first_context_slot = Add<HLoadNamedField>( |
| 1189 optimized_map, static_cast<HValue*>(NULL), |
| 1192 HObjectAccess::ForFirstContextSlot()); | 1190 HObjectAccess::ForFirstContextSlot()); |
| 1193 HValue* first_osr_ast_slot = Add<HLoadNamedField>(optimized_map, | 1191 HValue* first_osr_ast_slot = Add<HLoadNamedField>( |
| 1192 optimized_map, static_cast<HValue*>(NULL), |
| 1194 HObjectAccess::ForFirstOsrAstIdSlot()); | 1193 HObjectAccess::ForFirstOsrAstIdSlot()); |
| 1195 HValue* osr_ast_id_none = Add<HConstant>(BailoutId::None().ToInt()); | 1194 HValue* osr_ast_id_none = Add<HConstant>(BailoutId::None().ToInt()); |
| 1196 IfBuilder already_in(this); | 1195 IfBuilder already_in(this); |
| 1197 already_in.If<HCompareObjectEqAndBranch>(native_context, | 1196 already_in.If<HCompareObjectEqAndBranch>(native_context, |
| 1198 first_context_slot); | 1197 first_context_slot); |
| 1199 already_in.AndIf<HCompareObjectEqAndBranch>(first_osr_ast_slot, | 1198 already_in.AndIf<HCompareObjectEqAndBranch>(first_osr_ast_slot, |
| 1200 osr_ast_id_none); | 1199 osr_ast_id_none); |
| 1201 already_in.Then(); | 1200 already_in.Then(); |
| 1202 { | 1201 { |
| 1203 HValue* code_object = Add<HLoadNamedField>(optimized_map, | 1202 HValue* code_object = Add<HLoadNamedField>( |
| 1204 HObjectAccess::ForFirstCodeSlot()); | 1203 optimized_map, static_cast<HValue*>(NULL), |
| 1204 HObjectAccess::ForFirstCodeSlot()); |
| 1205 BuildInstallOptimizedCode(js_function, native_context, code_object); | 1205 BuildInstallOptimizedCode(js_function, native_context, code_object); |
| 1206 } | 1206 } |
| 1207 already_in.Else(); | 1207 already_in.Else(); |
| 1208 { | 1208 { |
| 1209 HValue* shared_function_entry_length = | 1209 HValue* shared_function_entry_length = |
| 1210 Add<HConstant>(SharedFunctionInfo::kEntryLength); | 1210 Add<HConstant>(SharedFunctionInfo::kEntryLength); |
| 1211 LoopBuilder loop_builder(this, | 1211 LoopBuilder loop_builder(this, |
| 1212 context(), | 1212 context(), |
| 1213 LoopBuilder::kPostDecrement, | 1213 LoopBuilder::kPostDecrement, |
| 1214 shared_function_entry_length); | 1214 shared_function_entry_length); |
| 1215 HValue* array_length = Add<HLoadNamedField>(optimized_map, | 1215 HValue* array_length = Add<HLoadNamedField>( |
| 1216 optimized_map, static_cast<HValue*>(NULL), |
| 1216 HObjectAccess::ForFixedArrayLength()); | 1217 HObjectAccess::ForFixedArrayLength()); |
| 1217 HValue* slot_iterator = loop_builder.BeginBody(array_length, | 1218 HValue* slot_iterator = loop_builder.BeginBody(array_length, |
| 1218 graph()->GetConstant0(), | 1219 graph()->GetConstant0(), |
| 1219 Token::GT); | 1220 Token::GT); |
| 1220 { | 1221 { |
| 1221 // Iterate through the rest of map backwards. | 1222 // Iterate through the rest of map backwards. |
| 1222 // Do not double check first entry. | 1223 // Do not double check first entry. |
| 1223 HValue* second_entry_index = | 1224 HValue* second_entry_index = |
| 1224 Add<HConstant>(SharedFunctionInfo::kSecondEntryIndex); | 1225 Add<HConstant>(SharedFunctionInfo::kSecondEntryIndex); |
| 1225 IfBuilder restore_check(this); | 1226 IfBuilder restore_check(this); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1288 HValue* size = Add<HConstant>(JSFunction::kSize); | 1289 HValue* size = Add<HConstant>(JSFunction::kSize); |
| 1289 HInstruction* js_function = Add<HAllocate>(size, HType::JSObject(), | 1290 HInstruction* js_function = Add<HAllocate>(size, HType::JSObject(), |
| 1290 NOT_TENURED, JS_FUNCTION_TYPE); | 1291 NOT_TENURED, JS_FUNCTION_TYPE); |
| 1291 | 1292 |
| 1292 int map_index = Context::FunctionMapIndex(casted_stub()->language_mode(), | 1293 int map_index = Context::FunctionMapIndex(casted_stub()->language_mode(), |
| 1293 casted_stub()->is_generator()); | 1294 casted_stub()->is_generator()); |
| 1294 | 1295 |
| 1295 // Compute the function map in the current native context and set that | 1296 // Compute the function map in the current native context and set that |
| 1296 // as the map of the allocated object. | 1297 // as the map of the allocated object. |
| 1297 HInstruction* native_context = BuildGetNativeContext(); | 1298 HInstruction* native_context = BuildGetNativeContext(); |
| 1298 HInstruction* map_slot_value = Add<HLoadNamedField>(native_context, | 1299 HInstruction* map_slot_value = Add<HLoadNamedField>( |
| 1300 native_context, static_cast<HValue*>(NULL), |
| 1299 HObjectAccess::ForContextSlot(map_index)); | 1301 HObjectAccess::ForContextSlot(map_index)); |
| 1300 Add<HStoreNamedField>(js_function, HObjectAccess::ForMap(), map_slot_value); | 1302 Add<HStoreNamedField>(js_function, HObjectAccess::ForMap(), map_slot_value); |
| 1301 | 1303 |
| 1302 // Initialize the rest of the function. | 1304 // Initialize the rest of the function. |
| 1303 Add<HStoreNamedField>(js_function, HObjectAccess::ForPropertiesPointer(), | 1305 Add<HStoreNamedField>(js_function, HObjectAccess::ForPropertiesPointer(), |
| 1304 empty_fixed_array); | 1306 empty_fixed_array); |
| 1305 Add<HStoreNamedField>(js_function, HObjectAccess::ForElementsPointer(), | 1307 Add<HStoreNamedField>(js_function, HObjectAccess::ForElementsPointer(), |
| 1306 empty_fixed_array); | 1308 empty_fixed_array); |
| 1307 Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(), | 1309 Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(), |
| 1308 empty_fixed_array); | 1310 empty_fixed_array); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1326 return js_function; | 1328 return js_function; |
| 1327 } | 1329 } |
| 1328 | 1330 |
| 1329 | 1331 |
| 1330 Handle<Code> FastNewClosureStub::GenerateCode(Isolate* isolate) { | 1332 Handle<Code> FastNewClosureStub::GenerateCode(Isolate* isolate) { |
| 1331 return DoGenerateCode(isolate, this); | 1333 return DoGenerateCode(isolate, this); |
| 1332 } | 1334 } |
| 1333 | 1335 |
| 1334 | 1336 |
| 1335 template<> | 1337 template<> |
| 1338 HValue* CodeStubGraphBuilder<FastNewContextStub>::BuildCodeStub() { |
| 1339 int length = casted_stub()->slots() + Context::MIN_CONTEXT_SLOTS; |
| 1340 |
| 1341 // Get the function. |
| 1342 HParameter* function = GetParameter(FastNewContextStub::kFunction); |
| 1343 |
| 1344 // Allocate the context in new space. |
| 1345 HAllocate* function_context = Add<HAllocate>( |
| 1346 Add<HConstant>(length * kPointerSize + FixedArray::kHeaderSize), |
| 1347 HType::Tagged(), NOT_TENURED, FIXED_ARRAY_TYPE); |
| 1348 |
| 1349 // Set up the object header. |
| 1350 AddStoreMapConstant(function_context, |
| 1351 isolate()->factory()->function_context_map()); |
| 1352 Add<HStoreNamedField>(function_context, |
| 1353 HObjectAccess::ForFixedArrayLength(), |
| 1354 Add<HConstant>(length)); |
| 1355 |
| 1356 // Set up the fixed slots. |
| 1357 Add<HStoreNamedField>(function_context, |
| 1358 HObjectAccess::ForContextSlot(Context::CLOSURE_INDEX), |
| 1359 function); |
| 1360 Add<HStoreNamedField>(function_context, |
| 1361 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX), |
| 1362 context()); |
| 1363 Add<HStoreNamedField>(function_context, |
| 1364 HObjectAccess::ForContextSlot(Context::EXTENSION_INDEX), |
| 1365 graph()->GetConstant0()); |
| 1366 |
| 1367 // Copy the global object from the previous context. |
| 1368 HValue* global_object = Add<HLoadNamedField>( |
| 1369 context(), static_cast<HValue*>(NULL), |
| 1370 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
| 1371 Add<HStoreNamedField>(function_context, |
| 1372 HObjectAccess::ForContextSlot( |
| 1373 Context::GLOBAL_OBJECT_INDEX), |
| 1374 global_object); |
| 1375 |
| 1376 // Initialize the rest of the slots to undefined. |
| 1377 for (int i = Context::MIN_CONTEXT_SLOTS; i < length; ++i) { |
| 1378 Add<HStoreNamedField>(function_context, |
| 1379 HObjectAccess::ForContextSlot(i), |
| 1380 graph()->GetConstantUndefined()); |
| 1381 } |
| 1382 |
| 1383 return function_context; |
| 1384 } |
| 1385 |
| 1386 |
| 1387 Handle<Code> FastNewContextStub::GenerateCode(Isolate* isolate) { |
| 1388 return DoGenerateCode(isolate, this); |
| 1389 } |
| 1390 |
| 1391 |
| 1392 template<> |
| 1336 HValue* CodeStubGraphBuilder<KeyedLoadDictionaryElementStub>::BuildCodeStub() { | 1393 HValue* CodeStubGraphBuilder<KeyedLoadDictionaryElementStub>::BuildCodeStub() { |
| 1337 HValue* receiver = GetParameter(0); | 1394 HValue* receiver = GetParameter(0); |
| 1338 HValue* key = GetParameter(1); | 1395 HValue* key = GetParameter(1); |
| 1339 | 1396 |
| 1340 Add<HCheckSmi>(key); | 1397 Add<HCheckSmi>(key); |
| 1341 | 1398 |
| 1342 return BuildUncheckedDictionaryElementLoad(receiver, key); | 1399 return BuildUncheckedDictionaryElementLoad(receiver, key); |
| 1343 } | 1400 } |
| 1344 | 1401 |
| 1345 | 1402 |
| 1346 Handle<Code> KeyedLoadDictionaryElementStub::GenerateCode(Isolate* isolate) { | 1403 Handle<Code> KeyedLoadDictionaryElementStub::GenerateCode(Isolate* isolate) { |
| 1347 return DoGenerateCode(isolate, this); | 1404 return DoGenerateCode(isolate, this); |
| 1348 } | 1405 } |
| 1349 | 1406 |
| 1350 | 1407 |
| 1408 template<> |
| 1409 HValue* CodeStubGraphBuilder<RegExpConstructResultStub>::BuildCodeStub() { |
| 1410 // Determine the parameters. |
| 1411 HValue* length = GetParameter(RegExpConstructResultStub::kLength); |
| 1412 HValue* index = GetParameter(RegExpConstructResultStub::kIndex); |
| 1413 HValue* input = GetParameter(RegExpConstructResultStub::kInput); |
| 1414 |
| 1415 return BuildRegExpConstructResult(length, index, input); |
| 1416 } |
| 1417 |
| 1418 |
| 1419 Handle<Code> RegExpConstructResultStub::GenerateCode(Isolate* isolate) { |
| 1420 return DoGenerateCode(isolate, this); |
| 1421 } |
| 1422 |
| 1423 |
| 1351 } } // namespace v8::internal | 1424 } } // namespace v8::internal |
| OLD | NEW |