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