@@ -55,6 +55,80 @@ static void ZapCodeRange(Address start, Address end) {
55
55
}
56
56
57
57
58
+ void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) {
59
+ HandleScope scope;
60
+
61
+ // Compute the size of relocation information needed for the code
62
+ // patching in Deoptimizer::DeoptimizeFunction.
63
+ int min_reloc_size = 0;
64
+ Address prev_reloc_address = code->instruction_start();
65
+ Address code_start_address = code->instruction_start();
66
+ SafepointTable table(*code);
67
+ for (unsigned i = 0; i < table.length(); ++i) {
68
+ Address curr_reloc_address = code_start_address + table.GetPcOffset(i);
69
+ ASSERT_GE(curr_reloc_address, prev_reloc_address);
70
+ SafepointEntry safepoint_entry = table.GetEntry(i);
71
+ int deoptimization_index = safepoint_entry.deoptimization_index();
72
+ if (deoptimization_index != Safepoint::kNoDeoptimizationIndex) {
73
+ // The gap code is needed to get to the state expected at the
74
+ // bailout and we need to skip the call opcode to get to the
75
+ // address that needs reloc.
76
+ curr_reloc_address += safepoint_entry.gap_code_size() + 1;
77
+ int pc_delta = curr_reloc_address - prev_reloc_address;
78
+ // We use RUNTIME_ENTRY reloc info which has a size of 2 bytes
79
+ // if encodable with small pc delta encoding and up to 6 bytes
80
+ // otherwise.
81
+ if (pc_delta <= RelocInfo::kMaxSmallPCDelta) {
82
+ min_reloc_size += 2;
83
+ } else {
84
+ min_reloc_size += 6;
85
+ }
86
+ prev_reloc_address = curr_reloc_address;
87
+ }
88
+ }
89
+
90
+ // If the relocation information is not big enough we create a new
91
+ // relocation info object that is padded with comments to make it
92
+ // big enough for lazy doptimization.
93
+ int reloc_length = code->relocation_info()->length();
94
+ if (min_reloc_size > reloc_length) {
95
+ int comment_reloc_size = RelocInfo::kMinRelocCommentSize;
96
+ // Padding needed.
97
+ int min_padding = min_reloc_size - reloc_length;
98
+ // Number of comments needed to take up at least that much space.
99
+ int additional_comments =
100
+ (min_padding + comment_reloc_size - 1) / comment_reloc_size;
101
+ // Actual padding size.
102
+ int padding = additional_comments * comment_reloc_size;
103
+ // Allocate new relocation info and copy old relocation to the end
104
+ // of the new relocation info array because relocation info is
105
+ // written and read backwards.
106
+ Handle<ByteArray> new_reloc =
107
+ Factory::NewByteArray(reloc_length + padding, TENURED);
108
+ memcpy(new_reloc->GetDataStartAddress() + padding,
109
+ code->relocation_info()->GetDataStartAddress(),
110
+ reloc_length);
111
+ // Create a relocation writer to write the comments in the padding
112
+ // space. Use position 0 for everything to ensure short encoding.
113
+ RelocInfoWriter reloc_info_writer(
114
+ new_reloc->GetDataStartAddress() + padding, 0);
115
+ intptr_t comment_string
116
+ = reinterpret_cast<intptr_t>(RelocInfo::kFillerCommentString);
117
+ RelocInfo rinfo(0, RelocInfo::COMMENT, comment_string);
118
+ for (int i = 0; i < additional_comments; ++i) {
119
+ #ifdef DEBUG
120
+ byte* pos_before = reloc_info_writer.pos();
121
+ #endif
122
+ reloc_info_writer.Write(&rinfo);
123
+ ASSERT(RelocInfo::kMinRelocCommentSize ==
124
+ pos_before - reloc_info_writer.pos());
125
+ }
126
+ // Replace relocation information on the code object.
127
+ code->set_relocation_info(*new_reloc);
128
+ }
129
+ }
130
+
131
+
58
132
void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
59
133
AssertNoAllocation no_allocation;
60
134
0 commit comments