Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(221)

Side by Side Diff: src/liveedit.cc

Issue 10914262: Add checks to live edit. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698