| 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 | |
| 89 enum ArgumentClass { | 84 enum ArgumentClass { |
| 90 NONE, | 85 NONE, |
| 91 SINGLE, | 86 SINGLE, |
| 92 MULTIPLE | 87 MULTIPLE |
| 93 }; | 88 }; |
| 94 | 89 |
| 95 HValue* BuildArrayConstructor(ElementsKind kind, | 90 HValue* BuildArrayConstructor(ElementsKind kind, |
| 96 AllocationSiteOverrideMode override_mode, | 91 AllocationSiteOverrideMode override_mode, |
| 97 ArgumentClass argument_class); | 92 ArgumentClass argument_class); |
| 98 HValue* BuildInternalArrayConstructor(ElementsKind kind, | 93 HValue* BuildInternalArrayConstructor(ElementsKind kind, |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 | 240 |
| 246 // Create the code object. | 241 // Create the code object. |
| 247 CodeDesc desc; | 242 CodeDesc desc; |
| 248 masm.GetCode(&desc); | 243 masm.GetCode(&desc); |
| 249 | 244 |
| 250 // Copy the generated code into a heap object. | 245 // Copy the generated code into a heap object. |
| 251 Code::Flags flags = Code::ComputeFlags( | 246 Code::Flags flags = Code::ComputeFlags( |
| 252 GetCodeKind(), | 247 GetCodeKind(), |
| 253 GetICState(), | 248 GetICState(), |
| 254 GetExtraICState(), | 249 GetExtraICState(), |
| 255 GetStubType()); | 250 GetStubType(), |
| 251 GetStubFlags()); |
| 256 Handle<Code> new_object = factory->NewCode( | 252 Handle<Code> new_object = factory->NewCode( |
| 257 desc, flags, masm.CodeObject(), NeedsImmovableCode()); | 253 desc, flags, masm.CodeObject(), NeedsImmovableCode()); |
| 258 return new_object; | 254 return new_object; |
| 259 } | 255 } |
| 260 | 256 |
| 261 | 257 |
| 262 template <class Stub> | 258 template <class Stub> |
| 263 static Handle<Code> DoGenerateCode(Isolate* isolate, Stub* stub) { | 259 static Handle<Code> DoGenerateCode(Isolate* isolate, Stub* stub) { |
| 264 CodeStub::Major major_key = | 260 CodeStub::Major major_key = |
| 265 static_cast<HydrogenCodeStub*>(stub)->MajorKey(); | 261 static_cast<HydrogenCodeStub*>(stub)->MajorKey(); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 292 } | 288 } |
| 293 | 289 |
| 294 | 290 |
| 295 template <> | 291 template <> |
| 296 HValue* CodeStubGraphBuilder<ToNumberStub>::BuildCodeStub() { | 292 HValue* CodeStubGraphBuilder<ToNumberStub>::BuildCodeStub() { |
| 297 HValue* value = GetParameter(0); | 293 HValue* value = GetParameter(0); |
| 298 | 294 |
| 299 // Check if the parameter is already a SMI or heap number. | 295 // Check if the parameter is already a SMI or heap number. |
| 300 IfBuilder if_number(this); | 296 IfBuilder if_number(this); |
| 301 if_number.If<HIsSmiAndBranch>(value); | 297 if_number.If<HIsSmiAndBranch>(value); |
| 302 if_number.OrIf<HCompareMap>(value, isolate()->factory()->heap_number_map(), | 298 if_number.OrIf<HCompareMap>(value, isolate()->factory()->heap_number_map()); |
| 303 top_info()); | |
| 304 if_number.Then(); | 299 if_number.Then(); |
| 305 | 300 |
| 306 // Return the number. | 301 // Return the number. |
| 307 Push(value); | 302 Push(value); |
| 308 | 303 |
| 309 if_number.Else(); | 304 if_number.Else(); |
| 310 | 305 |
| 311 // Convert the parameter to number using the builtin. | 306 // Convert the parameter to number using the builtin. |
| 312 HValue* function = AddLoadJSBuiltin(Builtins::TO_NUMBER); | 307 HValue* function = AddLoadJSBuiltin(Builtins::TO_NUMBER); |
| 313 Add<HPushArgument>(value); | 308 Add<HPushArgument>(value); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 | 351 |
| 357 HObjectAccess access = HObjectAccess::ForAllocationSiteOffset( | 352 HObjectAccess access = HObjectAccess::ForAllocationSiteOffset( |
| 358 AllocationSite::kTransitionInfoOffset); | 353 AllocationSite::kTransitionInfoOffset); |
| 359 HInstruction* boilerplate = Add<HLoadNamedField>( | 354 HInstruction* boilerplate = Add<HLoadNamedField>( |
| 360 allocation_site, static_cast<HValue*>(NULL), access); | 355 allocation_site, static_cast<HValue*>(NULL), access); |
| 361 HValue* push_value; | 356 HValue* push_value; |
| 362 if (mode == FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS) { | 357 if (mode == FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS) { |
| 363 HValue* elements = AddLoadElements(boilerplate); | 358 HValue* elements = AddLoadElements(boilerplate); |
| 364 | 359 |
| 365 IfBuilder if_fixed_cow(this); | 360 IfBuilder if_fixed_cow(this); |
| 366 if_fixed_cow.If<HCompareMap>(elements, factory->fixed_cow_array_map(), | 361 if_fixed_cow.If<HCompareMap>(elements, factory->fixed_cow_array_map()); |
| 367 top_info()); | |
| 368 if_fixed_cow.Then(); | 362 if_fixed_cow.Then(); |
| 369 push_value = BuildCloneShallowArray(boilerplate, | 363 push_value = BuildCloneShallowArray(boilerplate, |
| 370 allocation_site, | 364 allocation_site, |
| 371 alloc_site_mode, | 365 alloc_site_mode, |
| 372 FAST_ELEMENTS, | 366 FAST_ELEMENTS, |
| 373 0/*copy-on-write*/); | 367 0/*copy-on-write*/); |
| 374 environment()->Push(push_value); | 368 environment()->Push(push_value); |
| 375 if_fixed_cow.Else(); | 369 if_fixed_cow.Else(); |
| 376 | 370 |
| 377 IfBuilder if_fixed(this); | 371 IfBuilder if_fixed(this); |
| 378 if_fixed.If<HCompareMap>(elements, factory->fixed_array_map(), top_info()); | 372 if_fixed.If<HCompareMap>(elements, factory->fixed_array_map()); |
| 379 if_fixed.Then(); | 373 if_fixed.Then(); |
| 380 push_value = BuildCloneShallowArray(boilerplate, | 374 push_value = BuildCloneShallowArray(boilerplate, |
| 381 allocation_site, | 375 allocation_site, |
| 382 alloc_site_mode, | 376 alloc_site_mode, |
| 383 FAST_ELEMENTS, | 377 FAST_ELEMENTS, |
| 384 length); | 378 length); |
| 385 environment()->Push(push_value); | 379 environment()->Push(push_value); |
| 386 if_fixed.Else(); | 380 if_fixed.Else(); |
| 387 push_value = BuildCloneShallowArray(boilerplate, | 381 push_value = BuildCloneShallowArray(boilerplate, |
| 388 allocation_site, | 382 allocation_site, |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 HValue* site = Add<HLoadNamedField>( | 523 HValue* site = Add<HLoadNamedField>( |
| 530 site_list, static_cast<HValue*>(NULL), | 524 site_list, static_cast<HValue*>(NULL), |
| 531 HObjectAccess::ForAllocationSiteList()); | 525 HObjectAccess::ForAllocationSiteList()); |
| 532 store = Add<HStoreNamedField>(object, | 526 store = Add<HStoreNamedField>(object, |
| 533 HObjectAccess::ForAllocationSiteOffset(AllocationSite::kWeakNextOffset), | 527 HObjectAccess::ForAllocationSiteOffset(AllocationSite::kWeakNextOffset), |
| 534 site); | 528 site); |
| 535 store->SkipWriteBarrier(); | 529 store->SkipWriteBarrier(); |
| 536 Add<HStoreNamedField>(site_list, HObjectAccess::ForAllocationSiteList(), | 530 Add<HStoreNamedField>(site_list, HObjectAccess::ForAllocationSiteList(), |
| 537 object); | 531 object); |
| 538 | 532 |
| 539 HInstruction* feedback_vector = GetParameter(0); | 533 // We use a hammer (SkipWriteBarrier()) to indicate that we know the input |
| 540 HInstruction* slot = GetParameter(1); | 534 // cell is really a Cell, and so no write barrier is needed. |
| 541 Add<HStoreKeyed>(feedback_vector, slot, object, FAST_ELEMENTS, | 535 // TODO(mvstanton): Add a debug_code check to verify the input cell is really |
| 542 INITIALIZING_STORE); | 536 // a cell. (perhaps with a new instruction, HAssert). |
| 543 return feedback_vector; | 537 HInstruction* cell = GetParameter(0); |
| 538 HObjectAccess access = HObjectAccess::ForCellValue(); |
| 539 store = Add<HStoreNamedField>(cell, access, object); |
| 540 store->SkipWriteBarrier(); |
| 541 return cell; |
| 544 } | 542 } |
| 545 | 543 |
| 546 | 544 |
| 547 Handle<Code> CreateAllocationSiteStub::GenerateCode(Isolate* isolate) { | 545 Handle<Code> CreateAllocationSiteStub::GenerateCode(Isolate* isolate) { |
| 548 return DoGenerateCode(isolate, this); | 546 return DoGenerateCode(isolate, this); |
| 549 } | 547 } |
| 550 | 548 |
| 551 | 549 |
| 552 template <> | 550 template <> |
| 553 HValue* CodeStubGraphBuilder<KeyedLoadFastElementStub>::BuildCodeStub() { | 551 HValue* CodeStubGraphBuilder<KeyedLoadFastElementStub>::BuildCodeStub() { |
| 554 HInstruction* load = BuildUncheckedMonomorphicElementAccess( | 552 HInstruction* load = BuildUncheckedMonomorphicElementAccess( |
| 555 GetParameter(0), GetParameter(1), NULL, | 553 GetParameter(0), GetParameter(1), NULL, |
| 556 casted_stub()->is_js_array(), casted_stub()->elements_kind(), | 554 casted_stub()->is_js_array(), casted_stub()->elements_kind(), |
| 557 LOAD, NEVER_RETURN_HOLE, STANDARD_STORE); | 555 false, NEVER_RETURN_HOLE, STANDARD_STORE); |
| 558 return load; | 556 return load; |
| 559 } | 557 } |
| 560 | 558 |
| 561 | 559 |
| 562 Handle<Code> KeyedLoadFastElementStub::GenerateCode(Isolate* isolate) { | 560 Handle<Code> KeyedLoadFastElementStub::GenerateCode(Isolate* isolate) { |
| 563 return DoGenerateCode(isolate, this); | 561 return DoGenerateCode(isolate, this); |
| 564 } | 562 } |
| 565 | 563 |
| 566 | 564 |
| 567 HLoadNamedField* CodeStubGraphBuilderBase::BuildLoadNamedField( | |
| 568 HValue* object, | |
| 569 Representation representation, | |
| 570 int offset, | |
| 571 bool is_inobject) { | |
| 572 HObjectAccess access = is_inobject | |
| 573 ? HObjectAccess::ForObservableJSObjectOffset(offset, representation) | |
| 574 : HObjectAccess::ForBackingStoreOffset(offset, representation); | |
| 575 if (representation.IsDouble()) { | |
| 576 // Load the heap number. | |
| 577 object = Add<HLoadNamedField>( | |
| 578 object, static_cast<HValue*>(NULL), | |
| 579 access.WithRepresentation(Representation::Tagged())); | |
| 580 // Load the double value from it. | |
| 581 access = HObjectAccess::ForHeapNumberValue(); | |
| 582 } | |
| 583 return Add<HLoadNamedField>(object, static_cast<HValue*>(NULL), access); | |
| 584 } | |
| 585 | |
| 586 | |
| 587 template<> | 565 template<> |
| 588 HValue* CodeStubGraphBuilder<LoadFieldStub>::BuildCodeStub() { | 566 HValue* CodeStubGraphBuilder<LoadFieldStub>::BuildCodeStub() { |
| 589 return BuildLoadNamedField(GetParameter(0), | 567 Representation rep = casted_stub()->representation(); |
| 590 casted_stub()->representation(), | 568 int offset = casted_stub()->offset(); |
| 591 casted_stub()->offset(), | 569 HObjectAccess access = casted_stub()->is_inobject() ? |
| 592 casted_stub()->is_inobject()); | 570 HObjectAccess::ForObservableJSObjectOffset(offset, rep) : |
| 571 HObjectAccess::ForBackingStoreOffset(offset, rep); |
| 572 return AddLoadNamedField(GetParameter(0), access); |
| 593 } | 573 } |
| 594 | 574 |
| 595 | 575 |
| 596 Handle<Code> LoadFieldStub::GenerateCode(Isolate* isolate) { | 576 Handle<Code> LoadFieldStub::GenerateCode(Isolate* isolate) { |
| 597 return DoGenerateCode(isolate, this); | 577 return DoGenerateCode(isolate, this); |
| 598 } | 578 } |
| 599 | 579 |
| 600 | 580 |
| 601 template<> | 581 template<> |
| 602 HValue* CodeStubGraphBuilder<KeyedLoadFieldStub>::BuildCodeStub() { | 582 HValue* CodeStubGraphBuilder<KeyedLoadFieldStub>::BuildCodeStub() { |
| 603 return BuildLoadNamedField(GetParameter(0), | 583 Representation rep = casted_stub()->representation(); |
| 604 casted_stub()->representation(), | 584 int offset = casted_stub()->offset(); |
| 605 casted_stub()->offset(), | 585 HObjectAccess access = casted_stub()->is_inobject() ? |
| 606 casted_stub()->is_inobject()); | 586 HObjectAccess::ForObservableJSObjectOffset(offset, rep) : |
| 587 HObjectAccess::ForBackingStoreOffset(offset, rep); |
| 588 return AddLoadNamedField(GetParameter(0), access); |
| 607 } | 589 } |
| 608 | 590 |
| 609 | 591 |
| 610 Handle<Code> KeyedLoadFieldStub::GenerateCode(Isolate* isolate) { | 592 Handle<Code> KeyedLoadFieldStub::GenerateCode(Isolate* isolate) { |
| 611 return DoGenerateCode(isolate, this); | 593 return DoGenerateCode(isolate, this); |
| 612 } | 594 } |
| 613 | 595 |
| 614 | 596 |
| 615 template <> | 597 template <> |
| 616 HValue* CodeStubGraphBuilder<KeyedStoreFastElementStub>::BuildCodeStub() { | 598 HValue* CodeStubGraphBuilder<KeyedStoreFastElementStub>::BuildCodeStub() { |
| 617 BuildUncheckedMonomorphicElementAccess( | 599 BuildUncheckedMonomorphicElementAccess( |
| 618 GetParameter(0), GetParameter(1), GetParameter(2), | 600 GetParameter(0), GetParameter(1), GetParameter(2), |
| 619 casted_stub()->is_js_array(), casted_stub()->elements_kind(), | 601 casted_stub()->is_js_array(), casted_stub()->elements_kind(), |
| 620 STORE, NEVER_RETURN_HOLE, casted_stub()->store_mode()); | 602 true, NEVER_RETURN_HOLE, casted_stub()->store_mode()); |
| 621 | 603 |
| 622 return GetParameter(2); | 604 return GetParameter(2); |
| 623 } | 605 } |
| 624 | 606 |
| 625 | 607 |
| 626 Handle<Code> KeyedStoreFastElementStub::GenerateCode(Isolate* isolate) { | 608 Handle<Code> KeyedStoreFastElementStub::GenerateCode(Isolate* isolate) { |
| 627 return DoGenerateCode(isolate, this); | 609 return DoGenerateCode(isolate, this); |
| 628 } | 610 } |
| 629 | 611 |
| 630 | 612 |
| (...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1107 info()->MarkAsSavesCallerDoubles(); | 1089 info()->MarkAsSavesCallerDoubles(); |
| 1108 | 1090 |
| 1109 BuildTransitionElementsKind(object, map, | 1091 BuildTransitionElementsKind(object, map, |
| 1110 casted_stub()->from_kind(), | 1092 casted_stub()->from_kind(), |
| 1111 casted_stub()->to_kind(), | 1093 casted_stub()->to_kind(), |
| 1112 casted_stub()->is_jsarray()); | 1094 casted_stub()->is_jsarray()); |
| 1113 | 1095 |
| 1114 BuildUncheckedMonomorphicElementAccess(object, key, value, | 1096 BuildUncheckedMonomorphicElementAccess(object, key, value, |
| 1115 casted_stub()->is_jsarray(), | 1097 casted_stub()->is_jsarray(), |
| 1116 casted_stub()->to_kind(), | 1098 casted_stub()->to_kind(), |
| 1117 STORE, ALLOW_RETURN_HOLE, | 1099 true, ALLOW_RETURN_HOLE, |
| 1118 casted_stub()->store_mode()); | 1100 casted_stub()->store_mode()); |
| 1119 } | 1101 } |
| 1120 | 1102 |
| 1121 return value; | 1103 return value; |
| 1122 } | 1104 } |
| 1123 | 1105 |
| 1124 | 1106 |
| 1125 Handle<Code> ElementsTransitionAndStoreStub::GenerateCode(Isolate* isolate) { | 1107 Handle<Code> ElementsTransitionAndStoreStub::GenerateCode(Isolate* isolate) { |
| 1126 return DoGenerateCode(isolate, this); | 1108 return DoGenerateCode(isolate, this); |
| 1127 } | 1109 } |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1417 return BuildRegExpConstructResult(length, index, input); | 1399 return BuildRegExpConstructResult(length, index, input); |
| 1418 } | 1400 } |
| 1419 | 1401 |
| 1420 | 1402 |
| 1421 Handle<Code> RegExpConstructResultStub::GenerateCode(Isolate* isolate) { | 1403 Handle<Code> RegExpConstructResultStub::GenerateCode(Isolate* isolate) { |
| 1422 return DoGenerateCode(isolate, this); | 1404 return DoGenerateCode(isolate, this); |
| 1423 } | 1405 } |
| 1424 | 1406 |
| 1425 | 1407 |
| 1426 } } // namespace v8::internal | 1408 } } // namespace v8::internal |
| OLD | NEW |