OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 | 5 |
6 #include "src/v8.h" | 6 #include "src/v8.h" |
7 | 7 |
8 #include "src/liveedit.h" | 8 #include "src/liveedit.h" |
9 | 9 |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 1075 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1086 m_output->set(m_pos, fun); | 1086 m_output->set(m_pos, fun); |
1087 m_pos++; | 1087 m_pos++; |
1088 } | 1088 } |
1089 private: | 1089 private: |
1090 Handle<FixedArray> m_output; | 1090 Handle<FixedArray> m_output; |
1091 int m_pos; | 1091 int m_pos; |
1092 }; | 1092 }; |
1093 }; | 1093 }; |
1094 | 1094 |
1095 | 1095 |
1096 namespace { | |
1097 | |
1098 // Check whether the code is natural function code (not a lazy-compile stub | |
1099 // code). | |
1100 bool IsJSFunctionCode(Code* code) { return code->kind() == Code::FUNCTION; } | |
1101 | |
1102 | |
1103 // Returns true if an instance of candidate were inlined into function's code. | |
1104 bool IsInlined(JSFunction* function, SharedFunctionInfo* candidate) { | |
1105 DisallowHeapAllocation no_gc; | |
1106 | |
1107 if (function->code()->kind() != Code::OPTIMIZED_FUNCTION) return false; | |
1108 | |
1109 DeoptimizationInputData* const data = | |
1110 DeoptimizationInputData::cast(function->code()->deoptimization_data()); | |
1111 if (data != function->GetIsolate()->heap()->empty_fixed_array()) { | |
1112 FixedArray* const literals = data->LiteralArray(); | |
1113 int const inlined_count = data->InlinedFunctionCount()->value(); | |
1114 for (int i = 0; i < inlined_count; ++i) { | |
1115 if (SharedFunctionInfo::cast(literals->get(i)) == candidate) { | |
1116 return true; | |
1117 } | |
1118 } | |
1119 } | |
1120 | |
1121 return false; | |
1122 } | |
1123 | |
1124 } // namespace | |
1125 | |
1126 | |
1127 // Marks code that shares the same shared function info or has inlined | 1096 // Marks code that shares the same shared function info or has inlined |
1128 // code that shares the same function info. | 1097 // code that shares the same function info. |
1129 class DependentFunctionMarker: public OptimizedFunctionVisitor { | 1098 class DependentFunctionMarker: public OptimizedFunctionVisitor { |
1130 public: | 1099 public: |
1131 SharedFunctionInfo* shared_info_; | 1100 SharedFunctionInfo* shared_info_; |
1132 bool found_; | 1101 bool found_; |
1133 | 1102 |
1134 explicit DependentFunctionMarker(SharedFunctionInfo* shared_info) | 1103 explicit DependentFunctionMarker(SharedFunctionInfo* shared_info) |
1135 : shared_info_(shared_info), found_(false) { } | 1104 : shared_info_(shared_info), found_(false) { } |
1136 | 1105 |
1137 virtual void EnterContext(Context* context) { } // Don't care. | 1106 virtual void EnterContext(Context* context) { } // Don't care. |
1138 virtual void LeaveContext(Context* context) { } // Don't care. | 1107 virtual void LeaveContext(Context* context) { } // Don't care. |
1139 virtual void VisitFunction(JSFunction* function) { | 1108 virtual void VisitFunction(JSFunction* function) { |
1140 // It should be guaranteed by the iterator that everything is optimized. | 1109 // It should be guaranteed by the iterator that everything is optimized. |
1141 DCHECK(function->code()->kind() == Code::OPTIMIZED_FUNCTION); | 1110 DCHECK(function->code()->kind() == Code::OPTIMIZED_FUNCTION); |
1142 if (shared_info_ == function->shared() || | 1111 if (function->Inlines(shared_info_)) { |
1143 IsInlined(function, shared_info_)) { | |
1144 // Mark the code for deoptimization. | 1112 // Mark the code for deoptimization. |
1145 function->code()->set_marked_for_deoptimization(true); | 1113 function->code()->set_marked_for_deoptimization(true); |
1146 found_ = true; | 1114 found_ = true; |
1147 } | 1115 } |
1148 } | 1116 } |
1149 }; | 1117 }; |
1150 | 1118 |
1151 | 1119 |
1152 static void DeoptimizeDependentFunctions(SharedFunctionInfo* function_info) { | 1120 static void DeoptimizeDependentFunctions(SharedFunctionInfo* function_info) { |
1153 DisallowHeapAllocation no_allocation; | 1121 DisallowHeapAllocation no_allocation; |
(...skipping 11 matching lines...) Expand all Loading... |
1165 void LiveEdit::ReplaceFunctionCode( | 1133 void LiveEdit::ReplaceFunctionCode( |
1166 Handle<JSArray> new_compile_info_array, | 1134 Handle<JSArray> new_compile_info_array, |
1167 Handle<JSArray> shared_info_array) { | 1135 Handle<JSArray> shared_info_array) { |
1168 Isolate* isolate = new_compile_info_array->GetIsolate(); | 1136 Isolate* isolate = new_compile_info_array->GetIsolate(); |
1169 | 1137 |
1170 FunctionInfoWrapper compile_info_wrapper(new_compile_info_array); | 1138 FunctionInfoWrapper compile_info_wrapper(new_compile_info_array); |
1171 SharedInfoWrapper shared_info_wrapper(shared_info_array); | 1139 SharedInfoWrapper shared_info_wrapper(shared_info_array); |
1172 | 1140 |
1173 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo(); | 1141 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo(); |
1174 | 1142 |
1175 if (IsJSFunctionCode(shared_info->code())) { | 1143 if (shared_info->code()->kind() == Code::FUNCTION) { |
1176 Handle<Code> code = compile_info_wrapper.GetFunctionCode(); | 1144 Handle<Code> code = compile_info_wrapper.GetFunctionCode(); |
1177 ReplaceCodeObject(Handle<Code>(shared_info->code()), code); | 1145 ReplaceCodeObject(Handle<Code>(shared_info->code()), code); |
1178 Handle<Object> code_scope_info = compile_info_wrapper.GetCodeScopeInfo(); | 1146 Handle<Object> code_scope_info = compile_info_wrapper.GetCodeScopeInfo(); |
1179 if (code_scope_info->IsFixedArray()) { | 1147 if (code_scope_info->IsFixedArray()) { |
1180 shared_info->set_scope_info(ScopeInfo::cast(*code_scope_info)); | 1148 shared_info->set_scope_info(ScopeInfo::cast(*code_scope_info)); |
1181 } | 1149 } |
1182 shared_info->DisableOptimization(kLiveEdit); | 1150 shared_info->DisableOptimization(kLiveEdit); |
1183 // Update the type feedback vector, if needed. | 1151 // Update the type feedback vector, if needed. |
1184 MaybeHandle<TypeFeedbackVector> feedback_vector = | 1152 MaybeHandle<TypeFeedbackVector> feedback_vector = |
1185 compile_info_wrapper.GetFeedbackVector(); | 1153 compile_info_wrapper.GetFeedbackVector(); |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1396 position_change_array); | 1364 position_change_array); |
1397 int new_function_end = TranslatePosition(info->end_position(), | 1365 int new_function_end = TranslatePosition(info->end_position(), |
1398 position_change_array); | 1366 position_change_array); |
1399 int new_function_token_pos = | 1367 int new_function_token_pos = |
1400 TranslatePosition(info->function_token_position(), position_change_array); | 1368 TranslatePosition(info->function_token_position(), position_change_array); |
1401 | 1369 |
1402 info->set_start_position(new_function_start); | 1370 info->set_start_position(new_function_start); |
1403 info->set_end_position(new_function_end); | 1371 info->set_end_position(new_function_end); |
1404 info->set_function_token_position(new_function_token_pos); | 1372 info->set_function_token_position(new_function_token_pos); |
1405 | 1373 |
1406 if (IsJSFunctionCode(info->code())) { | 1374 if (info->code()->kind() == Code::FUNCTION) { |
1407 // Patch relocation info section of the code. | 1375 // Patch relocation info section of the code. |
1408 Handle<Code> patched_code = PatchPositionsInCode(Handle<Code>(info->code()), | 1376 Handle<Code> patched_code = PatchPositionsInCode(Handle<Code>(info->code()), |
1409 position_change_array); | 1377 position_change_array); |
1410 if (*patched_code != info->code()) { | 1378 if (*patched_code != info->code()) { |
1411 // Replace all references to the code across the heap. In particular, | 1379 // Replace all references to the code across the heap. In particular, |
1412 // some stubs may refer to this code and this code may be being executed | 1380 // some stubs may refer to this code and this code may be being executed |
1413 // on stack (it is safe to substitute the code object on stack, because | 1381 // on stack (it is safe to substitute the code object on stack, because |
1414 // we only change the structure of rinfo and leave instructions | 1382 // we only change the structure of rinfo and leave instructions |
1415 // untouched). | 1383 // untouched). |
1416 ReplaceCodeObject(Handle<Code>(info->code()), patched_code); | 1384 ReplaceCodeObject(Handle<Code>(info->code()), patched_code); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1501 Isolate* isolate = shared_info_array->GetIsolate(); | 1469 Isolate* isolate = shared_info_array->GetIsolate(); |
1502 int len = GetArrayLength(shared_info_array); | 1470 int len = GetArrayLength(shared_info_array); |
1503 for (int i = 0; i < len; i++) { | 1471 for (int i = 0; i < len; i++) { |
1504 HandleScope scope(isolate); | 1472 HandleScope scope(isolate); |
1505 Handle<Object> element = | 1473 Handle<Object> element = |
1506 Object::GetElement(isolate, shared_info_array, i).ToHandleChecked(); | 1474 Object::GetElement(isolate, shared_info_array, i).ToHandleChecked(); |
1507 Handle<JSValue> jsvalue = Handle<JSValue>::cast(element); | 1475 Handle<JSValue> jsvalue = Handle<JSValue>::cast(element); |
1508 Handle<SharedFunctionInfo> shared = | 1476 Handle<SharedFunctionInfo> shared = |
1509 UnwrapSharedFunctionInfoFromJSValue(jsvalue); | 1477 UnwrapSharedFunctionInfoFromJSValue(jsvalue); |
1510 | 1478 |
1511 if (function->shared() == *shared || IsInlined(*function, *shared)) { | 1479 if (function->Inlines(*shared)) { |
1512 SetElementSloppy(result, i, Handle<Smi>(Smi::FromInt(status), isolate)); | 1480 SetElementSloppy(result, i, Handle<Smi>(Smi::FromInt(status), isolate)); |
1513 return true; | 1481 return true; |
1514 } | 1482 } |
1515 } | 1483 } |
1516 return false; | 1484 return false; |
1517 } | 1485 } |
1518 | 1486 |
1519 | 1487 |
1520 // Iterates over handler chain and removes all elements that are inside | 1488 // Iterates over handler chain and removes all elements that are inside |
1521 // frames being dropped. | 1489 // frames being dropped. |
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2052 isolate_->active_function_info_listener()->FunctionCode(code); | 2020 isolate_->active_function_info_listener()->FunctionCode(code); |
2053 } | 2021 } |
2054 | 2022 |
2055 | 2023 |
2056 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { | 2024 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { |
2057 return isolate->active_function_info_listener() != NULL; | 2025 return isolate->active_function_info_listener() != NULL; |
2058 } | 2026 } |
2059 | 2027 |
2060 } // namespace internal | 2028 } // namespace internal |
2061 } // namespace v8 | 2029 } // namespace v8 |
OLD | NEW |