OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 | 261 |
262 void Comparator::CalculateDifference(Comparator::Input* input, | 262 void Comparator::CalculateDifference(Comparator::Input* input, |
263 Comparator::Output* result_writer) { | 263 Comparator::Output* result_writer) { |
264 Differencer differencer(input); | 264 Differencer differencer(input); |
265 differencer.Initialize(); | 265 differencer.Initialize(); |
266 differencer.FillTable(); | 266 differencer.FillTable(); |
267 differencer.SaveResult(result_writer); | 267 differencer.SaveResult(result_writer); |
268 } | 268 } |
269 | 269 |
270 | 270 |
271 static bool CompareSubstrings(Handle<String> s1, int pos1, | 271 static bool CompareSubstrings(Isolate* isolate, Handle<String> s1, int pos1, |
272 Handle<String> s2, int pos2, int len) { | 272 Handle<String> s2, int pos2, int len) { |
273 static StringInputBuffer buf1; | 273 StringInputBuffer& buf1 = *isolate->liveedit_compare_substrings_buf1(); |
274 static StringInputBuffer buf2; | 274 StringInputBuffer& buf2 = *isolate->liveedit_compare_substrings_buf2(); |
275 buf1.Reset(*s1); | 275 buf1.Reset(*s1); |
276 buf1.Seek(pos1); | 276 buf1.Seek(pos1); |
277 buf2.Reset(*s2); | 277 buf2.Reset(*s2); |
278 buf2.Seek(pos2); | 278 buf2.Seek(pos2); |
279 for (int i = 0; i < len; i++) { | 279 for (int i = 0; i < len; i++) { |
280 ASSERT(buf1.has_more() && buf2.has_more()); | 280 ASSERT(buf1.has_more() && buf2.has_more()); |
281 if (buf1.GetNext() != buf2.GetNext()) { | 281 if (buf1.GetNext() != buf2.GetNext()) { |
282 return false; | 282 return false; |
283 } | 283 } |
284 } | 284 } |
285 return true; | 285 return true; |
286 } | 286 } |
287 | 287 |
288 | 288 |
289 // A helper class that writes chunk numbers into JSArray. | 289 // A helper class that writes chunk numbers into JSArray. |
290 // Each chunk is stored as 3 array elements: (pos1_begin, pos1_end, pos2_end). | 290 // Each chunk is stored as 3 array elements: (pos1_begin, pos1_end, pos2_end). |
291 class CompareOutputArrayWriter { | 291 class CompareOutputArrayWriter { |
292 public: | 292 public: |
293 CompareOutputArrayWriter() | 293 CompareOutputArrayWriter() |
294 : array_(Factory::NewJSArray(10)), current_size_(0) {} | 294 : array_(FACTORY->NewJSArray(10)), current_size_(0) {} |
295 | 295 |
296 Handle<JSArray> GetResult() { | 296 Handle<JSArray> GetResult() { |
297 return array_; | 297 return array_; |
298 } | 298 } |
299 | 299 |
300 void WriteChunk(int char_pos1, int char_pos2, int char_len1, int char_len2) { | 300 void WriteChunk(int char_pos1, int char_pos2, int char_len1, int char_len2) { |
301 SetElementNonStrict(array_, | 301 SetElementNonStrict(array_, |
302 current_size_, | 302 current_size_, |
303 Handle<Object>(Smi::FromInt(char_pos1))); | 303 Handle<Object>(Smi::FromInt(char_pos1))); |
304 SetElementNonStrict(array_, | 304 SetElementNonStrict(array_, |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 | 403 |
404 int GetPosAfterNewLine(int index) { | 404 int GetPosAfterNewLine(int index) { |
405 return Smi::cast(ends_array_->get(index))->value() + 1; | 405 return Smi::cast(ends_array_->get(index))->value() + 1; |
406 } | 406 } |
407 }; | 407 }; |
408 | 408 |
409 | 409 |
410 // Represents 2 strings as 2 arrays of lines. | 410 // Represents 2 strings as 2 arrays of lines. |
411 class LineArrayCompareInput : public Comparator::Input { | 411 class LineArrayCompareInput : public Comparator::Input { |
412 public: | 412 public: |
413 LineArrayCompareInput(Handle<String> s1, Handle<String> s2, | 413 LineArrayCompareInput(Isolate* isolate, Handle<String> s1, Handle<String> s2, |
414 LineEndsWrapper line_ends1, LineEndsWrapper line_ends2) | 414 LineEndsWrapper line_ends1, LineEndsWrapper line_ends2) |
415 : s1_(s1), s2_(s2), line_ends1_(line_ends1), line_ends2_(line_ends2) { | 415 : isolate_(isolate), s1_(s1), s2_(s2), line_ends1_(line_ends1), |
| 416 line_ends2_(line_ends2) { |
416 } | 417 } |
417 int getLength1() { | 418 int getLength1() { |
418 return line_ends1_.length(); | 419 return line_ends1_.length(); |
419 } | 420 } |
420 int getLength2() { | 421 int getLength2() { |
421 return line_ends2_.length(); | 422 return line_ends2_.length(); |
422 } | 423 } |
423 bool equals(int index1, int index2) { | 424 bool equals(int index1, int index2) { |
424 int line_start1 = line_ends1_.GetLineStart(index1); | 425 int line_start1 = line_ends1_.GetLineStart(index1); |
425 int line_start2 = line_ends2_.GetLineStart(index2); | 426 int line_start2 = line_ends2_.GetLineStart(index2); |
426 int line_end1 = line_ends1_.GetLineEnd(index1); | 427 int line_end1 = line_ends1_.GetLineEnd(index1); |
427 int line_end2 = line_ends2_.GetLineEnd(index2); | 428 int line_end2 = line_ends2_.GetLineEnd(index2); |
428 int len1 = line_end1 - line_start1; | 429 int len1 = line_end1 - line_start1; |
429 int len2 = line_end2 - line_start2; | 430 int len2 = line_end2 - line_start2; |
430 if (len1 != len2) { | 431 if (len1 != len2) { |
431 return false; | 432 return false; |
432 } | 433 } |
433 return CompareSubstrings(s1_, line_start1, s2_, line_start2, len1); | 434 return CompareSubstrings(isolate_, s1_, line_start1, s2_, line_start2, |
| 435 len1); |
434 } | 436 } |
435 | 437 |
436 private: | 438 private: |
| 439 Isolate* isolate_; |
437 Handle<String> s1_; | 440 Handle<String> s1_; |
438 Handle<String> s2_; | 441 Handle<String> s2_; |
439 LineEndsWrapper line_ends1_; | 442 LineEndsWrapper line_ends1_; |
440 LineEndsWrapper line_ends2_; | 443 LineEndsWrapper line_ends2_; |
441 }; | 444 }; |
442 | 445 |
443 | 446 |
444 // Stores compare result in JSArray. For each chunk tries to conduct | 447 // Stores compare result in JSArray. For each chunk tries to conduct |
445 // a fine-grained nested diff token-wise. | 448 // a fine-grained nested diff token-wise. |
446 class TokenizingLineArrayCompareOutput : public Comparator::Output { | 449 class TokenizingLineArrayCompareOutput : public Comparator::Output { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 Handle<String> s1_; | 488 Handle<String> s1_; |
486 Handle<String> s2_; | 489 Handle<String> s2_; |
487 }; | 490 }; |
488 | 491 |
489 | 492 |
490 Handle<JSArray> LiveEdit::CompareStrings(Handle<String> s1, | 493 Handle<JSArray> LiveEdit::CompareStrings(Handle<String> s1, |
491 Handle<String> s2) { | 494 Handle<String> s2) { |
492 LineEndsWrapper line_ends1(s1); | 495 LineEndsWrapper line_ends1(s1); |
493 LineEndsWrapper line_ends2(s2); | 496 LineEndsWrapper line_ends2(s2); |
494 | 497 |
495 LineArrayCompareInput input(s1, s2, line_ends1, line_ends2); | 498 LineArrayCompareInput |
| 499 input(Isolate::Current(), s1, s2, line_ends1, line_ends2); |
496 TokenizingLineArrayCompareOutput output(line_ends1, line_ends2, s1, s2); | 500 TokenizingLineArrayCompareOutput output(line_ends1, line_ends2, s1, s2); |
497 | 501 |
498 Comparator::CalculateDifference(&input, &output); | 502 Comparator::CalculateDifference(&input, &output); |
499 | 503 |
500 return output.GetResult(); | 504 return output.GetResult(); |
501 } | 505 } |
502 | 506 |
503 | 507 |
504 static void CompileScriptForTracker(Handle<Script> script) { | 508 static void CompileScriptForTracker(Isolate* isolate, Handle<Script> script) { |
505 // TODO(635): support extensions. | 509 // TODO(635): support extensions. |
506 PostponeInterruptsScope postpone; | 510 PostponeInterruptsScope postpone(isolate); |
507 | 511 |
508 // Build AST. | 512 // Build AST. |
509 CompilationInfo info(script); | 513 CompilationInfo info(script); |
510 info.MarkAsGlobal(); | 514 info.MarkAsGlobal(); |
511 if (ParserApi::Parse(&info)) { | 515 if (ParserApi::Parse(&info)) { |
512 // Compile the code. | 516 // Compile the code. |
513 LiveEditFunctionTracker tracker(info.function()); | 517 LiveEditFunctionTracker tracker(info.isolate(), info.function()); |
514 if (Compiler::MakeCodeForLiveEdit(&info)) { | 518 if (Compiler::MakeCodeForLiveEdit(&info)) { |
515 ASSERT(!info.code().is_null()); | 519 ASSERT(!info.code().is_null()); |
516 tracker.RecordRootFunctionInfo(info.code()); | 520 tracker.RecordRootFunctionInfo(info.code()); |
517 } else { | 521 } else { |
518 Top::StackOverflow(); | 522 info.isolate()->StackOverflow(); |
519 } | 523 } |
520 } | 524 } |
521 } | 525 } |
522 | 526 |
523 | 527 |
524 // Unwraps JSValue object, returning its field "value" | 528 // Unwraps JSValue object, returning its field "value" |
525 static Handle<Object> UnwrapJSValue(Handle<JSValue> jsValue) { | 529 static Handle<Object> UnwrapJSValue(Handle<JSValue> jsValue) { |
526 return Handle<Object>(jsValue->value()); | 530 return Handle<Object>(jsValue->value()); |
527 } | 531 } |
528 | 532 |
529 | 533 |
530 // Wraps any object into a OpaqueReference, that will hide the object | 534 // Wraps any object into a OpaqueReference, that will hide the object |
531 // from JavaScript. | 535 // from JavaScript. |
532 static Handle<JSValue> WrapInJSValue(Object* object) { | 536 static Handle<JSValue> WrapInJSValue(Object* object) { |
533 Handle<JSFunction> constructor = Top::opaque_reference_function(); | 537 Handle<JSFunction> constructor = |
| 538 Isolate::Current()->opaque_reference_function(); |
534 Handle<JSValue> result = | 539 Handle<JSValue> result = |
535 Handle<JSValue>::cast(Factory::NewJSObject(constructor)); | 540 Handle<JSValue>::cast(FACTORY->NewJSObject(constructor)); |
536 result->set_value(object); | 541 result->set_value(object); |
537 return result; | 542 return result; |
538 } | 543 } |
539 | 544 |
540 | 545 |
541 // Simple helper class that creates more or less typed structures over | 546 // Simple helper class that creates more or less typed structures over |
542 // JSArray object. This is an adhoc method of passing structures from C++ | 547 // JSArray object. This is an adhoc method of passing structures from C++ |
543 // to JavaScript. | 548 // to JavaScript. |
544 template<typename S> | 549 template<typename S> |
545 class JSArrayBasedStruct { | 550 class JSArrayBasedStruct { |
546 public: | 551 public: |
547 static S Create() { | 552 static S Create() { |
548 Handle<JSArray> array = Factory::NewJSArray(S::kSize_); | 553 Handle<JSArray> array = FACTORY->NewJSArray(S::kSize_); |
549 return S(array); | 554 return S(array); |
550 } | 555 } |
551 static S cast(Object* object) { | 556 static S cast(Object* object) { |
552 JSArray* array = JSArray::cast(object); | 557 JSArray* array = JSArray::cast(object); |
553 Handle<JSArray> array_handle(array); | 558 Handle<JSArray> array_handle(array); |
554 return S(array_handle); | 559 return S(array_handle); |
555 } | 560 } |
556 explicit JSArrayBasedStruct(Handle<JSArray> array) : array_(array) { | 561 explicit JSArrayBasedStruct(Handle<JSArray> array) : array_(array) { |
557 } | 562 } |
558 Handle<JSArray> GetJSArray() { | 563 Handle<JSArray> GetJSArray() { |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
688 | 693 |
689 friend class JSArrayBasedStruct<SharedInfoWrapper>; | 694 friend class JSArrayBasedStruct<SharedInfoWrapper>; |
690 }; | 695 }; |
691 | 696 |
692 | 697 |
693 class FunctionInfoListener { | 698 class FunctionInfoListener { |
694 public: | 699 public: |
695 FunctionInfoListener() { | 700 FunctionInfoListener() { |
696 current_parent_index_ = -1; | 701 current_parent_index_ = -1; |
697 len_ = 0; | 702 len_ = 0; |
698 result_ = Factory::NewJSArray(10); | 703 result_ = FACTORY->NewJSArray(10); |
699 } | 704 } |
700 | 705 |
701 void FunctionStarted(FunctionLiteral* fun) { | 706 void FunctionStarted(FunctionLiteral* fun) { |
702 HandleScope scope; | 707 HandleScope scope; |
703 FunctionInfoWrapper info = FunctionInfoWrapper::Create(); | 708 FunctionInfoWrapper info = FunctionInfoWrapper::Create(); |
704 info.SetInitialProperties(fun->name(), fun->start_position(), | 709 info.SetInitialProperties(fun->name(), fun->start_position(), |
705 fun->end_position(), fun->num_parameters(), | 710 fun->end_position(), fun->num_parameters(), |
706 current_parent_index_); | 711 current_parent_index_); |
707 current_parent_index_ = len_; | 712 current_parent_index_ = len_; |
708 SetElementNonStrict(result_, len_, info.GetJSArray()); | 713 SetElementNonStrict(result_, len_, info.GetJSArray()); |
709 len_++; | 714 len_++; |
710 } | 715 } |
711 | 716 |
712 void FunctionDone() { | 717 void FunctionDone() { |
713 HandleScope scope; | 718 HandleScope scope; |
714 FunctionInfoWrapper info = | 719 FunctionInfoWrapper info = |
715 FunctionInfoWrapper::cast( | 720 FunctionInfoWrapper::cast( |
716 result_->GetElementNoExceptionThrown(current_parent_index_)); | 721 result_->GetElementNoExceptionThrown(current_parent_index_)); |
717 current_parent_index_ = info.GetParentIndex(); | 722 current_parent_index_ = info.GetParentIndex(); |
718 } | 723 } |
719 | 724 |
720 // Saves only function code, because for a script function we | 725 // Saves only function code, because for a script function we |
721 // may never create a SharedFunctionInfo object. | 726 // may never create a SharedFunctionInfo object. |
722 void FunctionCode(Handle<Code> function_code) { | 727 void FunctionCode(Handle<Code> function_code) { |
723 FunctionInfoWrapper info = | 728 FunctionInfoWrapper info = |
724 FunctionInfoWrapper::cast( | 729 FunctionInfoWrapper::cast( |
725 result_->GetElementNoExceptionThrown(current_parent_index_)); | 730 result_->GetElementNoExceptionThrown(current_parent_index_)); |
726 info.SetFunctionCode(function_code, Handle<Object>(Heap::null_value())); | 731 info.SetFunctionCode(function_code, Handle<Object>(HEAP->null_value())); |
727 } | 732 } |
728 | 733 |
729 // Saves full information about a function: its code, its scope info | 734 // Saves full information about a function: its code, its scope info |
730 // and a SharedFunctionInfo object. | 735 // and a SharedFunctionInfo object. |
731 void FunctionInfo(Handle<SharedFunctionInfo> shared, Scope* scope) { | 736 void FunctionInfo(Handle<SharedFunctionInfo> shared, Scope* scope) { |
732 if (!shared->IsSharedFunctionInfo()) { | 737 if (!shared->IsSharedFunctionInfo()) { |
733 return; | 738 return; |
734 } | 739 } |
735 FunctionInfoWrapper info = | 740 FunctionInfoWrapper info = |
736 FunctionInfoWrapper::cast( | 741 FunctionInfoWrapper::cast( |
737 result_->GetElementNoExceptionThrown(current_parent_index_)); | 742 result_->GetElementNoExceptionThrown(current_parent_index_)); |
738 info.SetFunctionCode(Handle<Code>(shared->code()), | 743 info.SetFunctionCode(Handle<Code>(shared->code()), |
739 Handle<Object>(shared->scope_info())); | 744 Handle<Object>(shared->scope_info())); |
740 info.SetSharedFunctionInfo(shared); | 745 info.SetSharedFunctionInfo(shared); |
741 | 746 |
742 Handle<Object> scope_info_list(SerializeFunctionScope(scope)); | 747 Handle<Object> scope_info_list(SerializeFunctionScope(scope)); |
743 info.SetOuterScopeInfo(scope_info_list); | 748 info.SetOuterScopeInfo(scope_info_list); |
744 } | 749 } |
745 | 750 |
746 Handle<JSArray> GetResult() { return result_; } | 751 Handle<JSArray> GetResult() { return result_; } |
747 | 752 |
748 private: | 753 private: |
749 Object* SerializeFunctionScope(Scope* scope) { | 754 Object* SerializeFunctionScope(Scope* scope) { |
750 HandleScope handle_scope; | 755 HandleScope handle_scope; |
751 | 756 |
752 Handle<JSArray> scope_info_list = Factory::NewJSArray(10); | 757 Handle<JSArray> scope_info_list = FACTORY->NewJSArray(10); |
753 int scope_info_length = 0; | 758 int scope_info_length = 0; |
754 | 759 |
755 // Saves some description of scope. It stores name and indexes of | 760 // Saves some description of scope. It stores name and indexes of |
756 // variables in the whole scope chain. Null-named slots delimit | 761 // variables in the whole scope chain. Null-named slots delimit |
757 // scopes of this chain. | 762 // scopes of this chain. |
758 Scope* outer_scope = scope->outer_scope(); | 763 Scope* outer_scope = scope->outer_scope(); |
759 if (outer_scope == NULL) { | 764 if (outer_scope == NULL) { |
760 return Heap::undefined_value(); | 765 return HEAP->undefined_value(); |
761 } | 766 } |
762 do { | 767 do { |
763 ZoneList<Variable*> list(10); | 768 ZoneList<Variable*> list(10); |
764 outer_scope->CollectUsedVariables(&list); | 769 outer_scope->CollectUsedVariables(&list); |
765 int j = 0; | 770 int j = 0; |
766 for (int i = 0; i < list.length(); i++) { | 771 for (int i = 0; i < list.length(); i++) { |
767 Variable* var1 = list[i]; | 772 Variable* var1 = list[i]; |
768 Slot* slot = var1->AsSlot(); | 773 Slot* slot = var1->AsSlot(); |
769 if (slot != NULL && slot->type() == Slot::CONTEXT) { | 774 if (slot != NULL && slot->type() == Slot::CONTEXT) { |
770 if (j != i) { | 775 if (j != i) { |
(...skipping 19 matching lines...) Expand all Loading... |
790 list[i]->name()); | 795 list[i]->name()); |
791 scope_info_length++; | 796 scope_info_length++; |
792 SetElementNonStrict( | 797 SetElementNonStrict( |
793 scope_info_list, | 798 scope_info_list, |
794 scope_info_length, | 799 scope_info_length, |
795 Handle<Smi>(Smi::FromInt(list[i]->AsSlot()->index()))); | 800 Handle<Smi>(Smi::FromInt(list[i]->AsSlot()->index()))); |
796 scope_info_length++; | 801 scope_info_length++; |
797 } | 802 } |
798 SetElementNonStrict(scope_info_list, | 803 SetElementNonStrict(scope_info_list, |
799 scope_info_length, | 804 scope_info_length, |
800 Handle<Object>(Heap::null_value())); | 805 Handle<Object>(HEAP->null_value())); |
801 scope_info_length++; | 806 scope_info_length++; |
802 | 807 |
803 outer_scope = outer_scope->outer_scope(); | 808 outer_scope = outer_scope->outer_scope(); |
804 } while (outer_scope != NULL); | 809 } while (outer_scope != NULL); |
805 | 810 |
806 return *scope_info_list; | 811 return *scope_info_list; |
807 } | 812 } |
808 | 813 |
809 Handle<JSArray> result_; | 814 Handle<JSArray> result_; |
810 int len_; | 815 int len_; |
811 int current_parent_index_; | 816 int current_parent_index_; |
812 }; | 817 }; |
813 | 818 |
814 | 819 |
815 static FunctionInfoListener* active_function_info_listener = NULL; | |
816 | |
817 JSArray* LiveEdit::GatherCompileInfo(Handle<Script> script, | 820 JSArray* LiveEdit::GatherCompileInfo(Handle<Script> script, |
818 Handle<String> source) { | 821 Handle<String> source) { |
| 822 Isolate* isolate = Isolate::Current(); |
819 CompilationZoneScope zone_scope(DELETE_ON_EXIT); | 823 CompilationZoneScope zone_scope(DELETE_ON_EXIT); |
820 | 824 |
821 FunctionInfoListener listener; | 825 FunctionInfoListener listener; |
822 Handle<Object> original_source = Handle<Object>(script->source()); | 826 Handle<Object> original_source = Handle<Object>(script->source()); |
823 script->set_source(*source); | 827 script->set_source(*source); |
824 active_function_info_listener = &listener; | 828 isolate->set_active_function_info_listener(&listener); |
825 CompileScriptForTracker(script); | 829 CompileScriptForTracker(isolate, script); |
826 active_function_info_listener = NULL; | 830 isolate->set_active_function_info_listener(NULL); |
827 script->set_source(*original_source); | 831 script->set_source(*original_source); |
828 | 832 |
829 return *(listener.GetResult()); | 833 return *(listener.GetResult()); |
830 } | 834 } |
831 | 835 |
832 | 836 |
833 void LiveEdit::WrapSharedFunctionInfos(Handle<JSArray> array) { | 837 void LiveEdit::WrapSharedFunctionInfos(Handle<JSArray> array) { |
834 HandleScope scope; | 838 HandleScope scope; |
835 int len = Smi::cast(array->length())->value(); | 839 int len = Smi::cast(array->length())->value(); |
836 for (int i = 0; i < len; i++) { | 840 for (int i = 0; i < len; i++) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
898 private: | 902 private: |
899 Code* original_; | 903 Code* original_; |
900 ZoneList<Object**> rvalues_; | 904 ZoneList<Object**> rvalues_; |
901 ZoneList<RelocInfo> reloc_infos_; | 905 ZoneList<RelocInfo> reloc_infos_; |
902 ZoneList<Address> code_entries_; | 906 ZoneList<Address> code_entries_; |
903 }; | 907 }; |
904 | 908 |
905 | 909 |
906 // Finds all references to original and replaces them with substitution. | 910 // Finds all references to original and replaces them with substitution. |
907 static void ReplaceCodeObject(Code* original, Code* substitution) { | 911 static void ReplaceCodeObject(Code* original, Code* substitution) { |
908 ASSERT(!Heap::InNewSpace(substitution)); | 912 ASSERT(!HEAP->InNewSpace(substitution)); |
909 | 913 |
910 AssertNoAllocation no_allocations_please; | 914 AssertNoAllocation no_allocations_please; |
911 | 915 |
912 // A zone scope for ReferenceCollectorVisitor. | 916 // A zone scope for ReferenceCollectorVisitor. |
913 ZoneScope scope(DELETE_ON_EXIT); | 917 ZoneScope scope(DELETE_ON_EXIT); |
914 | 918 |
915 ReferenceCollectorVisitor visitor(original); | 919 ReferenceCollectorVisitor visitor(original); |
916 | 920 |
917 // Iterate over all roots. Stack frames may have pointer into original code, | 921 // Iterate over all roots. Stack frames may have pointer into original code, |
918 // so temporary replace the pointers with offset numbers | 922 // so temporary replace the pointers with offset numbers |
919 // in prologue/epilogue. | 923 // in prologue/epilogue. |
920 { | 924 { |
921 Heap::IterateStrongRoots(&visitor, VISIT_ALL); | 925 HEAP->IterateStrongRoots(&visitor, VISIT_ALL); |
922 } | 926 } |
923 | 927 |
924 // Now iterate over all pointers of all objects, including code_target | 928 // Now iterate over all pointers of all objects, including code_target |
925 // implicit pointers. | 929 // implicit pointers. |
926 HeapIterator iterator; | 930 HeapIterator iterator; |
927 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | 931 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { |
928 obj->Iterate(&visitor); | 932 obj->Iterate(&visitor); |
929 } | 933 } |
930 | 934 |
931 visitor.Replace(substitution); | 935 visitor.Replace(substitution); |
932 } | 936 } |
933 | 937 |
934 | 938 |
935 // Check whether the code is natural function code (not a lazy-compile stub | 939 // Check whether the code is natural function code (not a lazy-compile stub |
936 // code). | 940 // code). |
937 static bool IsJSFunctionCode(Code* code) { | 941 static bool IsJSFunctionCode(Code* code) { |
938 return code->kind() == Code::FUNCTION; | 942 return code->kind() == Code::FUNCTION; |
939 } | 943 } |
940 | 944 |
941 | 945 |
942 // Returns true if an instance of candidate were inlined into function's code. | 946 // Returns true if an instance of candidate were inlined into function's code. |
943 static bool IsInlined(JSFunction* function, SharedFunctionInfo* candidate) { | 947 static bool IsInlined(JSFunction* function, SharedFunctionInfo* candidate) { |
944 AssertNoAllocation no_gc; | 948 AssertNoAllocation no_gc; |
945 | 949 |
946 if (function->code()->kind() != Code::OPTIMIZED_FUNCTION) return false; | 950 if (function->code()->kind() != Code::OPTIMIZED_FUNCTION) return false; |
947 | 951 |
948 DeoptimizationInputData* data = | 952 DeoptimizationInputData* data = |
949 DeoptimizationInputData::cast(function->code()->deoptimization_data()); | 953 DeoptimizationInputData::cast(function->code()->deoptimization_data()); |
950 | 954 |
951 if (data == Heap::empty_fixed_array()) return false; | 955 if (data == HEAP->empty_fixed_array()) return false; |
952 | 956 |
953 FixedArray* literals = data->LiteralArray(); | 957 FixedArray* literals = data->LiteralArray(); |
954 | 958 |
955 int inlined_count = data->InlinedFunctionCount()->value(); | 959 int inlined_count = data->InlinedFunctionCount()->value(); |
956 for (int i = 0; i < inlined_count; ++i) { | 960 for (int i = 0; i < inlined_count; ++i) { |
957 JSFunction* inlined = JSFunction::cast(literals->get(i)); | 961 JSFunction* inlined = JSFunction::cast(literals->get(i)); |
958 if (inlined->shared() == candidate) return true; | 962 if (inlined->shared() == candidate) return true; |
959 } | 963 } |
960 | 964 |
961 return false; | 965 return false; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
993 Deoptimizer::VisitAllOptimizedFunctions(&visitor); | 997 Deoptimizer::VisitAllOptimizedFunctions(&visitor); |
994 } | 998 } |
995 | 999 |
996 | 1000 |
997 MaybeObject* LiveEdit::ReplaceFunctionCode( | 1001 MaybeObject* LiveEdit::ReplaceFunctionCode( |
998 Handle<JSArray> new_compile_info_array, | 1002 Handle<JSArray> new_compile_info_array, |
999 Handle<JSArray> shared_info_array) { | 1003 Handle<JSArray> shared_info_array) { |
1000 HandleScope scope; | 1004 HandleScope scope; |
1001 | 1005 |
1002 if (!SharedInfoWrapper::IsInstance(shared_info_array)) { | 1006 if (!SharedInfoWrapper::IsInstance(shared_info_array)) { |
1003 return Top::ThrowIllegalOperation(); | 1007 return Isolate::Current()->ThrowIllegalOperation(); |
1004 } | 1008 } |
1005 | 1009 |
1006 FunctionInfoWrapper compile_info_wrapper(new_compile_info_array); | 1010 FunctionInfoWrapper compile_info_wrapper(new_compile_info_array); |
1007 SharedInfoWrapper shared_info_wrapper(shared_info_array); | 1011 SharedInfoWrapper shared_info_wrapper(shared_info_array); |
1008 | 1012 |
1009 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo(); | 1013 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo(); |
1010 | 1014 |
1011 if (IsJSFunctionCode(shared_info->code())) { | 1015 if (IsJSFunctionCode(shared_info->code())) { |
1012 ReplaceCodeObject(shared_info->code(), | 1016 ReplaceCodeObject(shared_info->code(), |
1013 *(compile_info_wrapper.GetFunctionCode())); | 1017 *(compile_info_wrapper.GetFunctionCode())); |
1014 Handle<Object> code_scope_info = compile_info_wrapper.GetCodeScopeInfo(); | 1018 Handle<Object> code_scope_info = compile_info_wrapper.GetCodeScopeInfo(); |
1015 if (code_scope_info->IsFixedArray()) { | 1019 if (code_scope_info->IsFixedArray()) { |
1016 shared_info->set_scope_info(SerializedScopeInfo::cast(*code_scope_info)); | 1020 shared_info->set_scope_info(SerializedScopeInfo::cast(*code_scope_info)); |
1017 } | 1021 } |
1018 } | 1022 } |
1019 | 1023 |
1020 if (shared_info->debug_info()->IsDebugInfo()) { | 1024 if (shared_info->debug_info()->IsDebugInfo()) { |
1021 Handle<DebugInfo> debug_info(DebugInfo::cast(shared_info->debug_info())); | 1025 Handle<DebugInfo> debug_info(DebugInfo::cast(shared_info->debug_info())); |
1022 Handle<Code> new_original_code = | 1026 Handle<Code> new_original_code = |
1023 Factory::CopyCode(compile_info_wrapper.GetFunctionCode()); | 1027 FACTORY->CopyCode(compile_info_wrapper.GetFunctionCode()); |
1024 debug_info->set_original_code(*new_original_code); | 1028 debug_info->set_original_code(*new_original_code); |
1025 } | 1029 } |
1026 | 1030 |
1027 shared_info->set_start_position(compile_info_wrapper.GetStartPosition()); | 1031 shared_info->set_start_position(compile_info_wrapper.GetStartPosition()); |
1028 shared_info->set_end_position(compile_info_wrapper.GetEndPosition()); | 1032 shared_info->set_end_position(compile_info_wrapper.GetEndPosition()); |
1029 | 1033 |
1030 shared_info->set_construct_stub( | 1034 shared_info->set_construct_stub( |
1031 Builtins::builtin(Builtins::JSConstructStubGeneric)); | 1035 Isolate::Current()->builtins()->builtin( |
| 1036 Builtins::JSConstructStubGeneric)); |
1032 | 1037 |
1033 DeoptimizeDependentFunctions(*shared_info); | 1038 DeoptimizeDependentFunctions(*shared_info); |
1034 CompilationCache::Remove(shared_info); | 1039 Isolate::Current()->compilation_cache()->Remove(shared_info); |
1035 | 1040 |
1036 return Heap::undefined_value(); | 1041 return HEAP->undefined_value(); |
1037 } | 1042 } |
1038 | 1043 |
1039 | 1044 |
1040 MaybeObject* LiveEdit::FunctionSourceUpdated( | 1045 MaybeObject* LiveEdit::FunctionSourceUpdated( |
1041 Handle<JSArray> shared_info_array) { | 1046 Handle<JSArray> shared_info_array) { |
1042 HandleScope scope; | 1047 HandleScope scope; |
1043 | 1048 |
1044 if (!SharedInfoWrapper::IsInstance(shared_info_array)) { | 1049 if (!SharedInfoWrapper::IsInstance(shared_info_array)) { |
1045 return Top::ThrowIllegalOperation(); | 1050 return Isolate::Current()->ThrowIllegalOperation(); |
1046 } | 1051 } |
1047 | 1052 |
1048 SharedInfoWrapper shared_info_wrapper(shared_info_array); | 1053 SharedInfoWrapper shared_info_wrapper(shared_info_array); |
1049 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo(); | 1054 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo(); |
1050 | 1055 |
1051 DeoptimizeDependentFunctions(*shared_info); | 1056 DeoptimizeDependentFunctions(*shared_info); |
1052 CompilationCache::Remove(shared_info); | 1057 Isolate::Current()->compilation_cache()->Remove(shared_info); |
1053 | 1058 |
1054 return Heap::undefined_value(); | 1059 return HEAP->undefined_value(); |
1055 } | 1060 } |
1056 | 1061 |
1057 | 1062 |
1058 void LiveEdit::SetFunctionScript(Handle<JSValue> function_wrapper, | 1063 void LiveEdit::SetFunctionScript(Handle<JSValue> function_wrapper, |
1059 Handle<Object> script_handle) { | 1064 Handle<Object> script_handle) { |
1060 Handle<SharedFunctionInfo> shared_info = | 1065 Handle<SharedFunctionInfo> shared_info = |
1061 Handle<SharedFunctionInfo>::cast(UnwrapJSValue(function_wrapper)); | 1066 Handle<SharedFunctionInfo>::cast(UnwrapJSValue(function_wrapper)); |
1062 shared_info->set_script(*script_handle); | 1067 shared_info->set_script(*script_handle); |
1063 | 1068 |
1064 CompilationCache::Remove(shared_info); | 1069 Isolate::Current()->compilation_cache()->Remove(shared_info); |
1065 } | 1070 } |
1066 | 1071 |
1067 | 1072 |
1068 // For a script text change (defined as position_change_array), translates | 1073 // For a script text change (defined as position_change_array), translates |
1069 // position in unchanged text to position in changed text. | 1074 // position in unchanged text to position in changed text. |
1070 // Text change is a set of non-overlapping regions in text, that have changed | 1075 // Text change is a set of non-overlapping regions in text, that have changed |
1071 // their contents and length. It is specified as array of groups of 3 numbers: | 1076 // their contents and length. It is specified as array of groups of 3 numbers: |
1072 // (change_begin, change_end, change_end_new_position). | 1077 // (change_begin, change_end, change_end_new_position). |
1073 // Each group describes a change in text; groups are sorted by change_begin. | 1078 // Each group describes a change in text; groups are sorted by change_begin. |
1074 // Only position in text beyond any changes may be successfully translated. | 1079 // Only position in text beyond any changes may be successfully translated. |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1202 Vector<byte> buffer = buffer_writer.GetResult(); | 1207 Vector<byte> buffer = buffer_writer.GetResult(); |
1203 | 1208 |
1204 if (buffer.length() == code->relocation_size()) { | 1209 if (buffer.length() == code->relocation_size()) { |
1205 // Simply patch relocation area of code. | 1210 // Simply patch relocation area of code. |
1206 memcpy(code->relocation_start(), buffer.start(), buffer.length()); | 1211 memcpy(code->relocation_start(), buffer.start(), buffer.length()); |
1207 return code; | 1212 return code; |
1208 } else { | 1213 } else { |
1209 // Relocation info section now has different size. We cannot simply | 1214 // Relocation info section now has different size. We cannot simply |
1210 // rewrite it inside code object. Instead we have to create a new | 1215 // rewrite it inside code object. Instead we have to create a new |
1211 // code object. | 1216 // code object. |
1212 Handle<Code> result(Factory::CopyCode(code, buffer)); | 1217 Handle<Code> result(FACTORY->CopyCode(code, buffer)); |
1213 return result; | 1218 return result; |
1214 } | 1219 } |
1215 } | 1220 } |
1216 | 1221 |
1217 | 1222 |
1218 MaybeObject* LiveEdit::PatchFunctionPositions( | 1223 MaybeObject* LiveEdit::PatchFunctionPositions( |
1219 Handle<JSArray> shared_info_array, Handle<JSArray> position_change_array) { | 1224 Handle<JSArray> shared_info_array, Handle<JSArray> position_change_array) { |
1220 | 1225 |
1221 if (!SharedInfoWrapper::IsInstance(shared_info_array)) { | 1226 if (!SharedInfoWrapper::IsInstance(shared_info_array)) { |
1222 return Top::ThrowIllegalOperation(); | 1227 return Isolate::Current()->ThrowIllegalOperation(); |
1223 } | 1228 } |
1224 | 1229 |
1225 SharedInfoWrapper shared_info_wrapper(shared_info_array); | 1230 SharedInfoWrapper shared_info_wrapper(shared_info_array); |
1226 Handle<SharedFunctionInfo> info = shared_info_wrapper.GetInfo(); | 1231 Handle<SharedFunctionInfo> info = shared_info_wrapper.GetInfo(); |
1227 | 1232 |
1228 int old_function_start = info->start_position(); | 1233 int old_function_start = info->start_position(); |
1229 int new_function_start = TranslatePosition(old_function_start, | 1234 int new_function_start = TranslatePosition(old_function_start, |
1230 position_change_array); | 1235 position_change_array); |
1231 info->set_start_position(new_function_start); | 1236 info->set_start_position(new_function_start); |
1232 info->set_end_position(TranslatePosition(info->end_position(), | 1237 info->set_end_position(TranslatePosition(info->end_position(), |
(...skipping 10 matching lines...) Expand all Loading... |
1243 if (*patched_code != info->code()) { | 1248 if (*patched_code != info->code()) { |
1244 // Replace all references to the code across the heap. In particular, | 1249 // Replace all references to the code across the heap. In particular, |
1245 // some stubs may refer to this code and this code may be being executed | 1250 // some stubs may refer to this code and this code may be being executed |
1246 // on stack (it is safe to substitute the code object on stack, because | 1251 // on stack (it is safe to substitute the code object on stack, because |
1247 // we only change the structure of rinfo and leave instructions | 1252 // we only change the structure of rinfo and leave instructions |
1248 // untouched). | 1253 // untouched). |
1249 ReplaceCodeObject(info->code(), *patched_code); | 1254 ReplaceCodeObject(info->code(), *patched_code); |
1250 } | 1255 } |
1251 } | 1256 } |
1252 | 1257 |
1253 return Heap::undefined_value(); | 1258 return HEAP->undefined_value(); |
1254 } | 1259 } |
1255 | 1260 |
1256 | 1261 |
1257 static Handle<Script> CreateScriptCopy(Handle<Script> original) { | 1262 static Handle<Script> CreateScriptCopy(Handle<Script> original) { |
1258 Handle<String> original_source(String::cast(original->source())); | 1263 Handle<String> original_source(String::cast(original->source())); |
1259 | 1264 |
1260 Handle<Script> copy = Factory::NewScript(original_source); | 1265 Handle<Script> copy = FACTORY->NewScript(original_source); |
1261 | 1266 |
1262 copy->set_name(original->name()); | 1267 copy->set_name(original->name()); |
1263 copy->set_line_offset(original->line_offset()); | 1268 copy->set_line_offset(original->line_offset()); |
1264 copy->set_column_offset(original->column_offset()); | 1269 copy->set_column_offset(original->column_offset()); |
1265 copy->set_data(original->data()); | 1270 copy->set_data(original->data()); |
1266 copy->set_type(original->type()); | 1271 copy->set_type(original->type()); |
1267 copy->set_context_data(original->context_data()); | 1272 copy->set_context_data(original->context_data()); |
1268 copy->set_compilation_type(original->compilation_type()); | 1273 copy->set_compilation_type(original->compilation_type()); |
1269 copy->set_eval_from_shared(original->eval_from_shared()); | 1274 copy->set_eval_from_shared(original->eval_from_shared()); |
1270 copy->set_eval_from_instructions_offset( | 1275 copy->set_eval_from_instructions_offset( |
1271 original->eval_from_instructions_offset()); | 1276 original->eval_from_instructions_offset()); |
1272 | 1277 |
1273 return copy; | 1278 return copy; |
1274 } | 1279 } |
1275 | 1280 |
1276 | 1281 |
1277 Object* LiveEdit::ChangeScriptSource(Handle<Script> original_script, | 1282 Object* LiveEdit::ChangeScriptSource(Handle<Script> original_script, |
1278 Handle<String> new_source, | 1283 Handle<String> new_source, |
1279 Handle<Object> old_script_name) { | 1284 Handle<Object> old_script_name) { |
1280 Handle<Object> old_script_object; | 1285 Handle<Object> old_script_object; |
1281 if (old_script_name->IsString()) { | 1286 if (old_script_name->IsString()) { |
1282 Handle<Script> old_script = CreateScriptCopy(original_script); | 1287 Handle<Script> old_script = CreateScriptCopy(original_script); |
1283 old_script->set_name(String::cast(*old_script_name)); | 1288 old_script->set_name(String::cast(*old_script_name)); |
1284 old_script_object = old_script; | 1289 old_script_object = old_script; |
1285 Debugger::OnAfterCompile(old_script, Debugger::SEND_WHEN_DEBUGGING); | 1290 Isolate::Current()->debugger()->OnAfterCompile( |
| 1291 old_script, Debugger::SEND_WHEN_DEBUGGING); |
1286 } else { | 1292 } else { |
1287 old_script_object = Handle<Object>(Heap::null_value()); | 1293 old_script_object = Handle<Object>(HEAP->null_value()); |
1288 } | 1294 } |
1289 | 1295 |
1290 original_script->set_source(*new_source); | 1296 original_script->set_source(*new_source); |
1291 | 1297 |
1292 // Drop line ends so that they will be recalculated. | 1298 // Drop line ends so that they will be recalculated. |
1293 original_script->set_line_ends(Heap::undefined_value()); | 1299 original_script->set_line_ends(HEAP->undefined_value()); |
1294 | 1300 |
1295 return *old_script_object; | 1301 return *old_script_object; |
1296 } | 1302 } |
1297 | 1303 |
1298 | 1304 |
1299 | 1305 |
1300 void LiveEdit::ReplaceRefToNestedFunction( | 1306 void LiveEdit::ReplaceRefToNestedFunction( |
1301 Handle<JSValue> parent_function_wrapper, | 1307 Handle<JSValue> parent_function_wrapper, |
1302 Handle<JSValue> orig_function_wrapper, | 1308 Handle<JSValue> orig_function_wrapper, |
1303 Handle<JSValue> subst_function_wrapper) { | 1309 Handle<JSValue> subst_function_wrapper) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1344 } | 1350 } |
1345 return false; | 1351 return false; |
1346 } | 1352 } |
1347 | 1353 |
1348 | 1354 |
1349 // Iterates over handler chain and removes all elements that are inside | 1355 // Iterates over handler chain and removes all elements that are inside |
1350 // frames being dropped. | 1356 // frames being dropped. |
1351 static bool FixTryCatchHandler(StackFrame* top_frame, | 1357 static bool FixTryCatchHandler(StackFrame* top_frame, |
1352 StackFrame* bottom_frame) { | 1358 StackFrame* bottom_frame) { |
1353 Address* pointer_address = | 1359 Address* pointer_address = |
1354 &Memory::Address_at(Top::get_address_from_id(Top::k_handler_address)); | 1360 &Memory::Address_at(Isolate::Current()->get_address_from_id( |
| 1361 Isolate::k_handler_address)); |
1355 | 1362 |
1356 while (*pointer_address < top_frame->sp()) { | 1363 while (*pointer_address < top_frame->sp()) { |
1357 pointer_address = &Memory::Address_at(*pointer_address); | 1364 pointer_address = &Memory::Address_at(*pointer_address); |
1358 } | 1365 } |
1359 Address* above_frame_address = pointer_address; | 1366 Address* above_frame_address = pointer_address; |
1360 while (*pointer_address < bottom_frame->fp()) { | 1367 while (*pointer_address < bottom_frame->fp()) { |
1361 pointer_address = &Memory::Address_at(*pointer_address); | 1368 pointer_address = &Memory::Address_at(*pointer_address); |
1362 } | 1369 } |
1363 bool change = *above_frame_address != *pointer_address; | 1370 bool change = *above_frame_address != *pointer_address; |
1364 *above_frame_address = *pointer_address; | 1371 *above_frame_address = *pointer_address; |
(...skipping 14 matching lines...) Expand all Loading... |
1379 return "Stack manipulations are not supported in this architecture."; | 1386 return "Stack manipulations are not supported in this architecture."; |
1380 } | 1387 } |
1381 | 1388 |
1382 StackFrame* pre_top_frame = frames[top_frame_index - 1]; | 1389 StackFrame* pre_top_frame = frames[top_frame_index - 1]; |
1383 StackFrame* top_frame = frames[top_frame_index]; | 1390 StackFrame* top_frame = frames[top_frame_index]; |
1384 StackFrame* bottom_js_frame = frames[bottom_js_frame_index]; | 1391 StackFrame* bottom_js_frame = frames[bottom_js_frame_index]; |
1385 | 1392 |
1386 ASSERT(bottom_js_frame->is_java_script()); | 1393 ASSERT(bottom_js_frame->is_java_script()); |
1387 | 1394 |
1388 // Check the nature of the top frame. | 1395 // Check the nature of the top frame. |
1389 if (pre_top_frame->code()->is_inline_cache_stub() && | 1396 Code* pre_top_frame_code = pre_top_frame->LookupCode(Isolate::Current()); |
1390 pre_top_frame->code()->ic_state() == DEBUG_BREAK) { | 1397 if (pre_top_frame_code->is_inline_cache_stub() && |
| 1398 pre_top_frame_code->ic_state() == DEBUG_BREAK) { |
1391 // OK, we can drop inline cache calls. | 1399 // OK, we can drop inline cache calls. |
1392 *mode = Debug::FRAME_DROPPED_IN_IC_CALL; | 1400 *mode = Debug::FRAME_DROPPED_IN_IC_CALL; |
1393 } else if (pre_top_frame->code() == Debug::debug_break_slot()) { | 1401 } else if (pre_top_frame_code == |
| 1402 Isolate::Current()->debug()->debug_break_slot()) { |
1394 // OK, we can drop debug break slot. | 1403 // OK, we can drop debug break slot. |
1395 *mode = Debug::FRAME_DROPPED_IN_DEBUG_SLOT_CALL; | 1404 *mode = Debug::FRAME_DROPPED_IN_DEBUG_SLOT_CALL; |
1396 } else if (pre_top_frame->code() == | 1405 } else if (pre_top_frame_code == |
1397 Builtins::builtin(Builtins::FrameDropper_LiveEdit)) { | 1406 Isolate::Current()->builtins()->builtin( |
| 1407 Builtins::FrameDropper_LiveEdit)) { |
1398 // OK, we can drop our own code. | 1408 // OK, we can drop our own code. |
1399 *mode = Debug::FRAME_DROPPED_IN_DIRECT_CALL; | 1409 *mode = Debug::FRAME_DROPPED_IN_DIRECT_CALL; |
1400 } else if (pre_top_frame->code()->kind() == Code::STUB && | 1410 } else if (pre_top_frame_code->kind() == Code::STUB && |
1401 pre_top_frame->code()->major_key()) { | 1411 pre_top_frame_code->major_key()) { |
1402 // Entry from our unit tests, it's fine, we support this case. | 1412 // Entry from our unit tests, it's fine, we support this case. |
1403 *mode = Debug::FRAME_DROPPED_IN_DIRECT_CALL; | 1413 *mode = Debug::FRAME_DROPPED_IN_DIRECT_CALL; |
1404 } else { | 1414 } else { |
1405 return "Unknown structure of stack above changing function"; | 1415 return "Unknown structure of stack above changing function"; |
1406 } | 1416 } |
1407 | 1417 |
1408 Address unused_stack_top = top_frame->sp(); | 1418 Address unused_stack_top = top_frame->sp(); |
1409 Address unused_stack_bottom = bottom_js_frame->fp() | 1419 Address unused_stack_bottom = bottom_js_frame->fp() |
1410 - Debug::kFrameDropperFrameSize * kPointerSize // Size of the new frame. | 1420 - Debug::kFrameDropperFrameSize * kPointerSize // Size of the new frame. |
1411 + kPointerSize; // Bigger address end is exclusive. | 1421 + kPointerSize; // Bigger address end is exclusive. |
1412 | 1422 |
1413 if (unused_stack_top > unused_stack_bottom) { | 1423 if (unused_stack_top > unused_stack_bottom) { |
1414 return "Not enough space for frame dropper frame"; | 1424 return "Not enough space for frame dropper frame"; |
1415 } | 1425 } |
1416 | 1426 |
1417 // Committing now. After this point we should return only NULL value. | 1427 // Committing now. After this point we should return only NULL value. |
1418 | 1428 |
1419 FixTryCatchHandler(pre_top_frame, bottom_js_frame); | 1429 FixTryCatchHandler(pre_top_frame, bottom_js_frame); |
1420 // Make sure FixTryCatchHandler is idempotent. | 1430 // Make sure FixTryCatchHandler is idempotent. |
1421 ASSERT(!FixTryCatchHandler(pre_top_frame, bottom_js_frame)); | 1431 ASSERT(!FixTryCatchHandler(pre_top_frame, bottom_js_frame)); |
1422 | 1432 |
1423 Handle<Code> code(Builtins::builtin(Builtins::FrameDropper_LiveEdit)); | 1433 Handle<Code> code(Isolate::Current()->builtins()->builtin( |
| 1434 Builtins::FrameDropper_LiveEdit)); |
1424 top_frame->set_pc(code->entry()); | 1435 top_frame->set_pc(code->entry()); |
1425 pre_top_frame->SetCallerFp(bottom_js_frame->fp()); | 1436 pre_top_frame->SetCallerFp(bottom_js_frame->fp()); |
1426 | 1437 |
1427 *restarter_frame_function_pointer = | 1438 *restarter_frame_function_pointer = |
1428 Debug::SetUpFrameDropperFrame(bottom_js_frame, code); | 1439 Debug::SetUpFrameDropperFrame(bottom_js_frame, code); |
1429 | 1440 |
1430 ASSERT((**restarter_frame_function_pointer)->IsJSFunction()); | 1441 ASSERT((**restarter_frame_function_pointer)->IsJSFunction()); |
1431 | 1442 |
1432 for (Address a = unused_stack_top; | 1443 for (Address a = unused_stack_top; |
1433 a < unused_stack_bottom; | 1444 a < unused_stack_bottom; |
1434 a += kPointerSize) { | 1445 a += kPointerSize) { |
1435 Memory::Object_at(a) = Smi::FromInt(0); | 1446 Memory::Object_at(a) = Smi::FromInt(0); |
1436 } | 1447 } |
1437 | 1448 |
1438 return NULL; | 1449 return NULL; |
1439 } | 1450 } |
1440 | 1451 |
1441 | 1452 |
1442 static bool IsDropableFrame(StackFrame* frame) { | 1453 static bool IsDropableFrame(StackFrame* frame) { |
1443 return !frame->is_exit(); | 1454 return !frame->is_exit(); |
1444 } | 1455 } |
1445 | 1456 |
1446 // Fills result array with statuses of functions. Modifies the stack | 1457 // Fills result array with statuses of functions. Modifies the stack |
1447 // removing all listed function if possible and if do_drop is true. | 1458 // removing all listed function if possible and if do_drop is true. |
1448 static const char* DropActivationsInActiveThread( | 1459 static const char* DropActivationsInActiveThread( |
1449 Handle<JSArray> shared_info_array, Handle<JSArray> result, bool do_drop) { | 1460 Handle<JSArray> shared_info_array, Handle<JSArray> result, bool do_drop) { |
1450 | 1461 Debug* debug = Isolate::Current()->debug(); |
1451 ZoneScope scope(DELETE_ON_EXIT); | 1462 ZoneScope scope(DELETE_ON_EXIT); |
1452 Vector<StackFrame*> frames = CreateStackMap(); | 1463 Vector<StackFrame*> frames = CreateStackMap(); |
1453 | 1464 |
1454 int array_len = Smi::cast(shared_info_array->length())->value(); | 1465 int array_len = Smi::cast(shared_info_array->length())->value(); |
1455 | 1466 |
1456 int top_frame_index = -1; | 1467 int top_frame_index = -1; |
1457 int frame_index = 0; | 1468 int frame_index = 0; |
1458 for (; frame_index < frames.length(); frame_index++) { | 1469 for (; frame_index < frames.length(); frame_index++) { |
1459 StackFrame* frame = frames[frame_index]; | 1470 StackFrame* frame = frames[frame_index]; |
1460 if (frame->id() == Debug::break_frame_id()) { | 1471 if (frame->id() == debug->break_frame_id()) { |
1461 top_frame_index = frame_index; | 1472 top_frame_index = frame_index; |
1462 break; | 1473 break; |
1463 } | 1474 } |
1464 if (CheckActivation(shared_info_array, result, frame, | 1475 if (CheckActivation(shared_info_array, result, frame, |
1465 LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE)) { | 1476 LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE)) { |
1466 // We are still above break_frame. It is not a target frame, | 1477 // We are still above break_frame. It is not a target frame, |
1467 // it is a problem. | 1478 // it is a problem. |
1468 return "Debugger mark-up on stack is not found"; | 1479 return "Debugger mark-up on stack is not found"; |
1469 } | 1480 } |
1470 } | 1481 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1527 } | 1538 } |
1528 | 1539 |
1529 // Adjust break_frame after some frames has been dropped. | 1540 // Adjust break_frame after some frames has been dropped. |
1530 StackFrame::Id new_id = StackFrame::NO_ID; | 1541 StackFrame::Id new_id = StackFrame::NO_ID; |
1531 for (int i = bottom_js_frame_index + 1; i < frames.length(); i++) { | 1542 for (int i = bottom_js_frame_index + 1; i < frames.length(); i++) { |
1532 if (frames[i]->type() == StackFrame::JAVA_SCRIPT) { | 1543 if (frames[i]->type() == StackFrame::JAVA_SCRIPT) { |
1533 new_id = frames[i]->id(); | 1544 new_id = frames[i]->id(); |
1534 break; | 1545 break; |
1535 } | 1546 } |
1536 } | 1547 } |
1537 Debug::FramesHaveBeenDropped(new_id, drop_mode, | 1548 debug->FramesHaveBeenDropped(new_id, drop_mode, |
1538 restarter_frame_function_pointer); | 1549 restarter_frame_function_pointer); |
1539 | 1550 |
1540 // Replace "blocked on active" with "replaced on active" status. | 1551 // Replace "blocked on active" with "replaced on active" status. |
1541 for (int i = 0; i < array_len; i++) { | 1552 for (int i = 0; i < array_len; i++) { |
1542 if (result->GetElement(i) == | 1553 if (result->GetElement(i) == |
1543 Smi::FromInt(LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) { | 1554 Smi::FromInt(LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) { |
1544 Handle<Object> replaced( | 1555 Handle<Object> replaced( |
1545 Smi::FromInt(LiveEdit::FUNCTION_REPLACED_ON_ACTIVE_STACK)); | 1556 Smi::FromInt(LiveEdit::FUNCTION_REPLACED_ON_ACTIVE_STACK)); |
1546 SetElementNonStrict(result, i, replaced); | 1557 SetElementNonStrict(result, i, replaced); |
1547 } | 1558 } |
(...skipping 24 matching lines...) Expand all Loading... |
1572 Handle<JSArray> shared_info_array_; | 1583 Handle<JSArray> shared_info_array_; |
1573 Handle<JSArray> result_; | 1584 Handle<JSArray> result_; |
1574 bool has_blocked_functions_; | 1585 bool has_blocked_functions_; |
1575 }; | 1586 }; |
1576 | 1587 |
1577 | 1588 |
1578 Handle<JSArray> LiveEdit::CheckAndDropActivations( | 1589 Handle<JSArray> LiveEdit::CheckAndDropActivations( |
1579 Handle<JSArray> shared_info_array, bool do_drop) { | 1590 Handle<JSArray> shared_info_array, bool do_drop) { |
1580 int len = Smi::cast(shared_info_array->length())->value(); | 1591 int len = Smi::cast(shared_info_array->length())->value(); |
1581 | 1592 |
1582 Handle<JSArray> result = Factory::NewJSArray(len); | 1593 Handle<JSArray> result = FACTORY->NewJSArray(len); |
1583 | 1594 |
1584 // Fill the default values. | 1595 // Fill the default values. |
1585 for (int i = 0; i < len; i++) { | 1596 for (int i = 0; i < len; i++) { |
1586 SetElementNonStrict( | 1597 SetElementNonStrict( |
1587 result, | 1598 result, |
1588 i, | 1599 i, |
1589 Handle<Smi>(Smi::FromInt(FUNCTION_AVAILABLE_FOR_PATCH))); | 1600 Handle<Smi>(Smi::FromInt(FUNCTION_AVAILABLE_FOR_PATCH))); |
1590 } | 1601 } |
1591 | 1602 |
1592 | 1603 |
1593 // First check inactive threads. Fail if some functions are blocked there. | 1604 // First check inactive threads. Fail if some functions are blocked there. |
1594 InactiveThreadActivationsChecker inactive_threads_checker(shared_info_array, | 1605 InactiveThreadActivationsChecker inactive_threads_checker(shared_info_array, |
1595 result); | 1606 result); |
1596 ThreadManager::IterateArchivedThreads(&inactive_threads_checker); | 1607 Isolate::Current()->thread_manager()->IterateArchivedThreads( |
| 1608 &inactive_threads_checker); |
1597 if (inactive_threads_checker.HasBlockedFunctions()) { | 1609 if (inactive_threads_checker.HasBlockedFunctions()) { |
1598 return result; | 1610 return result; |
1599 } | 1611 } |
1600 | 1612 |
1601 // Try to drop activations from the current stack. | 1613 // Try to drop activations from the current stack. |
1602 const char* error_message = | 1614 const char* error_message = |
1603 DropActivationsInActiveThread(shared_info_array, result, do_drop); | 1615 DropActivationsInActiveThread(shared_info_array, result, do_drop); |
1604 if (error_message != NULL) { | 1616 if (error_message != NULL) { |
1605 // Add error message as an array extra element. | 1617 // Add error message as an array extra element. |
1606 Vector<const char> vector_message(error_message, StrLength(error_message)); | 1618 Vector<const char> vector_message(error_message, StrLength(error_message)); |
1607 Handle<String> str = Factory::NewStringFromAscii(vector_message); | 1619 Handle<String> str = FACTORY->NewStringFromAscii(vector_message); |
1608 SetElementNonStrict(result, len, str); | 1620 SetElementNonStrict(result, len, str); |
1609 } | 1621 } |
1610 return result; | 1622 return result; |
1611 } | 1623 } |
1612 | 1624 |
1613 | 1625 |
1614 LiveEditFunctionTracker::LiveEditFunctionTracker(FunctionLiteral* fun) { | 1626 LiveEditFunctionTracker::LiveEditFunctionTracker(Isolate* isolate, |
1615 if (active_function_info_listener != NULL) { | 1627 FunctionLiteral* fun) |
1616 active_function_info_listener->FunctionStarted(fun); | 1628 : isolate_(isolate) { |
| 1629 if (isolate_->active_function_info_listener() != NULL) { |
| 1630 isolate_->active_function_info_listener()->FunctionStarted(fun); |
1617 } | 1631 } |
1618 } | 1632 } |
1619 | 1633 |
1620 | 1634 |
1621 LiveEditFunctionTracker::~LiveEditFunctionTracker() { | 1635 LiveEditFunctionTracker::~LiveEditFunctionTracker() { |
1622 if (active_function_info_listener != NULL) { | 1636 if (isolate_->active_function_info_listener() != NULL) { |
1623 active_function_info_listener->FunctionDone(); | 1637 isolate_->active_function_info_listener()->FunctionDone(); |
1624 } | 1638 } |
1625 } | 1639 } |
1626 | 1640 |
1627 | 1641 |
1628 void LiveEditFunctionTracker::RecordFunctionInfo( | 1642 void LiveEditFunctionTracker::RecordFunctionInfo( |
1629 Handle<SharedFunctionInfo> info, FunctionLiteral* lit) { | 1643 Handle<SharedFunctionInfo> info, FunctionLiteral* lit) { |
1630 if (active_function_info_listener != NULL) { | 1644 if (isolate_->active_function_info_listener() != NULL) { |
1631 active_function_info_listener->FunctionInfo(info, lit->scope()); | 1645 isolate_->active_function_info_listener()->FunctionInfo(info, lit->scope()); |
1632 } | 1646 } |
1633 } | 1647 } |
1634 | 1648 |
1635 | 1649 |
1636 void LiveEditFunctionTracker::RecordRootFunctionInfo(Handle<Code> code) { | 1650 void LiveEditFunctionTracker::RecordRootFunctionInfo(Handle<Code> code) { |
1637 active_function_info_listener->FunctionCode(code); | 1651 isolate_->active_function_info_listener()->FunctionCode(code); |
1638 } | 1652 } |
1639 | 1653 |
1640 | 1654 |
1641 bool LiveEditFunctionTracker::IsActive() { | 1655 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { |
1642 return active_function_info_listener != NULL; | 1656 return isolate->active_function_info_listener() != NULL; |
1643 } | 1657 } |
1644 | 1658 |
1645 | 1659 |
1646 #else // ENABLE_DEBUGGER_SUPPORT | 1660 #else // ENABLE_DEBUGGER_SUPPORT |
1647 | 1661 |
1648 // This ifdef-else-endif section provides working or stub implementation of | 1662 // This ifdef-else-endif section provides working or stub implementation of |
1649 // LiveEditFunctionTracker. | 1663 // LiveEditFunctionTracker. |
1650 LiveEditFunctionTracker::LiveEditFunctionTracker(FunctionLiteral* fun) { | 1664 LiveEditFunctionTracker::LiveEditFunctionTracker(Isolate* isolate, |
| 1665 FunctionLiteral* fun) { |
1651 } | 1666 } |
1652 | 1667 |
1653 | 1668 |
1654 LiveEditFunctionTracker::~LiveEditFunctionTracker() { | 1669 LiveEditFunctionTracker::~LiveEditFunctionTracker() { |
1655 } | 1670 } |
1656 | 1671 |
1657 | 1672 |
1658 void LiveEditFunctionTracker::RecordFunctionInfo( | 1673 void LiveEditFunctionTracker::RecordFunctionInfo( |
1659 Handle<SharedFunctionInfo> info, FunctionLiteral* lit) { | 1674 Handle<SharedFunctionInfo> info, FunctionLiteral* lit) { |
1660 } | 1675 } |
1661 | 1676 |
1662 | 1677 |
1663 void LiveEditFunctionTracker::RecordRootFunctionInfo(Handle<Code> code) { | 1678 void LiveEditFunctionTracker::RecordRootFunctionInfo(Handle<Code> code) { |
1664 } | 1679 } |
1665 | 1680 |
1666 | 1681 |
1667 bool LiveEditFunctionTracker::IsActive() { | 1682 bool LiveEditFunctionTracker::IsActive() { |
1668 return false; | 1683 return false; |
1669 } | 1684 } |
1670 | 1685 |
1671 #endif // ENABLE_DEBUGGER_SUPPORT | 1686 #endif // ENABLE_DEBUGGER_SUPPORT |
1672 | 1687 |
1673 | 1688 |
1674 | 1689 |
1675 } } // namespace v8::internal | 1690 } } // namespace v8::internal |
OLD | NEW |