48 #ifdef ENABLE_DEBUGGER_SUPPORT
51 void SetElementNonStrict(Handle<JSObject>
object,
53 Handle<Object> value) {
57 Handle<Object> no_failure =
59 ASSERT(!no_failure.is_null());
69 explicit Differencer(Comparator::Input* input)
70 : input_(input), len1_(input->GetLength1()), len2_(input->GetLength2()) {
71 buffer_ = NewArray<int>(len1_ * len2_);
78 int array_size = len1_ * len2_;
79 for (
int i = 0; i < array_size; i++) {
87 CompareUpToTail(0, 0);
90 void SaveResult(Comparator::Output* chunk_writer) {
91 ResultWriter writer(chunk_writer);
98 Direction dir = get_direction(pos1, pos2);
118 writer.skip1(len1_ - pos1);
123 writer.skip2(len2_ - pos2);
132 Comparator::Input* input_;
143 MAX_DIRECTION_FLAG_VALUE = SKIP_ANY
148 int CompareUpToTail(
int pos1,
int pos2) {
151 int cached_res = get_value4(pos1, pos2);
152 if (cached_res == kEmptyCellValue) {
155 if (input_->Equals(pos1, pos2)) {
156 res = CompareUpToTail(pos1 + 1, pos2 + 1);
159 int res1 = CompareUpToTail(pos1 + 1, pos2) +
160 (1 << kDirectionSizeBits);
161 int res2 = CompareUpToTail(pos1, pos2 + 1) +
162 (1 << kDirectionSizeBits);
166 }
else if (res1 < res2) {
174 set_value4_and_dir(pos1, pos2, res, dir);
179 return (len1_ - pos1) << kDirectionSizeBits;
182 return (len2_ - pos2) << kDirectionSizeBits;
186 inline int& get_cell(
int i1,
int i2) {
187 return buffer_[i1 + i2 * len1_];
191 void set_value4_and_dir(
int i1,
int i2,
int value4, Direction dir) {
192 ASSERT((value4 & kDirectionMask) == 0);
193 get_cell(i1, i2) = value4 | dir;
196 int get_value4(
int i1,
int i2) {
197 return get_cell(i1, i2) & (
kMaxUInt32 ^ kDirectionMask);
199 Direction get_direction(
int i1,
int i2) {
200 return static_cast<Direction
>(get_cell(i1, i2) & kDirectionMask);
203 static const int kDirectionSizeBits = 2;
204 static const int kDirectionMask = (1 << kDirectionSizeBits) - 1;
205 static const int kEmptyCellValue = -1 << kDirectionSizeBits;
209 void StaticAssertHolder() {
210 STATIC_ASSERT(MAX_DIRECTION_FLAG_VALUE < (1 << kDirectionSizeBits));
215 explicit ResultWriter(Comparator::Output* chunk_writer)
216 : chunk_writer_(chunk_writer), pos1_(0), pos2_(0),
217 pos1_begin_(-1), pos2_begin_(-1), has_open_chunk_(
false) {
224 void skip1(
int len1) {
228 void skip2(
int len2) {
237 Comparator::Output* chunk_writer_;
242 bool has_open_chunk_;
245 if (!has_open_chunk_) {
248 has_open_chunk_ =
true;
253 if (has_open_chunk_) {
254 chunk_writer_->AddChunk(pos1_begin_, pos2_begin_,
255 pos1_ - pos1_begin_, pos2_ - pos2_begin_);
256 has_open_chunk_ =
false;
263 void Comparator::CalculateDifference(Comparator::Input* input,
264 Comparator::Output* result_writer) {
265 Differencer differencer(input);
266 differencer.Initialize();
267 differencer.FillTable();
268 differencer.SaveResult(result_writer);
272 static bool CompareSubstrings(Handle<String>
s1,
int pos1,
273 Handle<String>
s2,
int pos2,
int len) {
274 for (
int i = 0; i < len; i++) {
275 if (s1->Get(i + pos1) != s2->Get(i + pos2)) {
287 class SubrangableInput :
public Comparator::Input {
289 virtual void SetSubrange1(
int offset,
int len) = 0;
290 virtual void SetSubrange2(
int offset,
int len) = 0;
294 class SubrangableOutput :
public Comparator::Output {
296 virtual void SetSubrange1(
int offset,
int len) = 0;
297 virtual void SetSubrange2(
int offset,
int len) = 0;
301 static int min(
int a,
int b) {
302 return a < b ? a : b;
308 static void NarrowDownInput(SubrangableInput* input,
309 SubrangableOutput* output) {
310 const int len1 = input->GetLength1();
311 const int len2 = input->GetLength2();
313 int common_prefix_len;
314 int common_suffix_len;
317 common_prefix_len = 0;
318 int prefix_limit = min(len1, len2);
319 while (common_prefix_len < prefix_limit &&
320 input->Equals(common_prefix_len, common_prefix_len)) {
324 common_suffix_len = 0;
325 int suffix_limit = min(len1 - common_prefix_len, len2 - common_prefix_len);
327 while (common_suffix_len < suffix_limit &&
328 input->Equals(len1 - common_suffix_len - 1,
329 len2 - common_suffix_len - 1)) {
334 if (common_prefix_len > 0 || common_suffix_len > 0) {
335 int new_len1 = len1 - common_suffix_len - common_prefix_len;
336 int new_len2 = len2 - common_suffix_len - common_prefix_len;
338 input->SetSubrange1(common_prefix_len, new_len1);
339 input->SetSubrange2(common_prefix_len, new_len2);
341 output->SetSubrange1(common_prefix_len, new_len1);
342 output->SetSubrange2(common_prefix_len, new_len2);
349 class CompareOutputArrayWriter {
351 CompareOutputArrayWriter()
352 : array_(
FACTORY->NewJSArray(10)), current_size_(0) {}
354 Handle<JSArray> GetResult() {
358 void WriteChunk(
int char_pos1,
int char_pos2,
int char_len1,
int char_len2) {
359 SetElementNonStrict(array_,
362 SetElementNonStrict(array_,
365 SetElementNonStrict(array_,
372 Handle<JSArray> array_;
380 class TokensCompareInput :
public Comparator::Input {
382 TokensCompareInput(Handle<String> s1,
int offset1,
int len1,
383 Handle<String> s2,
int offset2,
int len2)
384 : s1_(s1), offset1_(offset1), len1_(len1),
385 s2_(s2), offset2_(offset2), len2_(len2) {
387 virtual int GetLength1() {
390 virtual int GetLength2() {
393 bool Equals(
int index1,
int index2) {
394 return s1_->Get(offset1_ + index1) == s2_->Get(offset2_ + index2);
409 class TokensCompareOutput :
public Comparator::Output {
411 TokensCompareOutput(CompareOutputArrayWriter* array_writer,
412 int offset1,
int offset2)
413 : array_writer_(array_writer), offset1_(offset1), offset2_(offset2) {
416 void AddChunk(
int pos1,
int pos2,
int len1,
int len2) {
417 array_writer_->WriteChunk(pos1 + offset1_, pos2 + offset2_, len1, len2);
421 CompareOutputArrayWriter* array_writer_;
429 class LineEndsWrapper {
431 explicit LineEndsWrapper(Handle<String>
string)
433 string_len_(string->length()) {
436 return ends_array_->length() + 1;
440 int GetLineStart(
int index) {
444 return GetLineEnd(index - 1);
447 int GetLineEnd(
int index) {
448 if (index == ends_array_->length()) {
454 return GetPosAfterNewLine(index);
459 Handle<FixedArray> ends_array_;
462 int GetPosAfterNewLine(
int index) {
463 return Smi::cast(ends_array_->get(index))->value() + 1;
469 class LineArrayCompareInput :
public SubrangableInput {
471 LineArrayCompareInput(Handle<String> s1, Handle<String> s2,
472 LineEndsWrapper line_ends1, LineEndsWrapper line_ends2)
473 : s1_(s1), s2_(s2), line_ends1_(line_ends1),
474 line_ends2_(line_ends2),
475 subrange_offset1_(0), subrange_offset2_(0),
476 subrange_len1_(line_ends1_.length()),
477 subrange_len2_(line_ends2_.length()) {
480 return subrange_len1_;
483 return subrange_len2_;
485 bool Equals(
int index1,
int index2) {
486 index1 += subrange_offset1_;
487 index2 += subrange_offset2_;
489 int line_start1 = line_ends1_.GetLineStart(index1);
490 int line_start2 = line_ends2_.GetLineStart(index2);
491 int line_end1 = line_ends1_.GetLineEnd(index1);
492 int line_end2 = line_ends2_.GetLineEnd(index2);
493 int len1 = line_end1 - line_start1;
494 int len2 = line_end2 - line_start2;
498 return CompareSubstrings(s1_, line_start1, s2_, line_start2,
501 void SetSubrange1(
int offset,
int len) {
502 subrange_offset1_ = offset;
503 subrange_len1_ = len;
505 void SetSubrange2(
int offset,
int len) {
506 subrange_offset2_ = offset;
507 subrange_len2_ = len;
513 LineEndsWrapper line_ends1_;
514 LineEndsWrapper line_ends2_;
515 int subrange_offset1_;
516 int subrange_offset2_;
524 class TokenizingLineArrayCompareOutput :
public SubrangableOutput {
526 TokenizingLineArrayCompareOutput(LineEndsWrapper line_ends1,
527 LineEndsWrapper line_ends2,
528 Handle<String> s1, Handle<String> s2)
529 : line_ends1_(line_ends1), line_ends2_(line_ends2), s1_(s1), s2_(s2),
530 subrange_offset1_(0), subrange_offset2_(0) {
533 void AddChunk(
int line_pos1,
int line_pos2,
int line_len1,
int line_len2) {
534 line_pos1 += subrange_offset1_;
535 line_pos2 += subrange_offset2_;
537 int char_pos1 = line_ends1_.GetLineStart(line_pos1);
538 int char_pos2 = line_ends2_.GetLineStart(line_pos2);
539 int char_len1 = line_ends1_.GetLineStart(line_pos1 + line_len1) - char_pos1;
540 int char_len2 = line_ends2_.GetLineStart(line_pos2 + line_len2) - char_pos2;
542 if (char_len1 < CHUNK_LEN_LIMIT && char_len2 < CHUNK_LEN_LIMIT) {
544 HandleScope subTaskScope;
546 TokensCompareInput tokens_input(s1_, char_pos1, char_len1,
547 s2_, char_pos2, char_len2);
548 TokensCompareOutput tokens_output(&array_writer_, char_pos1,
551 Comparator::CalculateDifference(&tokens_input, &tokens_output);
553 array_writer_.WriteChunk(char_pos1, char_pos2, char_len1, char_len2);
556 void SetSubrange1(
int offset,
int len) {
557 subrange_offset1_ = offset;
559 void SetSubrange2(
int offset,
int len) {
560 subrange_offset2_ = offset;
563 Handle<JSArray> GetResult() {
564 return array_writer_.GetResult();
568 static const int CHUNK_LEN_LIMIT = 800;
570 CompareOutputArrayWriter array_writer_;
571 LineEndsWrapper line_ends1_;
572 LineEndsWrapper line_ends2_;
575 int subrange_offset1_;
576 int subrange_offset2_;
580 Handle<JSArray> LiveEdit::CompareStrings(Handle<String> s1,
585 LineEndsWrapper line_ends1(s1);
586 LineEndsWrapper line_ends2(s2);
588 LineArrayCompareInput input(s1, s2, line_ends1, line_ends2);
589 TokenizingLineArrayCompareOutput output(line_ends1, line_ends2, s1, s2);
591 NarrowDownInput(&input, &output);
593 Comparator::CalculateDifference(&input, &output);
595 return output.GetResult();
599 static void CompileScriptForTracker(Isolate* isolate, Handle<Script> script) {
601 PostponeInterruptsScope postpone(isolate);
604 CompilationInfoWithZone info(script);
609 LiveEditFunctionTracker tracker(info.isolate(), info.function());
610 if (Compiler::MakeCodeForLiveEdit(&info)) {
611 ASSERT(!info.code().is_null());
612 tracker.RecordRootFunctionInfo(info.code());
614 info.isolate()->StackOverflow();
621 static Handle<Object> UnwrapJSValue(Handle<JSValue> jsValue) {
622 return Handle<Object>(jsValue->value());
628 static Handle<JSValue> WrapInJSValue(Handle<Object>
object) {
629 Handle<JSFunction> constructor =
630 Isolate::Current()->opaque_reference_function();
631 Handle<JSValue> result =
633 result->set_value(*
object);
638 static Handle<SharedFunctionInfo> UnwrapSharedFunctionInfoFromJSValue(
639 Handle<JSValue> jsValue) {
640 Object* shared = jsValue->value();
641 CHECK(shared->IsSharedFunctionInfo());
646 static int GetArrayLength(Handle<JSArray> array) {
647 Object* length = array->length();
648 CHECK(length->IsSmi());
657 class JSArrayBasedStruct {
660 Handle<JSArray> array =
FACTORY->NewJSArray(S::kSize_);
663 static S cast(
Object*
object) {
665 Handle<JSArray> array_handle(array);
666 return S(array_handle);
668 explicit JSArrayBasedStruct(Handle<JSArray> array) : array_(array) {
670 Handle<JSArray> GetJSArray() {
675 void SetField(
int field_position, Handle<Object> value) {
676 SetElementNonStrict(array_, field_position, value);
678 void SetSmiValueField(
int field_position,
int value) {
679 SetElementNonStrict(array_,
683 Object* GetField(
int field_position) {
684 return array_->GetElementNoExceptionThrown(field_position);
686 int GetSmiValueField(
int field_position) {
687 Object* res = GetField(field_position);
693 Handle<JSArray> array_;
700 class FunctionInfoWrapper :
public JSArrayBasedStruct<FunctionInfoWrapper> {
702 explicit FunctionInfoWrapper(Handle<JSArray> array)
703 : JSArrayBasedStruct<FunctionInfoWrapper>(array) {
705 void SetInitialProperties(Handle<String> name,
int start_position,
706 int end_position,
int param_num,
int parent_index) {
708 this->SetField(kFunctionNameOffset_, name);
709 this->SetSmiValueField(kStartPositionOffset_, start_position);
710 this->SetSmiValueField(kEndPositionOffset_, end_position);
711 this->SetSmiValueField(kParamNumOffset_, param_num);
712 this->SetSmiValueField(kParentIndexOffset_, parent_index);
714 void SetFunctionCode(Handle<Code> function_code,
715 Handle<Object> code_scope_info) {
716 Handle<JSValue> code_wrapper = WrapInJSValue(function_code);
717 this->SetField(kCodeOffset_, code_wrapper);
719 Handle<JSValue> scope_wrapper = WrapInJSValue(code_scope_info);
720 this->SetField(kCodeScopeInfoOffset_, scope_wrapper);
722 void SetOuterScopeInfo(Handle<Object> scope_info_array) {
723 this->SetField(kOuterScopeInfoOffset_, scope_info_array);
725 void SetSharedFunctionInfo(Handle<SharedFunctionInfo> info) {
726 Handle<JSValue> info_holder = WrapInJSValue(info);
727 this->SetField(kSharedFunctionInfoOffset_, info_holder);
729 int GetParentIndex() {
730 return this->GetSmiValueField(kParentIndexOffset_);
732 Handle<Code> GetFunctionCode() {
733 Object* element = this->GetField(kCodeOffset_);
734 CHECK(element->IsJSValue());
736 Handle<Object> raw_result = UnwrapJSValue(value_wrapper);
737 CHECK(raw_result->IsCode());
740 Handle<Object> GetCodeScopeInfo() {
741 Object* element = this->GetField(kCodeScopeInfoOffset_);
742 CHECK(element->IsJSValue());
743 return UnwrapJSValue(Handle<JSValue>(
JSValue::cast(element)));
745 int GetStartPosition() {
746 return this->GetSmiValueField(kStartPositionOffset_);
748 int GetEndPosition() {
749 return this->GetSmiValueField(kEndPositionOffset_);
753 static const int kFunctionNameOffset_ = 0;
754 static const int kStartPositionOffset_ = 1;
755 static const int kEndPositionOffset_ = 2;
756 static const int kParamNumOffset_ = 3;
757 static const int kCodeOffset_ = 4;
758 static const int kCodeScopeInfoOffset_ = 5;
759 static const int kOuterScopeInfoOffset_ = 6;
760 static const int kParentIndexOffset_ = 7;
761 static const int kSharedFunctionInfoOffset_ = 8;
762 static const int kSize_ = 9;
764 friend class JSArrayBasedStruct<FunctionInfoWrapper>;
771 class SharedInfoWrapper :
public JSArrayBasedStruct<SharedInfoWrapper> {
773 static bool IsInstance(Handle<JSArray> array) {
778 explicit SharedInfoWrapper(Handle<JSArray> array)
779 : JSArrayBasedStruct<SharedInfoWrapper>(array) {
782 void SetProperties(Handle<String> name,
int start_position,
int end_position,
783 Handle<SharedFunctionInfo> info) {
785 this->SetField(kFunctionNameOffset_, name);
786 Handle<JSValue> info_holder = WrapInJSValue(info);
787 this->SetField(kSharedInfoOffset_, info_holder);
788 this->SetSmiValueField(kStartPositionOffset_, start_position);
789 this->SetSmiValueField(kEndPositionOffset_, end_position);
791 Handle<SharedFunctionInfo> GetInfo() {
792 Object* element = this->GetField(kSharedInfoOffset_);
793 CHECK(element->IsJSValue());
795 return UnwrapSharedFunctionInfoFromJSValue(value_wrapper);
799 static const int kFunctionNameOffset_ = 0;
800 static const int kStartPositionOffset_ = 1;
801 static const int kEndPositionOffset_ = 2;
802 static const int kSharedInfoOffset_ = 3;
803 static const int kSize_ = 4;
805 friend class JSArrayBasedStruct<SharedInfoWrapper>;
809 class FunctionInfoListener {
811 FunctionInfoListener() {
812 current_parent_index_ = -1;
814 result_ =
FACTORY->NewJSArray(10);
817 void FunctionStarted(FunctionLiteral* fun) {
819 FunctionInfoWrapper info = FunctionInfoWrapper::Create();
820 info.SetInitialProperties(fun->name(), fun->start_position(),
821 fun->end_position(), fun->parameter_count(),
822 current_parent_index_);
823 current_parent_index_ = len_;
824 SetElementNonStrict(result_, len_, info.GetJSArray());
828 void FunctionDone() {
830 FunctionInfoWrapper info =
831 FunctionInfoWrapper::cast(
832 result_->GetElementNoExceptionThrown(current_parent_index_));
833 current_parent_index_ = info.GetParentIndex();
838 void FunctionCode(Handle<Code> function_code) {
839 FunctionInfoWrapper info =
840 FunctionInfoWrapper::cast(
841 result_->GetElementNoExceptionThrown(current_parent_index_));
842 info.SetFunctionCode(function_code, Handle<Object>(
HEAP->null_value()));
847 void FunctionInfo(Handle<SharedFunctionInfo> shared, Scope* scope,
849 if (!shared->IsSharedFunctionInfo()) {
852 FunctionInfoWrapper info =
853 FunctionInfoWrapper::cast(
854 result_->GetElementNoExceptionThrown(current_parent_index_));
855 info.SetFunctionCode(Handle<Code>(shared->code()),
856 Handle<Object>(shared->scope_info()));
857 info.SetSharedFunctionInfo(shared);
859 Handle<Object> scope_info_list(SerializeFunctionScope(scope, zone));
860 info.SetOuterScopeInfo(scope_info_list);
863 Handle<JSArray> GetResult() {
return result_; }
866 Object* SerializeFunctionScope(Scope* scope, Zone* zone) {
867 HandleScope handle_scope;
869 Handle<JSArray> scope_info_list =
FACTORY->NewJSArray(10);
870 int scope_info_length = 0;
875 Scope* outer_scope = scope->outer_scope();
876 if (outer_scope ==
NULL) {
877 return HEAP->undefined_value();
880 ZoneList<Variable*> stack_list(outer_scope->StackLocalCount(), zone);
881 ZoneList<Variable*> context_list(outer_scope->ContextLocalCount(), zone);
882 outer_scope->CollectStackAndContextLocals(&stack_list, &context_list);
885 for (
int i = 0; i < context_list.length(); i++) {
886 SetElementNonStrict(scope_info_list,
888 context_list[i]->name());
896 SetElementNonStrict(scope_info_list,
898 Handle<Object>(
HEAP->null_value()));
901 outer_scope = outer_scope->outer_scope();
902 }
while (outer_scope !=
NULL);
904 return *scope_info_list;
907 Handle<JSArray> result_;
909 int current_parent_index_;
913 JSArray* LiveEdit::GatherCompileInfo(Handle<Script> script,
914 Handle<String> source) {
915 Isolate* isolate = Isolate::Current();
917 FunctionInfoListener listener;
918 Handle<Object> original_source = Handle<Object>(script->source());
919 script->set_source(*source);
920 isolate->set_active_function_info_listener(&listener);
921 CompileScriptForTracker(isolate, script);
922 isolate->set_active_function_info_listener(
NULL);
923 script->set_source(*original_source);
925 return *(listener.GetResult());
929 void LiveEdit::WrapSharedFunctionInfos(Handle<JSArray> array) {
931 int len = GetArrayLength(array);
932 for (
int i = 0; i < len; i++) {
933 Handle<SharedFunctionInfo> info(
935 SharedInfoWrapper info_wrapper = SharedInfoWrapper::Create();
937 info_wrapper.SetProperties(name_handle, info->start_position(),
938 info->end_position(), info);
939 SetElementNonStrict(array, i, info_wrapper.GetJSArray());
947 class ReplacingVisitor :
public ObjectVisitor {
949 explicit ReplacingVisitor(Code* original, Code* substitution)
950 : original_(original), substitution_(substitution) {
953 virtual void VisitPointers(
Object** start,
Object** end) {
954 for (
Object** p = start; p < end; p++) {
955 if (*p == original_) {
961 virtual void VisitCodeEntry(
Address entry) {
963 Address substitution_entry = substitution_->instruction_start();
968 virtual void VisitCodeTarget(RelocInfo* rinfo) {
969 if (RelocInfo::IsCodeTarget(rinfo->rmode()) &&
971 Address substitution_entry = substitution_->instruction_start();
972 rinfo->set_target_address(substitution_entry);
976 virtual void VisitDebugTarget(RelocInfo* rinfo) {
977 VisitCodeTarget(rinfo);
987 static void ReplaceCodeObject(Handle<Code> original,
988 Handle<Code> substitution) {
995 "liveedit.cc ReplaceCodeObject");
999 AssertNoAllocation no_allocations_please;
1001 ReplacingVisitor visitor(*original, *substitution);
1010 HeapIterator iterator;
1011 for (HeapObject* obj = iterator.next(); obj !=
NULL; obj = iterator.next()) {
1012 obj->Iterate(&visitor);
1019 static bool IsJSFunctionCode(Code*
code) {
1020 return code->kind() == Code::FUNCTION;
1025 static bool IsInlined(JSFunction*
function, SharedFunctionInfo* candidate) {
1026 AssertNoAllocation no_gc;
1028 if (function->code()->kind() != Code::OPTIMIZED_FUNCTION)
return false;
1030 DeoptimizationInputData* data =
1033 if (data ==
HEAP->empty_fixed_array())
return false;
1035 FixedArray* literals = data->LiteralArray();
1037 int inlined_count = data->InlinedFunctionCount()->value();
1038 for (
int i = 0; i < inlined_count; ++i) {
1040 if (inlined->shared() == candidate)
return true;
1047 class DependentFunctionsDeoptimizingVisitor :
public OptimizedFunctionVisitor {
1049 explicit DependentFunctionsDeoptimizingVisitor(
1050 SharedFunctionInfo* function_info)
1051 : function_info_(function_info) {}
1053 virtual void EnterContext(Context* context) {
1056 virtual void VisitFunction(JSFunction*
function) {
1057 if (function->shared() == function_info_ ||
1058 IsInlined(
function, function_info_)) {
1063 virtual void LeaveContext(Context* context) {
1067 SharedFunctionInfo* function_info_;
1071 static void DeoptimizeDependentFunctions(SharedFunctionInfo* function_info) {
1072 AssertNoAllocation no_allocation;
1074 DependentFunctionsDeoptimizingVisitor visitor(function_info);
1079 MaybeObject* LiveEdit::ReplaceFunctionCode(
1080 Handle<JSArray> new_compile_info_array,
1081 Handle<JSArray> shared_info_array) {
1084 if (!SharedInfoWrapper::IsInstance(shared_info_array)) {
1085 return Isolate::Current()->ThrowIllegalOperation();
1088 FunctionInfoWrapper compile_info_wrapper(new_compile_info_array);
1089 SharedInfoWrapper shared_info_wrapper(shared_info_array);
1091 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo();
1093 HEAP->EnsureHeapIsIterable();
1095 if (IsJSFunctionCode(shared_info->code())) {
1096 Handle<Code> code = compile_info_wrapper.GetFunctionCode();
1097 ReplaceCodeObject(Handle<Code>(shared_info->code()), code);
1098 Handle<Object> code_scope_info = compile_info_wrapper.GetCodeScopeInfo();
1099 if (code_scope_info->IsFixedArray()) {
1104 if (shared_info->debug_info()->IsDebugInfo()) {
1105 Handle<DebugInfo> debug_info(DebugInfo::cast(shared_info->debug_info()));
1106 Handle<Code> new_original_code =
1107 FACTORY->CopyCode(compile_info_wrapper.GetFunctionCode());
1108 debug_info->set_original_code(*new_original_code);
1111 int start_position = compile_info_wrapper.GetStartPosition();
1112 int end_position = compile_info_wrapper.GetEndPosition();
1113 shared_info->set_start_position(start_position);
1114 shared_info->set_end_position(end_position);
1116 shared_info->set_construct_stub(
1117 Isolate::Current()->builtins()->builtin(
1118 Builtins::kJSConstructStubGeneric));
1120 DeoptimizeDependentFunctions(*shared_info);
1121 Isolate::Current()->compilation_cache()->Remove(shared_info);
1123 return HEAP->undefined_value();
1127 MaybeObject* LiveEdit::FunctionSourceUpdated(
1128 Handle<JSArray> shared_info_array) {
1131 if (!SharedInfoWrapper::IsInstance(shared_info_array)) {
1132 return Isolate::Current()->ThrowIllegalOperation();
1135 SharedInfoWrapper shared_info_wrapper(shared_info_array);
1136 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo();
1138 DeoptimizeDependentFunctions(*shared_info);
1139 Isolate::Current()->compilation_cache()->Remove(shared_info);
1141 return HEAP->undefined_value();
1145 void LiveEdit::SetFunctionScript(Handle<JSValue> function_wrapper,
1146 Handle<Object> script_handle) {
1147 Handle<SharedFunctionInfo> shared_info =
1148 UnwrapSharedFunctionInfoFromJSValue(function_wrapper);
1149 CHECK(script_handle->IsScript() || script_handle->IsUndefined());
1150 shared_info->set_script(*script_handle);
1152 Isolate::Current()->compilation_cache()->Remove(shared_info);
1165 static int TranslatePosition(
int original_position,
1166 Handle<JSArray> position_change_array) {
1167 int position_diff = 0;
1168 int array_len = GetArrayLength(position_change_array);
1170 for (
int i = 0; i < array_len; i += 3) {
1171 Object* element = position_change_array->GetElementNoExceptionThrown(i);
1172 CHECK(element->IsSmi());
1174 if (original_position < chunk_start) {
1177 element = position_change_array->GetElementNoExceptionThrown(i + 1);
1178 CHECK(element->IsSmi());
1181 ASSERT(original_position >= chunk_end);
1182 element = position_change_array->GetElementNoExceptionThrown(i + 2);
1183 CHECK(element->IsSmi());
1185 position_diff = chunk_changed_end - chunk_end;
1188 return original_position + position_diff;
1198 class RelocInfoBuffer {
1200 RelocInfoBuffer(
int buffer_initial_capicity,
byte*
pc) {
1201 buffer_size_ = buffer_initial_capicity + kBufferGap;
1202 buffer_ = NewArray<byte>(buffer_size_);
1204 reloc_info_writer_.Reposition(
buffer_ + buffer_size_, pc);
1206 ~RelocInfoBuffer() {
1212 void Write(
const RelocInfo* rinfo) {
1213 if (
buffer_ + kBufferGap >= reloc_info_writer_.pos()) {
1216 reloc_info_writer_.Write(rinfo);
1219 Vector<byte> GetResult() {
1222 static_cast<int>((
buffer_ + buffer_size_) - reloc_info_writer_.pos());
1223 return Vector<byte>(reloc_info_writer_.pos(), result_size);
1229 int new_buffer_size;
1230 if (buffer_size_ < 2 *
KB) {
1231 new_buffer_size = 4 *
KB;
1233 new_buffer_size = 2 * buffer_size_;
1237 if (new_buffer_size > kMaximalBufferSize) {
1242 byte* new_buffer = NewArray<byte>(new_buffer_size);
1245 int curently_used_size =
1246 static_cast<int>(
buffer_ + buffer_size_ - reloc_info_writer_.pos());
1247 memmove(new_buffer + new_buffer_size - curently_used_size,
1248 reloc_info_writer_.pos(), curently_used_size);
1250 reloc_info_writer_.Reposition(
1251 new_buffer + new_buffer_size - curently_used_size,
1252 reloc_info_writer_.last_pc());
1256 buffer_size_ = new_buffer_size;
1259 RelocInfoWriter reloc_info_writer_;
1263 static const int kBufferGap = RelocInfoWriter::kMaxSize;
1264 static const int kMaximalBufferSize = 512*
MB;
1269 static Handle<Code> PatchPositionsInCode(
1271 Handle<JSArray> position_change_array) {
1273 RelocInfoBuffer buffer_writer(code->relocation_size(),
1274 code->instruction_start());
1277 AssertNoAllocation no_allocations_please;
1278 for (RelocIterator it(*code); !it.done(); it.next()) {
1279 RelocInfo* rinfo = it.rinfo();
1280 if (RelocInfo::IsPosition(rinfo->rmode())) {
1281 int position =
static_cast<int>(rinfo->data());
1282 int new_position = TranslatePosition(position,
1283 position_change_array);
1284 if (position != new_position) {
1285 RelocInfo info_copy(rinfo->pc(), rinfo->rmode(), new_position,
NULL);
1286 buffer_writer.Write(&info_copy);
1290 buffer_writer.Write(it.rinfo());
1294 Vector<byte> buffer = buffer_writer.GetResult();
1296 if (buffer.length() == code->relocation_size()) {
1298 memcpy(code->relocation_start(), buffer.start(), buffer.length());
1304 Handle<Code> result(
FACTORY->CopyCode(code, buffer));
1310 MaybeObject* LiveEdit::PatchFunctionPositions(
1311 Handle<JSArray> shared_info_array, Handle<JSArray> position_change_array) {
1312 if (!SharedInfoWrapper::IsInstance(shared_info_array)) {
1313 return Isolate::Current()->ThrowIllegalOperation();
1316 SharedInfoWrapper shared_info_wrapper(shared_info_array);
1317 Handle<SharedFunctionInfo> info = shared_info_wrapper.GetInfo();
1319 int old_function_start = info->start_position();
1320 int new_function_start = TranslatePosition(old_function_start,
1321 position_change_array);
1322 int new_function_end = TranslatePosition(info->end_position(),
1323 position_change_array);
1324 int new_function_token_pos =
1325 TranslatePosition(info->function_token_position(), position_change_array);
1327 info->set_start_position(new_function_start);
1328 info->set_end_position(new_function_end);
1329 info->set_function_token_position(new_function_token_pos);
1331 HEAP->EnsureHeapIsIterable();
1333 if (IsJSFunctionCode(info->code())) {
1335 Handle<Code> patched_code = PatchPositionsInCode(Handle<Code>(info->code()),
1336 position_change_array);
1337 if (*patched_code != info->code()) {
1343 ReplaceCodeObject(Handle<Code>(info->code()), patched_code);
1347 return HEAP->undefined_value();
1351 static Handle<Script> CreateScriptCopy(Handle<Script> original) {
1352 Handle<String> original_source(
String::cast(original->source()));
1354 Handle<Script> copy =
FACTORY->NewScript(original_source);
1356 copy->set_name(original->name());
1357 copy->set_line_offset(original->line_offset());
1358 copy->set_column_offset(original->column_offset());
1359 copy->set_data(original->data());
1360 copy->set_type(original->type());
1361 copy->set_context_data(original->context_data());
1362 copy->set_compilation_type(original->compilation_type());
1363 copy->set_eval_from_shared(original->eval_from_shared());
1364 copy->set_eval_from_instructions_offset(
1365 original->eval_from_instructions_offset());
1371 Object* LiveEdit::ChangeScriptSource(Handle<Script> original_script,
1372 Handle<String> new_source,
1373 Handle<Object> old_script_name) {
1374 Handle<Object> old_script_object;
1375 if (old_script_name->IsString()) {
1376 Handle<Script> old_script = CreateScriptCopy(original_script);
1378 old_script_object = old_script;
1379 Isolate::Current()->debugger()->OnAfterCompile(
1380 old_script, Debugger::SEND_WHEN_DEBUGGING);
1382 old_script_object = Handle<Object>(
HEAP->null_value());
1385 original_script->set_source(*new_source);
1388 original_script->set_line_ends(
HEAP->undefined_value());
1390 return *old_script_object;
1395 void LiveEdit::ReplaceRefToNestedFunction(
1396 Handle<JSValue> parent_function_wrapper,
1397 Handle<JSValue> orig_function_wrapper,
1398 Handle<JSValue> subst_function_wrapper) {
1400 Handle<SharedFunctionInfo> parent_shared =
1401 UnwrapSharedFunctionInfoFromJSValue(parent_function_wrapper);
1402 Handle<SharedFunctionInfo> orig_shared =
1403 UnwrapSharedFunctionInfoFromJSValue(orig_function_wrapper);
1404 Handle<SharedFunctionInfo> subst_shared =
1405 UnwrapSharedFunctionInfoFromJSValue(subst_function_wrapper);
1407 for (RelocIterator it(parent_shared->code()); !it.done(); it.next()) {
1408 if (it.rinfo()->rmode() == RelocInfo::EMBEDDED_OBJECT) {
1409 if (it.rinfo()->target_object() == *orig_shared) {
1410 it.rinfo()->set_target_object(*subst_shared);
1419 static bool CheckActivation(Handle<JSArray> shared_info_array,
1420 Handle<JSArray> result,
1422 LiveEdit::FunctionPatchabilityStatus status) {
1423 if (!frame->is_java_script())
return false;
1425 Handle<JSFunction>
function(
1428 int len = GetArrayLength(shared_info_array);
1429 for (
int i = 0; i < len; i++) {
1430 Object* element = shared_info_array->GetElementNoExceptionThrown(i);
1431 CHECK(element->IsJSValue());
1433 Handle<SharedFunctionInfo> shared =
1434 UnwrapSharedFunctionInfoFromJSValue(jsvalue);
1436 if (function->shared() == *shared || IsInlined(*
function, *shared)) {
1437 SetElementNonStrict(result, i, Handle<Smi>(
Smi::FromInt(status)));
1447 static bool FixTryCatchHandler(
StackFrame* top_frame,
1451 Isolate::kHandlerAddress));
1453 while (*pointer_address < top_frame->
sp()) {
1456 Address* above_frame_address = pointer_address;
1457 while (*pointer_address < bottom_frame->
fp()) {
1460 bool change = *above_frame_address != *pointer_address;
1461 *above_frame_address = *pointer_address;
1470 static const char* DropFrames(Vector<StackFrame*> frames,
1471 int top_frame_index,
1472 int bottom_js_frame_index,
1473 Debug::FrameDropMode* mode,
1474 Object*** restarter_frame_function_pointer) {
1475 if (!Debug::kFrameDropperSupported) {
1476 return "Stack manipulations are not supported in this architecture.";
1479 StackFrame* pre_top_frame = frames[top_frame_index - 1];
1480 StackFrame* top_frame = frames[top_frame_index];
1481 StackFrame* bottom_js_frame = frames[bottom_js_frame_index];
1483 ASSERT(bottom_js_frame->is_java_script());
1486 Isolate* isolate = Isolate::Current();
1487 Code* pre_top_frame_code = pre_top_frame->LookupCode();
1488 bool frame_has_padding;
1489 if (pre_top_frame_code->is_inline_cache_stub() &&
1492 *mode = Debug::FRAME_DROPPED_IN_IC_CALL;
1493 frame_has_padding = Debug::FramePaddingLayout::kIsSupported;
1494 }
else if (pre_top_frame_code ==
1495 isolate->debug()->debug_break_slot()) {
1497 *mode = Debug::FRAME_DROPPED_IN_DEBUG_SLOT_CALL;
1498 frame_has_padding = Debug::FramePaddingLayout::kIsSupported;
1499 }
else if (pre_top_frame_code ==
1500 isolate->builtins()->builtin(
1501 Builtins::kFrameDropper_LiveEdit)) {
1503 pre_top_frame = frames[top_frame_index - 2];
1504 top_frame = frames[top_frame_index - 1];
1505 *mode = Debug::CURRENTLY_SET_MODE;
1506 frame_has_padding =
false;
1507 }
else if (pre_top_frame_code ==
1508 isolate->builtins()->builtin(Builtins::kReturn_DebugBreak)) {
1509 *mode = Debug::FRAME_DROPPED_IN_RETURN_CALL;
1510 frame_has_padding = Debug::FramePaddingLayout::kIsSupported;
1511 }
else if (pre_top_frame_code->kind() == Code::STUB &&
1512 pre_top_frame_code->major_key() == CodeStub::CEntry) {
1515 *mode = Debug::FRAME_DROPPED_IN_DIRECT_CALL;
1519 frame_has_padding =
false;
1523 ASSERT(frames[top_frame_index - 2]->LookupCode() ==
1524 isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit));
1525 pre_top_frame = frames[top_frame_index - 3];
1526 top_frame = frames[top_frame_index - 2];
1527 *mode = Debug::CURRENTLY_SET_MODE;
1528 frame_has_padding =
false;
1530 return "Unknown structure of stack above changing function";
1533 Address unused_stack_top = top_frame->sp();
1534 Address unused_stack_bottom = bottom_js_frame->fp()
1538 Address* top_frame_pc_address = top_frame->pc_address();
1543 if (unused_stack_top > unused_stack_bottom) {
1544 if (frame_has_padding) {
1545 int shortage_bytes =
1546 static_cast<int>(unused_stack_top - unused_stack_bottom);
1548 Address padding_start = pre_top_frame->fp() -
1549 Debug::FramePaddingLayout::kFrameBaseSize *
kPointerSize;
1551 Address padding_pointer = padding_start;
1552 Smi* padding_object =
1553 Smi::FromInt(Debug::FramePaddingLayout::kPaddingValue);
1557 int padding_counter =
1559 if (padding_counter * kPointerSize < shortage_bytes) {
1560 return "Not enough space for frame dropper frame "
1561 "(even with padding frame)";
1564 Smi::FromInt(padding_counter - shortage_bytes / kPointerSize);
1566 StackFrame* pre_pre_frame = frames[top_frame_index - 2];
1568 memmove(padding_start + kPointerSize - shortage_bytes,
1569 padding_start + kPointerSize,
1570 Debug::FramePaddingLayout::kFrameBaseSize * kPointerSize);
1572 pre_top_frame->UpdateFp(pre_top_frame->fp() - shortage_bytes);
1573 pre_pre_frame->SetCallerFp(pre_top_frame->fp());
1574 unused_stack_top -= shortage_bytes;
1579 return "Not enough space for frame dropper frame";
1585 FixTryCatchHandler(pre_top_frame, bottom_js_frame);
1587 ASSERT(!FixTryCatchHandler(pre_top_frame, bottom_js_frame));
1589 Handle<Code> code = Isolate::Current()->builtins()->FrameDropper_LiveEdit();
1590 *top_frame_pc_address = code->entry();
1591 pre_top_frame->SetCallerFp(bottom_js_frame->fp());
1593 *restarter_frame_function_pointer =
1594 Debug::SetUpFrameDropperFrame(bottom_js_frame, code);
1596 ASSERT((**restarter_frame_function_pointer)->IsJSFunction());
1598 for (
Address a = unused_stack_top;
1599 a < unused_stack_bottom;
1608 static bool IsDropableFrame(
StackFrame* frame) {
1609 return !frame->is_exit();
1615 class MultipleFunctionTarget {
1617 MultipleFunctionTarget(Handle<JSArray> shared_info_array,
1618 Handle<JSArray> result)
1619 : m_shared_info_array(shared_info_array),
1622 LiveEdit::FunctionPatchabilityStatus status) {
1623 return CheckActivation(m_shared_info_array, m_result, frame, status);
1625 const char* GetNotFoundMessage() {
1629 Handle<JSArray> m_shared_info_array;
1630 Handle<JSArray> m_result;
1634 template<
typename TARGET>
1635 static const char* DropActivationsInActiveThreadImpl(
1636 TARGET& target,
bool do_drop, Zone* zone) {
1637 Isolate* isolate = Isolate::Current();
1638 Debug* debug = isolate->debug();
1643 int top_frame_index = -1;
1644 int frame_index = 0;
1645 for (; frame_index < frames.length(); frame_index++) {
1647 if (frame->id() == debug->break_frame_id()) {
1648 top_frame_index = frame_index;
1651 if (target.MatchActivation(
1652 frame, LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE)) {
1655 return "Debugger mark-up on stack is not found";
1659 if (top_frame_index == -1) {
1661 return target.GetNotFoundMessage();
1664 bool target_frame_found =
false;
1665 int bottom_js_frame_index = top_frame_index;
1666 bool c_code_found =
false;
1668 for (; frame_index < frames.length(); frame_index++) {
1670 if (!IsDropableFrame(frame)) {
1671 c_code_found =
true;
1674 if (target.MatchActivation(
1675 frame, LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) {
1676 target_frame_found =
true;
1677 bottom_js_frame_index = frame_index;
1684 for (; frame_index < frames.length(); frame_index++) {
1686 if (frame->is_java_script()) {
1687 if (target.MatchActivation(
1688 frame, LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE)) {
1701 if (!target_frame_found) {
1703 return target.GetNotFoundMessage();
1706 Debug::FrameDropMode drop_mode = Debug::FRAMES_UNTOUCHED;
1707 Object** restarter_frame_function_pointer =
NULL;
1708 const char* error_message = DropFrames(frames, top_frame_index,
1709 bottom_js_frame_index, &drop_mode,
1710 &restarter_frame_function_pointer);
1712 if (error_message !=
NULL) {
1713 return error_message;
1717 StackFrame::Id new_id = StackFrame::NO_ID;
1718 for (
int i = bottom_js_frame_index + 1; i < frames.length(); i++) {
1719 if (frames[i]->type() == StackFrame::JAVA_SCRIPT) {
1720 new_id = frames[i]->id();
1724 debug->FramesHaveBeenDropped(new_id, drop_mode,
1725 restarter_frame_function_pointer);
1731 static const char* DropActivationsInActiveThread(
1732 Handle<JSArray> shared_info_array, Handle<JSArray> result,
bool do_drop,
1734 MultipleFunctionTarget target(shared_info_array, result);
1737 DropActivationsInActiveThreadImpl(target, do_drop, zone);
1742 int array_len = GetArrayLength(shared_info_array);
1745 for (
int i = 0; i < array_len; i++) {
1746 if (result->GetElement(i) ==
1747 Smi::FromInt(LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) {
1748 Handle<Object> replaced(
1749 Smi::FromInt(LiveEdit::FUNCTION_REPLACED_ON_ACTIVE_STACK));
1750 SetElementNonStrict(result, i, replaced);
1757 class InactiveThreadActivationsChecker :
public ThreadVisitor {
1759 InactiveThreadActivationsChecker(Handle<JSArray> shared_info_array,
1760 Handle<JSArray> result)
1761 : shared_info_array_(shared_info_array), result_(result),
1762 has_blocked_functions_(
false) {
1764 void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
1765 for (StackFrameIterator it(isolate, top); !it.done(); it.Advance()) {
1766 has_blocked_functions_ |= CheckActivation(
1767 shared_info_array_, result_, it.frame(),
1768 LiveEdit::FUNCTION_BLOCKED_ON_OTHER_STACK);
1771 bool HasBlockedFunctions() {
1772 return has_blocked_functions_;
1776 Handle<JSArray> shared_info_array_;
1777 Handle<JSArray> result_;
1778 bool has_blocked_functions_;
1782 Handle<JSArray> LiveEdit::CheckAndDropActivations(
1783 Handle<JSArray> shared_info_array,
bool do_drop, Zone* zone) {
1784 int len = GetArrayLength(shared_info_array);
1786 Handle<JSArray> result =
FACTORY->NewJSArray(len);
1789 for (
int i = 0; i < len; i++) {
1790 SetElementNonStrict(
1793 Handle<Smi>(
Smi::FromInt(FUNCTION_AVAILABLE_FOR_PATCH)));
1798 InactiveThreadActivationsChecker inactive_threads_checker(shared_info_array,
1800 Isolate::Current()->thread_manager()->IterateArchivedThreads(
1801 &inactive_threads_checker);
1802 if (inactive_threads_checker.HasBlockedFunctions()) {
1807 const char* error_message =
1808 DropActivationsInActiveThread(shared_info_array, result, do_drop, zone);
1809 if (error_message !=
NULL) {
1811 Vector<const char> vector_message(error_message,
StrLength(error_message));
1812 Handle<String> str =
FACTORY->NewStringFromAscii(vector_message);
1813 SetElementNonStrict(result, len, str);
1821 class SingleFrameTarget {
1823 explicit SingleFrameTarget(JavaScriptFrame* frame)
1825 m_saved_status(LiveEdit::FUNCTION_AVAILABLE_FOR_PATCH) {}
1828 LiveEdit::FunctionPatchabilityStatus status) {
1829 if (frame->fp() == m_frame->fp()) {
1830 m_saved_status = status;
1835 const char* GetNotFoundMessage() {
1836 return "Failed to found requested frame";
1838 LiveEdit::FunctionPatchabilityStatus saved_status() {
1839 return m_saved_status;
1842 JavaScriptFrame* m_frame;
1843 LiveEdit::FunctionPatchabilityStatus m_saved_status;
1849 const char* LiveEdit::RestartFrame(JavaScriptFrame* frame, Zone* zone) {
1850 SingleFrameTarget target(frame);
1852 const char* result = DropActivationsInActiveThreadImpl(target,
true, zone);
1853 if (result !=
NULL) {
1856 if (target.saved_status() == LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE) {
1857 return "Function is blocked under native code";
1864 FunctionLiteral* fun)
1865 : isolate_(isolate) {
1866 if (isolate_->active_function_info_listener() !=
NULL) {
1867 isolate_->active_function_info_listener()->FunctionStarted(fun);
1873 if (isolate_->active_function_info_listener() !=
NULL) {
1874 isolate_->active_function_info_listener()->FunctionDone();
1880 Handle<SharedFunctionInfo> info, FunctionLiteral* lit,
1882 if (isolate_->active_function_info_listener() !=
NULL) {
1883 isolate_->active_function_info_listener()->FunctionInfo(info, lit->scope(),
1890 isolate_->active_function_info_listener()->FunctionCode(code);
1895 return isolate->active_function_info_listener() !=
NULL;
1899 #else // ENABLE_DEBUGGER_SUPPORT
1926 #endif // ENABLE_DEBUGGER_SUPPORT
static Object *& Object_at(Address addr)
void RecordRootFunctionInfo(Handle< Code > code)
static bool IsActive(Isolate *isolate)
static String * cast(Object *obj)
static Smi * FromInt(int value)
static Object * GetObjectFromEntryAddress(Address location_of_address)
Handle< FixedArray > CalculateLineEnds(Handle< String > src, bool with_last_line)
static Handle< T > cast(Handle< S > that)
#define ASSERT(condition)
static void DeoptimizeFunction(JSFunction *function)
LiveEditFunctionTracker(Isolate *isolate, FunctionLiteral *fun)
static SharedFunctionInfo * cast(Object *obj)
StringInputBuffer *const buffer_
Vector< StackFrame * > CreateStackMap(Zone *zone)
static Smi * cast(Object *object)
Handle< String > FlattenGetString(Handle< String > string)
static bool Parse(CompilationInfo *info, int flags)
static ScopeInfo * cast(Object *object)
HANDLE HANDLE LPSTACKFRAME64 StackFrame
Object * GetElementNoExceptionThrown(uint32_t index)
STATIC_ASSERT((FixedDoubleArray::kHeaderSize &kDoubleAlignmentMask)==0)
static int CompareIndex(Variable *const *v, Variable *const *w)
static Address & Address_at(Address addr)
static MUST_USE_RESULT Handle< Object > SetElement(Handle< JSObject > object, uint32_t index, Handle< Object > value, PropertyAttributes attr, StrictModeFlag strict_mode, SetPropertyMode set_mode=SET_PROPERTY)
static Code * GetCodeFromTargetAddress(Address address)
static const int kMakeHeapIterableMask
static JavaScriptFrame * cast(StackFrame *frame)
activate correct semantics for inheriting readonliness false
int StrLength(const char *string)
static JSArray * cast(Object *obj)
void RecordFunctionInfo(Handle< SharedFunctionInfo > info, FunctionLiteral *lit, Zone *zone)
static JSValue * cast(Object *obj)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if expose natives in global object expose gc extension number of stack frames to capture disable builtin natives files print a stack trace if an assertion failure occurs use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations prepare for turning on always opt minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions automatically set the debug break flag when debugger commands are in the queue always cause a debug break before aborting maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print more details following each garbage collection print amount of external allocated memory after each time it is adjusted flush code that we expect not to use again before full gc do incremental marking steps track object counts and memory usage use caching Perform compaction on every full GC Never perform compaction on full GC testing only Compact code space on full incremental collections Default seed for initializing random allows verbose printing trace parsing and preparsing Check icache flushes in ARM and MIPS simulator Stack alingment in bytes in print stack trace when throwing exceptions randomize hashes to avoid predictable hash Fixed seed to use to hash property activate a timer that switches between V8 threads testing_bool_flag float flag Seed used for threading test randomness A filename with extra code to be included in the Print usage message
~LiveEditFunctionTracker()
static void VisitAllOptimizedFunctions(OptimizedFunctionVisitor *visitor)
const uint32_t kMaxUInt32
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
void DeleteArray(T *array)
static void FatalProcessOutOfMemory(const char *location, bool take_snapshot=false)
static JSFunction * cast(Object *obj)