Commit d8bc3362 authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[deoptimizer] Fix bug in object materialization

Object materialization did not correctly deal with a mismatch between
current representation of a field value and expected representation.
This is an attempt to repair the situation.

Bug: chromium:1084820
Change-Id: Ib337cbaf5e36a5a616b6a6cb0ddf51018d49b96a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2228330
Commit-Queue: Georg Neis <neis@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarNico Hartmann <nicohartmann@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68231}
parent 87d70eab
This diff is collapsed.
...@@ -39,13 +39,17 @@ enum class BuiltinContinuationMode; ...@@ -39,13 +39,17 @@ enum class BuiltinContinuationMode;
class TranslatedValue { class TranslatedValue {
public: public:
// Allocation-less getter of the value. // Allocation-free getter of the value.
// Returns ReadOnlyRoots::arguments_marker() if allocation would be necessary // Returns ReadOnlyRoots::arguments_marker() if allocation would be necessary
// to get the value. // to get the value. In the case of numbers, returns a Smi if possible.
Object GetRawValue() const; Object GetRawValue() const;
// Getter for the value, takes care of materializing the subgraph // Convenience wrapper around GetRawValue (checked).
// reachable from this value. int GetSmiValue() const;
// Returns the value, possibly materializing it first (and the whole subgraph
// reachable from this value). In the case of numbers, returns a Smi if
// possible.
Handle<Object> GetValue(); Handle<Object> GetValue();
bool IsMaterializedObject() const; bool IsMaterializedObject() const;
...@@ -102,15 +106,14 @@ class TranslatedValue { ...@@ -102,15 +106,14 @@ class TranslatedValue {
static TranslatedValue NewInvalid(TranslatedState* container); static TranslatedValue NewInvalid(TranslatedState* container);
Isolate* isolate() const; Isolate* isolate() const;
void MaterializeSimple();
void set_storage(Handle<HeapObject> storage) { storage_ = storage; } void set_storage(Handle<HeapObject> storage) { storage_ = storage; }
void set_initialized_storage(Handle<Object> storage); void set_initialized_storage(Handle<HeapObject> storage);
void mark_finished() { materialization_state_ = kFinished; } void mark_finished() { materialization_state_ = kFinished; }
void mark_allocated() { materialization_state_ = kAllocated; } void mark_allocated() { materialization_state_ = kAllocated; }
Handle<Object> GetStorage() { Handle<HeapObject> storage() {
DCHECK_NE(kUninitialized, materialization_state()); DCHECK_NE(materialization_state(), kUninitialized);
return storage_; return storage_;
} }
...@@ -120,9 +123,9 @@ class TranslatedValue { ...@@ -120,9 +123,9 @@ class TranslatedValue {
// objects and constructing handles (to get // objects and constructing handles (to get
// to the isolate). // to the isolate).
Handle<Object> storage_; // Contains the materialized value or the Handle<HeapObject> storage_; // Contains the materialized value or the
// byte-array that will be later morphed into // byte-array that will be later morphed into
// the materialized object. // the materialized object.
struct MaterializedObjectInfo { struct MaterializedObjectInfo {
int id_; int id_;
...@@ -376,7 +379,7 @@ class TranslatedState { ...@@ -376,7 +379,7 @@ class TranslatedState {
int* value_index, std::stack<int>* worklist); int* value_index, std::stack<int>* worklist);
void EnsureCapturedObjectAllocatedAt(int object_index, void EnsureCapturedObjectAllocatedAt(int object_index,
std::stack<int>* worklist); std::stack<int>* worklist);
Handle<Object> InitializeObjectAt(TranslatedValue* slot); Handle<HeapObject> InitializeObjectAt(TranslatedValue* slot);
void InitializeCapturedObjectAt(int object_index, std::stack<int>* worklist, void InitializeCapturedObjectAt(int object_index, std::stack<int>* worklist,
const DisallowHeapAllocation& no_allocation); const DisallowHeapAllocation& no_allocation);
void InitializeJSObjectAt(TranslatedFrame* frame, int* value_index, void InitializeJSObjectAt(TranslatedFrame* frame, int* value_index,
...@@ -392,6 +395,9 @@ class TranslatedState { ...@@ -392,6 +395,9 @@ class TranslatedState {
TranslatedValue* ResolveCapturedObject(TranslatedValue* slot); TranslatedValue* ResolveCapturedObject(TranslatedValue* slot);
TranslatedValue* GetValueByObjectIndex(int object_index); TranslatedValue* GetValueByObjectIndex(int object_index);
Handle<Object> GetValueAndAdvance(TranslatedFrame* frame, int* value_index); Handle<Object> GetValueAndAdvance(TranslatedFrame* frame, int* value_index);
TranslatedValue* GetResolvedSlot(TranslatedFrame* frame, int value_index);
TranslatedValue* GetResolvedSlotAndAdvance(TranslatedFrame* frame,
int* value_index);
static uint32_t GetUInt32Slot(Address fp, int slot_index); static uint32_t GetUInt32Slot(Address fp, int slot_index);
static uint64_t GetUInt64Slot(Address fp, int slot_index); static uint64_t GetUInt64Slot(Address fp, int slot_index);
...@@ -773,7 +779,7 @@ class FrameDescription { ...@@ -773,7 +779,7 @@ class FrameDescription {
intptr_t continuation_; intptr_t continuation_;
// This must be at the end of the object as the object is allocated larger // This must be at the end of the object as the object is allocated larger
// than it's definition indicate to extend this array. // than its definition indicates to extend this array.
intptr_t frame_content_[1]; intptr_t frame_content_[1];
intptr_t* GetFrameSlotPointer(unsigned offset) { intptr_t* GetFrameSlotPointer(unsigned offset) {
......
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
// Create a map where 'my_property' has HeapObject representation.
const dummy_obj = {};
dummy_obj.my_property = 'some HeapObject';
dummy_obj.my_property = 'some other HeapObject';
function gaga() {
const obj = {};
// Store a HeapNumber and then a Smi.
// This must happen in a loop, even if it's only 2 iterations:
for (let j = -3_000_000_000; j <= -1_000_000_000; j += 2_000_000_000) {
obj.my_property = j;
}
// Trigger (soft) deopt.
if (!%IsBeingInterpreted()) obj + obj;
}
%PrepareFunctionForOptimization(gaga);
gaga();
gaga();
%OptimizeFunctionOnNextCall(gaga);
gaga();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment