Merge V8 5.3.332.45. DO NOT MERGE
Test: Manual
FPIIM-449
Change-Id: Id3254828b068abdea3cb10442e0172a8c9a98e03
(cherry picked from commit 13e2dadd00298019ed862f2b2fc5068bba730bcf)
diff --git a/src/debug/liveedit.cc b/src/debug/liveedit.cc
index 50d60a1..aa67537 100644
--- a/src/debug/liveedit.cc
+++ b/src/debug/liveedit.cc
@@ -621,11 +621,9 @@
this->SetSmiValueField(kParentIndexOffset_, parent_index);
}
-
-void FunctionInfoWrapper::SetFunctionCode(Handle<Code> function_code,
+void FunctionInfoWrapper::SetFunctionCode(Handle<AbstractCode> function_code,
Handle<HeapObject> code_scope_info) {
// CompileForLiveEdit must deliver full-codegen code.
- DCHECK(function_code->kind() == Code::FUNCTION);
Handle<JSValue> code_wrapper = WrapInJSValue(function_code);
this->SetField(kCodeOffset_, code_wrapper);
@@ -640,27 +638,25 @@
this->SetField(kSharedFunctionInfoOffset_, info_holder);
}
-
-Handle<Code> FunctionInfoWrapper::GetFunctionCode() {
+Handle<AbstractCode> FunctionInfoWrapper::GetFunctionCode() {
Handle<Object> element = this->GetField(kCodeOffset_);
Handle<JSValue> value_wrapper = Handle<JSValue>::cast(element);
Handle<Object> raw_result = UnwrapJSValue(value_wrapper);
- CHECK(raw_result->IsCode());
- return Handle<Code>::cast(raw_result);
+ CHECK(raw_result->IsAbstractCode());
+ return Handle<AbstractCode>::cast(raw_result);
}
-
-MaybeHandle<TypeFeedbackVector> FunctionInfoWrapper::GetFeedbackVector() {
+MaybeHandle<TypeFeedbackMetadata> FunctionInfoWrapper::GetFeedbackMetadata() {
Handle<Object> element = this->GetField(kSharedFunctionInfoOffset_);
if (element->IsJSValue()) {
Handle<JSValue> value_wrapper = Handle<JSValue>::cast(element);
Handle<Object> raw_result = UnwrapJSValue(value_wrapper);
Handle<SharedFunctionInfo> shared =
Handle<SharedFunctionInfo>::cast(raw_result);
- return Handle<TypeFeedbackVector>(shared->feedback_vector(), isolate());
+ return Handle<TypeFeedbackMetadata>(shared->feedback_metadata(), isolate());
} else {
// Scripts may never have a SharedFunctionInfo created.
- return MaybeHandle<TypeFeedbackVector>();
+ return MaybeHandle<TypeFeedbackMetadata>();
}
}
@@ -863,11 +859,11 @@
public:
static void PatchLiterals(FunctionInfoWrapper* compile_info_wrapper,
Handle<SharedFunctionInfo> shared_info,
- Isolate* isolate) {
+ bool feedback_metadata_changed, Isolate* isolate) {
int new_literal_count = compile_info_wrapper->GetLiteralCount();
int old_literal_count = shared_info->num_literals();
- if (old_literal_count == new_literal_count) {
+ if (old_literal_count == new_literal_count && !feedback_metadata_changed) {
// If literal count didn't change, simply go over all functions
// and clear literal arrays.
ClearValuesVisitor visitor;
@@ -878,10 +874,13 @@
// collect all functions and fix their literal arrays.
Handle<FixedArray> function_instances =
CollectJSFunctions(shared_info, isolate);
- Handle<TypeFeedbackVector> vector(shared_info->feedback_vector());
+ Handle<TypeFeedbackMetadata> feedback_metadata(
+ shared_info->feedback_metadata());
for (int i = 0; i < function_instances->length(); i++) {
Handle<JSFunction> fun(JSFunction::cast(function_instances->get(i)));
+ Handle<TypeFeedbackVector> vector =
+ TypeFeedbackVector::New(isolate, feedback_metadata);
Handle<LiteralsArray> new_literals =
LiteralsArray::New(isolate, vector, new_literal_count, TENURED);
fun->set_literals(*new_literals);
@@ -929,10 +928,10 @@
class ClearValuesVisitor {
public:
void visit(JSFunction* fun) {
- FixedArray* literals = fun->literals();
- int len = literals->length();
+ LiteralsArray* literals = fun->literals();
+ int len = literals->literals_count();
for (int j = 0; j < len; j++) {
- literals->set_undefined(j);
+ literals->set_literal_undefined(j);
}
}
};
@@ -1007,18 +1006,20 @@
SharedInfoWrapper shared_info_wrapper(shared_info_array);
Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo();
+ bool feedback_metadata_changed = false;
if (shared_info->is_compiled()) {
- Handle<Code> new_code = compile_info_wrapper.GetFunctionCode();
- Handle<Code> old_code(shared_info->code());
+ Handle<AbstractCode> new_code = compile_info_wrapper.GetFunctionCode();
if (shared_info->HasBytecodeArray()) {
- // The old code is interpreted. If we clear the bytecode array, the
- // interpreter entry trampoline will self-heal and go to compiled code.
+ DCHECK(new_code->IsBytecodeArray());
+ // The old code is interpreted, the new code must be interpreted as well.
shared_info->ClearBytecodeArray();
- shared_info->ReplaceCode(*new_code);
+ shared_info->set_bytecode_array(BytecodeArray::cast(*new_code));
} else {
+ Handle<Code> old_code(shared_info->code());
DCHECK(old_code->kind() == Code::FUNCTION);
- ReplaceCodeObject(old_code, new_code);
+ DCHECK(new_code->kind() == AbstractCode::FUNCTION);
+ ReplaceCodeObject(old_code, Handle<Code>::cast(new_code));
}
if (shared_info->HasDebugInfo()) {
// Existing break points will be re-applied. Reset the debug info here.
@@ -1031,10 +1032,14 @@
}
shared_info->DisableOptimization(kLiveEdit);
// Update the type feedback vector, if needed.
- MaybeHandle<TypeFeedbackVector> feedback_vector =
- compile_info_wrapper.GetFeedbackVector();
- if (!feedback_vector.is_null()) {
- shared_info->set_feedback_vector(*feedback_vector.ToHandleChecked());
+ MaybeHandle<TypeFeedbackMetadata> feedback_metadata =
+ compile_info_wrapper.GetFeedbackMetadata();
+ if (!feedback_metadata.is_null()) {
+ Handle<TypeFeedbackMetadata> checked_feedback_metadata =
+ feedback_metadata.ToHandleChecked();
+ feedback_metadata_changed = checked_feedback_metadata->DiffersFrom(
+ shared_info->feedback_metadata());
+ shared_info->set_feedback_metadata(*checked_feedback_metadata);
}
}
@@ -1043,7 +1048,8 @@
shared_info->set_start_position(start_position);
shared_info->set_end_position(end_position);
- LiteralFixer::PatchLiterals(&compile_info_wrapper, shared_info, isolate);
+ LiteralFixer::PatchLiterals(&compile_info_wrapper, shared_info,
+ feedback_metadata_changed, isolate);
DeoptimizeDependentFunctions(*shared_info);
isolate->compilation_cache()->Remove(shared_info);
@@ -1063,7 +1069,8 @@
Handle<Object> script_handle) {
Handle<SharedFunctionInfo> shared_info =
UnwrapSharedFunctionInfoFromJSValue(function_wrapper);
- CHECK(script_handle->IsScript() || script_handle->IsUndefined());
+ Isolate* isolate = function_wrapper->GetIsolate();
+ CHECK(script_handle->IsScript() || script_handle->IsUndefined(isolate));
SharedFunctionInfo::SetScript(shared_info, script_handle);
shared_info->DisableOptimization(kLiveEdit);
@@ -1219,18 +1226,13 @@
}
Vector<byte> buffer = buffer_writer.GetResult();
+ Handle<ByteArray> reloc_info =
+ isolate->factory()->NewByteArray(buffer.length(), TENURED);
- if (buffer.length() == code->relocation_size()) {
- // Simply patch relocation area of code.
- MemCopy(code->relocation_start(), buffer.start(), buffer.length());
- return code;
- } else {
- // Relocation info section now has different size. We cannot simply
- // rewrite it inside code object. Instead we have to create a new
- // code object.
- Handle<Code> result(isolate->factory()->CopyCode(code, buffer));
- return result;
- }
+ DisallowHeapAllocation no_gc;
+ code->set_relocation_info(*reloc_info);
+ CopyBytes(code->relocation_start(), buffer.start(), buffer.length());
+ return code;
}
void PatchPositionsInBytecodeArray(Handle<BytecodeArray> bytecode,
@@ -1248,7 +1250,8 @@
iterator.is_statement());
}
- bytecode->set_source_position_table(*builder.ToSourcePositionTable());
+ Handle<ByteArray> source_position_table = builder.ToSourcePositionTable();
+ bytecode->set_source_position_table(*source_position_table);
}
} // namespace
@@ -1601,7 +1604,7 @@
Handle<Object> new_element =
JSReceiver::GetElement(isolate, new_shared_array_, i)
.ToHandleChecked();
- if (new_element->IsUndefined()) return false;
+ if (new_element->IsUndefined(isolate)) return false;
Handle<SharedFunctionInfo> new_shared =
UnwrapSharedFunctionInfoFromJSValue(
Handle<JSValue>::cast(new_element));
@@ -1619,6 +1622,21 @@
return false;
}
+ void set_status(LiveEdit::FunctionPatchabilityStatus status) {
+ Isolate* isolate = old_shared_array_->GetIsolate();
+ int len = GetArrayLength(old_shared_array_);
+ for (int i = 0; i < len; ++i) {
+ Handle<Object> old_element =
+ JSReceiver::GetElement(isolate, result_, i).ToHandleChecked();
+ if (!old_element->IsSmi() ||
+ Smi::cast(*old_element)->value() ==
+ LiveEdit::FUNCTION_AVAILABLE_FOR_PATCH) {
+ SetElementSloppy(result_, i,
+ Handle<Smi>(Smi::FromInt(status), isolate));
+ }
+ }
+ }
+
private:
Handle<JSArray> old_shared_array_;
Handle<JSArray> new_shared_array_;
@@ -1672,7 +1690,7 @@
if (frame->is_java_script()) {
SharedFunctionInfo* shared =
JavaScriptFrame::cast(frame)->function()->shared();
- if (shared->is_generator()) {
+ if (shared->is_resumable()) {
non_droppable_frame_found = true;
non_droppable_reason = LiveEdit::FUNCTION_BLOCKED_UNDER_GENERATOR;
break;
@@ -1696,6 +1714,13 @@
// Fail.
return NULL;
}
+ if (non_droppable_reason ==
+ LiveEdit::FUNCTION_BLOCKED_UNDER_GENERATOR &&
+ !target_frame_found) {
+ // Fail.
+ target.set_status(non_droppable_reason);
+ return NULL;
+ }
}
}
}
@@ -1993,7 +2018,7 @@
FunctionInfoWrapper info = FunctionInfoWrapper::cast(
*JSReceiver::GetElement(isolate_, result_, current_parent_index_)
.ToHandleChecked());
- info.SetFunctionCode(Handle<Code>(shared->code()),
+ info.SetFunctionCode(Handle<AbstractCode>(shared->abstract_code()),
Handle<HeapObject>(shared->scope_info()));
info.SetSharedFunctionInfo(shared);