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 617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
628 static Handle<JSValue> WrapInJSValue(Handle<Object> object) { | 628 static Handle<JSValue> WrapInJSValue(Handle<Object> object) { |
629 Handle<JSFunction> constructor = | 629 Handle<JSFunction> constructor = |
630 Isolate::Current()->opaque_reference_function(); | 630 Isolate::Current()->opaque_reference_function(); |
631 Handle<JSValue> result = | 631 Handle<JSValue> result = |
632 Handle<JSValue>::cast(FACTORY->NewJSObject(constructor)); | 632 Handle<JSValue>::cast(FACTORY->NewJSObject(constructor)); |
633 result->set_value(*object); | 633 result->set_value(*object); |
634 return result; | 634 return result; |
635 } | 635 } |
636 | 636 |
637 | 637 |
| 638 static Handle<SharedFunctionInfo> UnwrapSharedFunctionInfoFromJSValue( |
| 639 Handle<JSValue> jsValue) { |
| 640 Object* shared = jsValue->value(); |
| 641 CHECK(shared->IsSharedFunctionInfo()); |
| 642 return Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(shared)); |
| 643 } |
| 644 |
| 645 |
| 646 static int GetArrayLength(Handle<JSArray> array) { |
| 647 Object* length = array->length(); |
| 648 CHECK(length->IsSmi()); |
| 649 return Smi::cast(length)->value(); |
| 650 } |
| 651 |
| 652 |
638 // Simple helper class that creates more or less typed structures over | 653 // Simple helper class that creates more or less typed structures over |
639 // JSArray object. This is an adhoc method of passing structures from C++ | 654 // JSArray object. This is an adhoc method of passing structures from C++ |
640 // to JavaScript. | 655 // to JavaScript. |
641 template<typename S> | 656 template<typename S> |
642 class JSArrayBasedStruct { | 657 class JSArrayBasedStruct { |
643 public: | 658 public: |
644 static S Create() { | 659 static S Create() { |
645 Handle<JSArray> array = FACTORY->NewJSArray(S::kSize_); | 660 Handle<JSArray> array = FACTORY->NewJSArray(S::kSize_); |
646 return S(array); | 661 return S(array); |
647 } | 662 } |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
770 this->SetField(kFunctionNameOffset_, name); | 785 this->SetField(kFunctionNameOffset_, name); |
771 Handle<JSValue> info_holder = WrapInJSValue(info); | 786 Handle<JSValue> info_holder = WrapInJSValue(info); |
772 this->SetField(kSharedInfoOffset_, info_holder); | 787 this->SetField(kSharedInfoOffset_, info_holder); |
773 this->SetSmiValueField(kStartPositionOffset_, start_position); | 788 this->SetSmiValueField(kStartPositionOffset_, start_position); |
774 this->SetSmiValueField(kEndPositionOffset_, end_position); | 789 this->SetSmiValueField(kEndPositionOffset_, end_position); |
775 } | 790 } |
776 Handle<SharedFunctionInfo> GetInfo() { | 791 Handle<SharedFunctionInfo> GetInfo() { |
777 Object* element = this->GetField(kSharedInfoOffset_); | 792 Object* element = this->GetField(kSharedInfoOffset_); |
778 CHECK(element->IsJSValue()); | 793 CHECK(element->IsJSValue()); |
779 Handle<JSValue> value_wrapper(JSValue::cast(element)); | 794 Handle<JSValue> value_wrapper(JSValue::cast(element)); |
780 Handle<Object> raw_result = UnwrapJSValue(value_wrapper); | 795 return UnwrapSharedFunctionInfoFromJSValue(value_wrapper); |
781 CHECK(raw_result->IsSharedFunctionInfo()); | |
782 return Handle<SharedFunctionInfo>::cast(raw_result); | |
783 } | 796 } |
784 | 797 |
785 private: | 798 private: |
786 static const int kFunctionNameOffset_ = 0; | 799 static const int kFunctionNameOffset_ = 0; |
787 static const int kStartPositionOffset_ = 1; | 800 static const int kStartPositionOffset_ = 1; |
788 static const int kEndPositionOffset_ = 2; | 801 static const int kEndPositionOffset_ = 2; |
789 static const int kSharedInfoOffset_ = 3; | 802 static const int kSharedInfoOffset_ = 3; |
790 static const int kSize_ = 4; | 803 static const int kSize_ = 4; |
791 | 804 |
792 friend class JSArrayBasedStruct<SharedInfoWrapper>; | 805 friend class JSArrayBasedStruct<SharedInfoWrapper>; |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
908 CompileScriptForTracker(isolate, script); | 921 CompileScriptForTracker(isolate, script); |
909 isolate->set_active_function_info_listener(NULL); | 922 isolate->set_active_function_info_listener(NULL); |
910 script->set_source(*original_source); | 923 script->set_source(*original_source); |
911 | 924 |
912 return *(listener.GetResult()); | 925 return *(listener.GetResult()); |
913 } | 926 } |
914 | 927 |
915 | 928 |
916 void LiveEdit::WrapSharedFunctionInfos(Handle<JSArray> array) { | 929 void LiveEdit::WrapSharedFunctionInfos(Handle<JSArray> array) { |
917 HandleScope scope; | 930 HandleScope scope; |
918 int len = Smi::cast(array->length())->value(); | 931 int len = GetArrayLength(array); |
919 for (int i = 0; i < len; i++) { | 932 for (int i = 0; i < len; i++) { |
920 Handle<SharedFunctionInfo> info( | 933 Handle<SharedFunctionInfo> info( |
921 SharedFunctionInfo::cast(array->GetElementNoExceptionThrown(i))); | 934 SharedFunctionInfo::cast(array->GetElementNoExceptionThrown(i))); |
922 SharedInfoWrapper info_wrapper = SharedInfoWrapper::Create(); | 935 SharedInfoWrapper info_wrapper = SharedInfoWrapper::Create(); |
923 Handle<String> name_handle(String::cast(info->name())); | 936 Handle<String> name_handle(String::cast(info->name())); |
924 info_wrapper.SetProperties(name_handle, info->start_position(), | 937 info_wrapper.SetProperties(name_handle, info->start_position(), |
925 info->end_position(), info); | 938 info->end_position(), info); |
926 SetElementNonStrict(array, i, info_wrapper.GetJSArray()); | 939 SetElementNonStrict(array, i, info_wrapper.GetJSArray()); |
927 } | 940 } |
928 } | 941 } |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1125 DeoptimizeDependentFunctions(*shared_info); | 1138 DeoptimizeDependentFunctions(*shared_info); |
1126 Isolate::Current()->compilation_cache()->Remove(shared_info); | 1139 Isolate::Current()->compilation_cache()->Remove(shared_info); |
1127 | 1140 |
1128 return HEAP->undefined_value(); | 1141 return HEAP->undefined_value(); |
1129 } | 1142 } |
1130 | 1143 |
1131 | 1144 |
1132 void LiveEdit::SetFunctionScript(Handle<JSValue> function_wrapper, | 1145 void LiveEdit::SetFunctionScript(Handle<JSValue> function_wrapper, |
1133 Handle<Object> script_handle) { | 1146 Handle<Object> script_handle) { |
1134 Handle<SharedFunctionInfo> shared_info = | 1147 Handle<SharedFunctionInfo> shared_info = |
1135 Handle<SharedFunctionInfo>::cast(UnwrapJSValue(function_wrapper)); | 1148 UnwrapSharedFunctionInfoFromJSValue(function_wrapper); |
1136 CHECK(script_handle->IsScript() || script_handle->IsUndefined()); | 1149 CHECK(script_handle->IsScript() || script_handle->IsUndefined()); |
1137 shared_info->set_script(*script_handle); | 1150 shared_info->set_script(*script_handle); |
1138 | 1151 |
1139 Isolate::Current()->compilation_cache()->Remove(shared_info); | 1152 Isolate::Current()->compilation_cache()->Remove(shared_info); |
1140 } | 1153 } |
1141 | 1154 |
1142 | 1155 |
1143 // For a script text change (defined as position_change_array), translates | 1156 // For a script text change (defined as position_change_array), translates |
1144 // position in unchanged text to position in changed text. | 1157 // position in unchanged text to position in changed text. |
1145 // Text change is a set of non-overlapping regions in text, that have changed | 1158 // Text change is a set of non-overlapping regions in text, that have changed |
1146 // their contents and length. It is specified as array of groups of 3 numbers: | 1159 // their contents and length. It is specified as array of groups of 3 numbers: |
1147 // (change_begin, change_end, change_end_new_position). | 1160 // (change_begin, change_end, change_end_new_position). |
1148 // Each group describes a change in text; groups are sorted by change_begin. | 1161 // Each group describes a change in text; groups are sorted by change_begin. |
1149 // Only position in text beyond any changes may be successfully translated. | 1162 // Only position in text beyond any changes may be successfully translated. |
1150 // If a positions is inside some region that changed, result is currently | 1163 // If a positions is inside some region that changed, result is currently |
1151 // undefined. | 1164 // undefined. |
1152 static int TranslatePosition(int original_position, | 1165 static int TranslatePosition(int original_position, |
1153 Handle<JSArray> position_change_array) { | 1166 Handle<JSArray> position_change_array) { |
1154 int position_diff = 0; | 1167 int position_diff = 0; |
1155 int array_len = Smi::cast(position_change_array->length())->value(); | 1168 int array_len = GetArrayLength(position_change_array); |
1156 // TODO(635): binary search may be used here | 1169 // TODO(635): binary search may be used here |
1157 for (int i = 0; i < array_len; i += 3) { | 1170 for (int i = 0; i < array_len; i += 3) { |
1158 Object* element = position_change_array->GetElementNoExceptionThrown(i); | 1171 Object* element = position_change_array->GetElementNoExceptionThrown(i); |
| 1172 CHECK(element->IsSmi()); |
1159 int chunk_start = Smi::cast(element)->value(); | 1173 int chunk_start = Smi::cast(element)->value(); |
1160 if (original_position < chunk_start) { | 1174 if (original_position < chunk_start) { |
1161 break; | 1175 break; |
1162 } | 1176 } |
1163 element = position_change_array->GetElementNoExceptionThrown(i + 1); | 1177 element = position_change_array->GetElementNoExceptionThrown(i + 1); |
| 1178 CHECK(element->IsSmi()); |
1164 int chunk_end = Smi::cast(element)->value(); | 1179 int chunk_end = Smi::cast(element)->value(); |
1165 // Position mustn't be inside a chunk. | 1180 // Position mustn't be inside a chunk. |
1166 ASSERT(original_position >= chunk_end); | 1181 ASSERT(original_position >= chunk_end); |
1167 element = position_change_array->GetElementNoExceptionThrown(i + 2); | 1182 element = position_change_array->GetElementNoExceptionThrown(i + 2); |
| 1183 CHECK(element->IsSmi()); |
1168 int chunk_changed_end = Smi::cast(element)->value(); | 1184 int chunk_changed_end = Smi::cast(element)->value(); |
1169 position_diff = chunk_changed_end - chunk_end; | 1185 position_diff = chunk_changed_end - chunk_end; |
1170 } | 1186 } |
1171 | 1187 |
1172 return original_position + position_diff; | 1188 return original_position + position_diff; |
1173 } | 1189 } |
1174 | 1190 |
1175 | 1191 |
1176 // Auto-growing buffer for writing relocation info code section. This buffer | 1192 // Auto-growing buffer for writing relocation info code section. This buffer |
1177 // is a simplified version of buffer from Assembler. Unlike Assembler, this | 1193 // is a simplified version of buffer from Assembler. Unlike Assembler, this |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1286 // rewrite it inside code object. Instead we have to create a new | 1302 // rewrite it inside code object. Instead we have to create a new |
1287 // code object. | 1303 // code object. |
1288 Handle<Code> result(FACTORY->CopyCode(code, buffer)); | 1304 Handle<Code> result(FACTORY->CopyCode(code, buffer)); |
1289 return result; | 1305 return result; |
1290 } | 1306 } |
1291 } | 1307 } |
1292 | 1308 |
1293 | 1309 |
1294 MaybeObject* LiveEdit::PatchFunctionPositions( | 1310 MaybeObject* LiveEdit::PatchFunctionPositions( |
1295 Handle<JSArray> shared_info_array, Handle<JSArray> position_change_array) { | 1311 Handle<JSArray> shared_info_array, Handle<JSArray> position_change_array) { |
1296 | |
1297 if (!SharedInfoWrapper::IsInstance(shared_info_array)) { | 1312 if (!SharedInfoWrapper::IsInstance(shared_info_array)) { |
1298 return Isolate::Current()->ThrowIllegalOperation(); | 1313 return Isolate::Current()->ThrowIllegalOperation(); |
1299 } | 1314 } |
1300 | 1315 |
1301 SharedInfoWrapper shared_info_wrapper(shared_info_array); | 1316 SharedInfoWrapper shared_info_wrapper(shared_info_array); |
1302 Handle<SharedFunctionInfo> info = shared_info_wrapper.GetInfo(); | 1317 Handle<SharedFunctionInfo> info = shared_info_wrapper.GetInfo(); |
1303 | 1318 |
1304 int old_function_start = info->start_position(); | 1319 int old_function_start = info->start_position(); |
1305 int new_function_start = TranslatePosition(old_function_start, | 1320 int new_function_start = TranslatePosition(old_function_start, |
1306 position_change_array); | 1321 position_change_array); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1376 } | 1391 } |
1377 | 1392 |
1378 | 1393 |
1379 | 1394 |
1380 void LiveEdit::ReplaceRefToNestedFunction( | 1395 void LiveEdit::ReplaceRefToNestedFunction( |
1381 Handle<JSValue> parent_function_wrapper, | 1396 Handle<JSValue> parent_function_wrapper, |
1382 Handle<JSValue> orig_function_wrapper, | 1397 Handle<JSValue> orig_function_wrapper, |
1383 Handle<JSValue> subst_function_wrapper) { | 1398 Handle<JSValue> subst_function_wrapper) { |
1384 | 1399 |
1385 Handle<SharedFunctionInfo> parent_shared = | 1400 Handle<SharedFunctionInfo> parent_shared = |
1386 Handle<SharedFunctionInfo>::cast(UnwrapJSValue(parent_function_wrapper)); | 1401 UnwrapSharedFunctionInfoFromJSValue(parent_function_wrapper); |
1387 Handle<SharedFunctionInfo> orig_shared = | 1402 Handle<SharedFunctionInfo> orig_shared = |
1388 Handle<SharedFunctionInfo>::cast(UnwrapJSValue(orig_function_wrapper)); | 1403 UnwrapSharedFunctionInfoFromJSValue(orig_function_wrapper); |
1389 Handle<SharedFunctionInfo> subst_shared = | 1404 Handle<SharedFunctionInfo> subst_shared = |
1390 Handle<SharedFunctionInfo>::cast(UnwrapJSValue(subst_function_wrapper)); | 1405 UnwrapSharedFunctionInfoFromJSValue(subst_function_wrapper); |
1391 | 1406 |
1392 for (RelocIterator it(parent_shared->code()); !it.done(); it.next()) { | 1407 for (RelocIterator it(parent_shared->code()); !it.done(); it.next()) { |
1393 if (it.rinfo()->rmode() == RelocInfo::EMBEDDED_OBJECT) { | 1408 if (it.rinfo()->rmode() == RelocInfo::EMBEDDED_OBJECT) { |
1394 if (it.rinfo()->target_object() == *orig_shared) { | 1409 if (it.rinfo()->target_object() == *orig_shared) { |
1395 it.rinfo()->set_target_object(*subst_shared); | 1410 it.rinfo()->set_target_object(*subst_shared); |
1396 } | 1411 } |
1397 } | 1412 } |
1398 } | 1413 } |
1399 } | 1414 } |
1400 | 1415 |
1401 | 1416 |
1402 // Check an activation against list of functions. If there is a function | 1417 // Check an activation against list of functions. If there is a function |
1403 // that matches, its status in result array is changed to status argument value. | 1418 // that matches, its status in result array is changed to status argument value. |
1404 static bool CheckActivation(Handle<JSArray> shared_info_array, | 1419 static bool CheckActivation(Handle<JSArray> shared_info_array, |
1405 Handle<JSArray> result, | 1420 Handle<JSArray> result, |
1406 StackFrame* frame, | 1421 StackFrame* frame, |
1407 LiveEdit::FunctionPatchabilityStatus status) { | 1422 LiveEdit::FunctionPatchabilityStatus status) { |
1408 if (!frame->is_java_script()) return false; | 1423 if (!frame->is_java_script()) return false; |
1409 | 1424 |
1410 Handle<JSFunction> function( | 1425 Handle<JSFunction> function( |
1411 JSFunction::cast(JavaScriptFrame::cast(frame)->function())); | 1426 JSFunction::cast(JavaScriptFrame::cast(frame)->function())); |
1412 | 1427 |
1413 int len = Smi::cast(shared_info_array->length())->value(); | 1428 int len = GetArrayLength(shared_info_array); |
1414 for (int i = 0; i < len; i++) { | 1429 for (int i = 0; i < len; i++) { |
1415 JSValue* wrapper = | 1430 Object* element = shared_info_array->GetElementNoExceptionThrown(i); |
1416 JSValue::cast(shared_info_array->GetElementNoExceptionThrown(i)); | 1431 CHECK(element->IsJSValue()); |
1417 Handle<SharedFunctionInfo> shared( | 1432 Handle<JSValue> jsvalue(JSValue::cast(element)); |
1418 SharedFunctionInfo::cast(wrapper->value())); | 1433 Handle<SharedFunctionInfo> shared = |
| 1434 UnwrapSharedFunctionInfoFromJSValue(jsvalue); |
1419 | 1435 |
1420 if (function->shared() == *shared || IsInlined(*function, *shared)) { | 1436 if (function->shared() == *shared || IsInlined(*function, *shared)) { |
1421 SetElementNonStrict(result, i, Handle<Smi>(Smi::FromInt(status))); | 1437 SetElementNonStrict(result, i, Handle<Smi>(Smi::FromInt(status))); |
1422 return true; | 1438 return true; |
1423 } | 1439 } |
1424 } | 1440 } |
1425 return false; | 1441 return false; |
1426 } | 1442 } |
1427 | 1443 |
1428 | 1444 |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1716 Handle<JSArray> shared_info_array, Handle<JSArray> result, bool do_drop, | 1732 Handle<JSArray> shared_info_array, Handle<JSArray> result, bool do_drop, |
1717 Zone* zone) { | 1733 Zone* zone) { |
1718 MultipleFunctionTarget target(shared_info_array, result); | 1734 MultipleFunctionTarget target(shared_info_array, result); |
1719 | 1735 |
1720 const char* message = | 1736 const char* message = |
1721 DropActivationsInActiveThreadImpl(target, do_drop, zone); | 1737 DropActivationsInActiveThreadImpl(target, do_drop, zone); |
1722 if (message) { | 1738 if (message) { |
1723 return message; | 1739 return message; |
1724 } | 1740 } |
1725 | 1741 |
1726 int array_len = Smi::cast(shared_info_array->length())->value(); | 1742 int array_len = GetArrayLength(shared_info_array); |
1727 | 1743 |
1728 // Replace "blocked on active" with "replaced on active" status. | 1744 // Replace "blocked on active" with "replaced on active" status. |
1729 for (int i = 0; i < array_len; i++) { | 1745 for (int i = 0; i < array_len; i++) { |
1730 if (result->GetElement(i) == | 1746 if (result->GetElement(i) == |
1731 Smi::FromInt(LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) { | 1747 Smi::FromInt(LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) { |
1732 Handle<Object> replaced( | 1748 Handle<Object> replaced( |
1733 Smi::FromInt(LiveEdit::FUNCTION_REPLACED_ON_ACTIVE_STACK)); | 1749 Smi::FromInt(LiveEdit::FUNCTION_REPLACED_ON_ACTIVE_STACK)); |
1734 SetElementNonStrict(result, i, replaced); | 1750 SetElementNonStrict(result, i, replaced); |
1735 } | 1751 } |
1736 } | 1752 } |
(...skipping 21 matching lines...) Expand all Loading... |
1758 | 1774 |
1759 private: | 1775 private: |
1760 Handle<JSArray> shared_info_array_; | 1776 Handle<JSArray> shared_info_array_; |
1761 Handle<JSArray> result_; | 1777 Handle<JSArray> result_; |
1762 bool has_blocked_functions_; | 1778 bool has_blocked_functions_; |
1763 }; | 1779 }; |
1764 | 1780 |
1765 | 1781 |
1766 Handle<JSArray> LiveEdit::CheckAndDropActivations( | 1782 Handle<JSArray> LiveEdit::CheckAndDropActivations( |
1767 Handle<JSArray> shared_info_array, bool do_drop, Zone* zone) { | 1783 Handle<JSArray> shared_info_array, bool do_drop, Zone* zone) { |
1768 int len = Smi::cast(shared_info_array->length())->value(); | 1784 int len = GetArrayLength(shared_info_array); |
1769 | 1785 |
1770 Handle<JSArray> result = FACTORY->NewJSArray(len); | 1786 Handle<JSArray> result = FACTORY->NewJSArray(len); |
1771 | 1787 |
1772 // Fill the default values. | 1788 // Fill the default values. |
1773 for (int i = 0; i < len; i++) { | 1789 for (int i = 0; i < len; i++) { |
1774 SetElementNonStrict( | 1790 SetElementNonStrict( |
1775 result, | 1791 result, |
1776 i, | 1792 i, |
1777 Handle<Smi>(Smi::FromInt(FUNCTION_AVAILABLE_FOR_PATCH))); | 1793 Handle<Smi>(Smi::FromInt(FUNCTION_AVAILABLE_FOR_PATCH))); |
1778 } | 1794 } |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1905 | 1921 |
1906 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { | 1922 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { |
1907 return false; | 1923 return false; |
1908 } | 1924 } |
1909 | 1925 |
1910 #endif // ENABLE_DEBUGGER_SUPPORT | 1926 #endif // ENABLE_DEBUGGER_SUPPORT |
1911 | 1927 |
1912 | 1928 |
1913 | 1929 |
1914 } } // namespace v8::internal | 1930 } } // namespace v8::internal |
OLD | NEW |