Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: src/type-info.cc

Issue 185653004: Experimental parser: merge to r19637 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/type-info.h ('k') | src/typedarray.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 26 matching lines...) Expand all
37 37
38 #include "ic-inl.h" 38 #include "ic-inl.h"
39 #include "objects-inl.h" 39 #include "objects-inl.h"
40 40
41 namespace v8 { 41 namespace v8 {
42 namespace internal { 42 namespace internal {
43 43
44 44
45 TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code, 45 TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code,
46 Handle<Context> native_context, 46 Handle<Context> native_context,
47 Isolate* isolate,
48 Zone* zone) 47 Zone* zone)
49 : native_context_(native_context), 48 : native_context_(native_context),
50 isolate_(isolate),
51 zone_(zone) { 49 zone_(zone) {
50 Object* raw_info = code->type_feedback_info();
51 if (raw_info->IsTypeFeedbackInfo()) {
52 feedback_vector_ = Handle<FixedArray>(TypeFeedbackInfo::cast(raw_info)->
53 feedback_vector());
54 }
55
52 BuildDictionary(code); 56 BuildDictionary(code);
53 ASSERT(dictionary_->IsDictionary()); 57 ASSERT(dictionary_->IsDictionary());
54 } 58 }
55 59
56 60
57 static uint32_t IdToKey(TypeFeedbackId ast_id) { 61 static uint32_t IdToKey(TypeFeedbackId ast_id) {
58 return static_cast<uint32_t>(ast_id.ToInt()); 62 return static_cast<uint32_t>(ast_id.ToInt());
59 } 63 }
60 64
61 65
62 Handle<Object> TypeFeedbackOracle::GetInfo(TypeFeedbackId ast_id) { 66 Handle<Object> TypeFeedbackOracle::GetInfo(TypeFeedbackId ast_id) {
63 int entry = dictionary_->FindEntry(IdToKey(ast_id)); 67 int entry = dictionary_->FindEntry(IdToKey(ast_id));
64 if (entry != UnseededNumberDictionary::kNotFound) { 68 if (entry != UnseededNumberDictionary::kNotFound) {
65 Object* value = dictionary_->ValueAt(entry); 69 Object* value = dictionary_->ValueAt(entry);
66 if (value->IsCell()) { 70 if (value->IsCell()) {
67 Cell* cell = Cell::cast(value); 71 Cell* cell = Cell::cast(value);
68 return Handle<Object>(cell->value(), isolate_); 72 return Handle<Object>(cell->value(), isolate());
69 } else { 73 } else {
70 return Handle<Object>(value, isolate_); 74 return Handle<Object>(value, isolate());
71 } 75 }
72 } 76 }
73 return Handle<Object>::cast(isolate_->factory()->undefined_value()); 77 return Handle<Object>::cast(isolate()->factory()->undefined_value());
74 } 78 }
75 79
76 80
77 Handle<Cell> TypeFeedbackOracle::GetInfoCell( 81 Handle<Object> TypeFeedbackOracle::GetInfo(int slot) {
78 TypeFeedbackId ast_id) { 82 ASSERT(slot >= 0 && slot < feedback_vector_->length());
79 int entry = dictionary_->FindEntry(IdToKey(ast_id)); 83 Object* obj = feedback_vector_->get(slot);
80 if (entry != UnseededNumberDictionary::kNotFound) { 84 if (!obj->IsJSFunction() ||
81 Cell* cell = Cell::cast(dictionary_->ValueAt(entry)); 85 !CanRetainOtherContext(JSFunction::cast(obj), *native_context_)) {
82 return Handle<Cell>(cell, isolate_); 86 return Handle<Object>(obj, isolate());
83 } 87 }
84 return Handle<Cell>::null(); 88 return Handle<Object>::cast(isolate()->factory()->undefined_value());
85 } 89 }
86 90
87 91
88 bool TypeFeedbackOracle::LoadIsUninitialized(TypeFeedbackId id) { 92 bool TypeFeedbackOracle::LoadIsUninitialized(TypeFeedbackId id) {
89 Handle<Object> maybe_code = GetInfo(id); 93 Handle<Object> maybe_code = GetInfo(id);
90 if (maybe_code->IsCode()) { 94 if (maybe_code->IsCode()) {
91 Handle<Code> code = Handle<Code>::cast(maybe_code); 95 Handle<Code> code = Handle<Code>::cast(maybe_code);
92 return code->is_inline_cache_stub() && code->ic_state() == UNINITIALIZED; 96 return code->is_inline_cache_stub() && code->ic_state() == UNINITIALIZED;
93 } 97 }
94 return false; 98 return false;
95 } 99 }
96 100
97 101
98 bool TypeFeedbackOracle::LoadIsPreMonomorphic(TypeFeedbackId id) {
99 Handle<Object> maybe_code = GetInfo(id);
100 if (maybe_code->IsCode()) {
101 Handle<Code> code = Handle<Code>::cast(maybe_code);
102 return code->is_inline_cache_stub() && code->ic_state() == PREMONOMORPHIC;
103 }
104 return false;
105 }
106
107
108 bool TypeFeedbackOracle::StoreIsUninitialized(TypeFeedbackId ast_id) { 102 bool TypeFeedbackOracle::StoreIsUninitialized(TypeFeedbackId ast_id) {
109 Handle<Object> maybe_code = GetInfo(ast_id); 103 Handle<Object> maybe_code = GetInfo(ast_id);
110 if (!maybe_code->IsCode()) return false; 104 if (!maybe_code->IsCode()) return false;
111 Handle<Code> code = Handle<Code>::cast(maybe_code); 105 Handle<Code> code = Handle<Code>::cast(maybe_code);
112 return code->ic_state() == UNINITIALIZED; 106 return code->ic_state() == UNINITIALIZED;
113 } 107 }
114 108
115 109
116 bool TypeFeedbackOracle::StoreIsPreMonomorphic(TypeFeedbackId ast_id) {
117 Handle<Object> maybe_code = GetInfo(ast_id);
118 if (maybe_code->IsCode()) {
119 Handle<Code> code = Handle<Code>::cast(maybe_code);
120 return code->ic_state() == PREMONOMORPHIC;
121 }
122 return false;
123 }
124
125
126 bool TypeFeedbackOracle::StoreIsKeyedPolymorphic(TypeFeedbackId ast_id) { 110 bool TypeFeedbackOracle::StoreIsKeyedPolymorphic(TypeFeedbackId ast_id) {
127 Handle<Object> maybe_code = GetInfo(ast_id); 111 Handle<Object> maybe_code = GetInfo(ast_id);
128 if (maybe_code->IsCode()) { 112 if (maybe_code->IsCode()) {
129 Handle<Code> code = Handle<Code>::cast(maybe_code); 113 Handle<Code> code = Handle<Code>::cast(maybe_code);
130 return code->is_keyed_store_stub() && 114 return code->is_keyed_store_stub() &&
131 code->ic_state() == POLYMORPHIC; 115 code->ic_state() == POLYMORPHIC;
132 } 116 }
133 return false; 117 return false;
134 } 118 }
135 119
136 120
137 bool TypeFeedbackOracle::CallIsMonomorphic(TypeFeedbackId id) { 121 bool TypeFeedbackOracle::CallIsMonomorphic(int slot) {
138 Handle<Object> value = GetInfo(id); 122 Handle<Object> value = GetInfo(slot);
139 return value->IsAllocationSite() || value->IsJSFunction() || value->IsSmi() || 123 return value->IsAllocationSite() || value->IsJSFunction();
140 (value->IsCode() && Handle<Code>::cast(value)->ic_state() == MONOMORPHIC);
141 } 124 }
142 125
143 126
144 bool TypeFeedbackOracle::KeyedArrayCallIsHoley(TypeFeedbackId id) { 127 bool TypeFeedbackOracle::CallNewIsMonomorphic(int slot) {
145 Handle<Object> value = GetInfo(id); 128 Handle<Object> info = GetInfo(slot);
146 Handle<Code> code = Handle<Code>::cast(value);
147 return KeyedArrayCallStub::IsHoley(code);
148 }
149
150
151 bool TypeFeedbackOracle::CallNewIsMonomorphic(TypeFeedbackId id) {
152 Handle<Object> info = GetInfo(id);
153 return info->IsAllocationSite() || info->IsJSFunction(); 129 return info->IsAllocationSite() || info->IsJSFunction();
154 } 130 }
155 131
156 132
157 byte TypeFeedbackOracle::ForInType(TypeFeedbackId id) { 133 byte TypeFeedbackOracle::ForInType(int feedback_vector_slot) {
158 Handle<Object> value = GetInfo(id); 134 Handle<Object> value = GetInfo(feedback_vector_slot);
159 return value->IsSmi() && 135 return value->IsSmi() &&
160 Smi::cast(*value)->value() == TypeFeedbackCells::kForInFastCaseMarker 136 Smi::cast(*value)->value() == TypeFeedbackInfo::kForInFastCaseMarker
161 ? ForInStatement::FAST_FOR_IN : ForInStatement::SLOW_FOR_IN; 137 ? ForInStatement::FAST_FOR_IN : ForInStatement::SLOW_FOR_IN;
162 } 138 }
163 139
164 140
165 KeyedAccessStoreMode TypeFeedbackOracle::GetStoreMode( 141 KeyedAccessStoreMode TypeFeedbackOracle::GetStoreMode(
166 TypeFeedbackId ast_id) { 142 TypeFeedbackId ast_id) {
167 Handle<Object> maybe_code = GetInfo(ast_id); 143 Handle<Object> maybe_code = GetInfo(ast_id);
168 if (maybe_code->IsCode()) { 144 if (maybe_code->IsCode()) {
169 Handle<Code> code = Handle<Code>::cast(maybe_code); 145 Handle<Code> code = Handle<Code>::cast(maybe_code);
170 if (code->kind() == Code::KEYED_STORE_IC) { 146 if (code->kind() == Code::KEYED_STORE_IC) {
171 return KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state()); 147 return KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state());
172 } 148 }
173 } 149 }
174 return STANDARD_STORE; 150 return STANDARD_STORE;
175 } 151 }
176 152
177 153
178 void TypeFeedbackOracle::CallReceiverTypes(TypeFeedbackId id, 154 Handle<JSFunction> TypeFeedbackOracle::GetCallTarget(int slot) {
179 Handle<String> name, 155 Handle<Object> info = GetInfo(slot);
180 int arity,
181 SmallMapList* types) {
182 Code::Flags flags = Code::ComputeMonomorphicFlags(
183 Code::CALL_IC, kNoExtraICState, OWN_MAP, Code::NORMAL, arity);
184 CollectReceiverTypes(id, name, flags, types);
185 }
186
187
188 CheckType TypeFeedbackOracle::GetCallCheckType(TypeFeedbackId id) {
189 Handle<Object> value = GetInfo(id);
190 if (!value->IsSmi()) return RECEIVER_MAP_CHECK;
191 CheckType check = static_cast<CheckType>(Smi::cast(*value)->value());
192 ASSERT(check != RECEIVER_MAP_CHECK);
193 return check;
194 }
195
196
197 Handle<JSFunction> TypeFeedbackOracle::GetCallTarget(TypeFeedbackId id) {
198 Handle<Object> info = GetInfo(id);
199 if (info->IsAllocationSite()) { 156 if (info->IsAllocationSite()) {
200 return Handle<JSFunction>(isolate_->global_context()->array_function()); 157 return Handle<JSFunction>(isolate()->native_context()->array_function());
201 } else { 158 } else {
202 return Handle<JSFunction>::cast(info); 159 return Handle<JSFunction>::cast(info);
203 } 160 }
204 } 161 }
205 162
206 163
207 Handle<JSFunction> TypeFeedbackOracle::GetCallNewTarget(TypeFeedbackId id) { 164 Handle<JSFunction> TypeFeedbackOracle::GetCallNewTarget(int slot) {
208 Handle<Object> info = GetInfo(id); 165 Handle<Object> info = GetInfo(slot);
209 if (info->IsAllocationSite()) { 166 if (info->IsAllocationSite()) {
210 return Handle<JSFunction>(isolate_->global_context()->array_function()); 167 return Handle<JSFunction>(isolate()->native_context()->array_function());
211 } else { 168 } else {
212 return Handle<JSFunction>::cast(info); 169 return Handle<JSFunction>::cast(info);
213 } 170 }
214 } 171 }
215 172
216 173
217 Handle<Cell> TypeFeedbackOracle::GetCallNewAllocationInfoCell( 174 Handle<AllocationSite> TypeFeedbackOracle::GetCallNewAllocationSite(int slot) {
218 TypeFeedbackId id) { 175 Handle<Object> info = GetInfo(slot);
219 return GetInfoCell(id); 176 if (info->IsAllocationSite()) {
177 return Handle<AllocationSite>::cast(info);
178 }
179 return Handle<AllocationSite>::null();
220 } 180 }
221 181
222 182
223 bool TypeFeedbackOracle::LoadIsBuiltin( 183 bool TypeFeedbackOracle::LoadIsBuiltin(
224 TypeFeedbackId id, Builtins::Name builtin) { 184 TypeFeedbackId id, Builtins::Name builtin) {
225 return *GetInfo(id) == isolate_->builtins()->builtin(builtin); 185 return *GetInfo(id) == isolate()->builtins()->builtin(builtin);
226 } 186 }
227 187
228 188
229 bool TypeFeedbackOracle::LoadIsStub(TypeFeedbackId id, ICStub* stub) { 189 bool TypeFeedbackOracle::LoadIsStub(TypeFeedbackId id, ICStub* stub) {
230 Handle<Object> object = GetInfo(id); 190 Handle<Object> object = GetInfo(id);
231 if (!object->IsCode()) return false; 191 if (!object->IsCode()) return false;
232 Handle<Code> code = Handle<Code>::cast(object); 192 Handle<Code> code = Handle<Code>::cast(object);
233 if (!code->is_load_stub()) return false; 193 if (!code->is_load_stub()) return false;
234 if (code->ic_state() != MONOMORPHIC) return false; 194 if (code->ic_state() != MONOMORPHIC) return false;
235 return stub->Describes(*code); 195 return stub->Describes(*code);
236 } 196 }
237 197
238 198
239 void TypeFeedbackOracle::CompareType(TypeFeedbackId id, 199 void TypeFeedbackOracle::CompareType(TypeFeedbackId id,
240 Handle<Type>* left_type, 200 Type** left_type,
241 Handle<Type>* right_type, 201 Type** right_type,
242 Handle<Type>* combined_type) { 202 Type** combined_type) {
243 Handle<Object> info = GetInfo(id); 203 Handle<Object> info = GetInfo(id);
244 if (!info->IsCode()) { 204 if (!info->IsCode()) {
245 // For some comparisons we don't have ICs, e.g. LiteralCompareTypeof. 205 // For some comparisons we don't have ICs, e.g. LiteralCompareTypeof.
246 *left_type = *right_type = *combined_type = Type::None(isolate_); 206 *left_type = *right_type = *combined_type = Type::None(zone());
247 return; 207 return;
248 } 208 }
249 Handle<Code> code = Handle<Code>::cast(info); 209 Handle<Code> code = Handle<Code>::cast(info);
250 210
251 Handle<Map> map; 211 Handle<Map> map;
252 Map* raw_map = code->FindFirstMap(); 212 Map* raw_map = code->FindFirstMap();
253 if (raw_map != NULL) { 213 if (raw_map != NULL) {
254 map = Map::CurrentMapForDeprecated(handle(raw_map)); 214 map = Map::CurrentMapForDeprecated(handle(raw_map));
255 if (!map.is_null() && CanRetainOtherContext(*map, *native_context_)) { 215 if (!map.is_null() && CanRetainOtherContext(*map, *native_context_)) {
256 map = Handle<Map>::null(); 216 map = Handle<Map>::null();
257 } 217 }
258 } 218 }
259 219
260 if (code->is_compare_ic_stub()) { 220 if (code->is_compare_ic_stub()) {
261 int stub_minor_key = code->stub_info(); 221 int stub_minor_key = code->stub_info();
262 CompareIC::StubInfoToType( 222 CompareIC::StubInfoToType(
263 stub_minor_key, left_type, right_type, combined_type, map, isolate()); 223 stub_minor_key, left_type, right_type, combined_type, map, zone());
264 } else if (code->is_compare_nil_ic_stub()) { 224 } else if (code->is_compare_nil_ic_stub()) {
265 CompareNilICStub stub(code->extended_extra_ic_state()); 225 CompareNilICStub stub(code->extra_ic_state());
266 *combined_type = stub.GetType(isolate_, map); 226 *combined_type = stub.GetType(zone(), map);
267 *left_type = *right_type = stub.GetInputType(isolate_, map); 227 *left_type = *right_type = stub.GetInputType(zone(), map);
268 } 228 }
269 } 229 }
270 230
271 231
272 void TypeFeedbackOracle::BinaryType(TypeFeedbackId id, 232 void TypeFeedbackOracle::BinaryType(TypeFeedbackId id,
273 Handle<Type>* left, 233 Type** left,
274 Handle<Type>* right, 234 Type** right,
275 Handle<Type>* result, 235 Type** result,
276 Maybe<int>* fixed_right_arg, 236 Maybe<int>* fixed_right_arg,
277 Handle<AllocationSite>* allocation_site, 237 Handle<AllocationSite>* allocation_site,
278 Token::Value op) { 238 Token::Value op) {
279 Handle<Object> object = GetInfo(id); 239 Handle<Object> object = GetInfo(id);
280 if (!object->IsCode()) { 240 if (!object->IsCode()) {
281 // For some binary ops we don't have ICs, e.g. Token::COMMA, but for the 241 // For some binary ops we don't have ICs, e.g. Token::COMMA, but for the
282 // operations covered by the BinaryOpIC we should always have them. 242 // operations covered by the BinaryOpIC we should always have them.
283 ASSERT(op < BinaryOpIC::State::FIRST_TOKEN || 243 ASSERT(op < BinaryOpIC::State::FIRST_TOKEN ||
284 op > BinaryOpIC::State::LAST_TOKEN); 244 op > BinaryOpIC::State::LAST_TOKEN);
285 *left = *right = *result = Type::None(isolate_); 245 *left = *right = *result = Type::None(zone());
286 *fixed_right_arg = Maybe<int>(); 246 *fixed_right_arg = Maybe<int>();
287 *allocation_site = Handle<AllocationSite>::null(); 247 *allocation_site = Handle<AllocationSite>::null();
288 return; 248 return;
289 } 249 }
290 Handle<Code> code = Handle<Code>::cast(object); 250 Handle<Code> code = Handle<Code>::cast(object);
291 ASSERT_EQ(Code::BINARY_OP_IC, code->kind()); 251 ASSERT_EQ(Code::BINARY_OP_IC, code->kind());
292 BinaryOpIC::State state(code->extended_extra_ic_state()); 252 BinaryOpIC::State state(code->extra_ic_state());
293 ASSERT_EQ(op, state.op()); 253 ASSERT_EQ(op, state.op());
294 254
295 *left = state.GetLeftType(isolate()); 255 *left = state.GetLeftType(zone());
296 *right = state.GetRightType(isolate()); 256 *right = state.GetRightType(zone());
297 *result = state.GetResultType(isolate()); 257 *result = state.GetResultType(zone());
298 *fixed_right_arg = state.fixed_right_arg(); 258 *fixed_right_arg = state.fixed_right_arg();
299 259
300 AllocationSite* first_allocation_site = code->FindFirstAllocationSite(); 260 AllocationSite* first_allocation_site = code->FindFirstAllocationSite();
301 if (first_allocation_site != NULL) { 261 if (first_allocation_site != NULL) {
302 *allocation_site = handle(first_allocation_site); 262 *allocation_site = handle(first_allocation_site);
303 } else { 263 } else {
304 *allocation_site = Handle<AllocationSite>::null(); 264 *allocation_site = Handle<AllocationSite>::null();
305 } 265 }
306 } 266 }
307 267
308 268
309 Handle<Type> TypeFeedbackOracle::CountType(TypeFeedbackId id) { 269 Type* TypeFeedbackOracle::CountType(TypeFeedbackId id) {
310 Handle<Object> object = GetInfo(id); 270 Handle<Object> object = GetInfo(id);
311 if (!object->IsCode()) return Type::None(isolate_); 271 if (!object->IsCode()) return Type::None(zone());
312 Handle<Code> code = Handle<Code>::cast(object); 272 Handle<Code> code = Handle<Code>::cast(object);
313 ASSERT_EQ(Code::BINARY_OP_IC, code->kind()); 273 ASSERT_EQ(Code::BINARY_OP_IC, code->kind());
314 BinaryOpIC::State state(code->extended_extra_ic_state()); 274 BinaryOpIC::State state(code->extra_ic_state());
315 return state.GetLeftType(isolate()); 275 return state.GetLeftType(zone());
316 } 276 }
317 277
318 278
319 void TypeFeedbackOracle::PropertyReceiverTypes( 279 void TypeFeedbackOracle::PropertyReceiverTypes(
320 TypeFeedbackId id, Handle<String> name, 280 TypeFeedbackId id, Handle<String> name,
321 SmallMapList* receiver_types, bool* is_prototype) { 281 SmallMapList* receiver_types, bool* is_prototype) {
322 receiver_types->Clear(); 282 receiver_types->Clear();
323 FunctionPrototypeStub proto_stub(Code::LOAD_IC); 283 FunctionPrototypeStub proto_stub(Code::LOAD_IC);
324 *is_prototype = LoadIsStub(id, &proto_stub); 284 *is_prototype = LoadIsStub(id, &proto_stub);
325 if (!*is_prototype) { 285 if (!*is_prototype) {
326 Code::Flags flags = Code::ComputeFlags( 286 Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC);
327 Code::HANDLER, MONOMORPHIC, kNoExtraICState,
328 Code::NORMAL, Code::LOAD_IC);
329 CollectReceiverTypes(id, name, flags, receiver_types); 287 CollectReceiverTypes(id, name, flags, receiver_types);
330 } 288 }
331 } 289 }
332 290
333 291
334 void TypeFeedbackOracle::KeyedPropertyReceiverTypes( 292 void TypeFeedbackOracle::KeyedPropertyReceiverTypes(
335 TypeFeedbackId id, SmallMapList* receiver_types, bool* is_string) { 293 TypeFeedbackId id, SmallMapList* receiver_types, bool* is_string) {
336 receiver_types->Clear(); 294 receiver_types->Clear();
337 *is_string = false; 295 *is_string = false;
338 if (LoadIsBuiltin(id, Builtins::kKeyedLoadIC_String)) { 296 if (LoadIsBuiltin(id, Builtins::kKeyedLoadIC_String)) {
339 *is_string = true; 297 *is_string = true;
340 } else { 298 } else {
341 CollectReceiverTypes(id, receiver_types); 299 CollectReceiverTypes(id, receiver_types);
342 } 300 }
343 } 301 }
344 302
345 303
346 void TypeFeedbackOracle::AssignmentReceiverTypes( 304 void TypeFeedbackOracle::AssignmentReceiverTypes(
347 TypeFeedbackId id, Handle<String> name, SmallMapList* receiver_types) { 305 TypeFeedbackId id, Handle<String> name, SmallMapList* receiver_types) {
348 receiver_types->Clear(); 306 receiver_types->Clear();
349 Code::Flags flags = Code::ComputeFlags( 307 Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC);
350 Code::HANDLER, MONOMORPHIC, kNoExtraICState,
351 Code::NORMAL, Code::STORE_IC);
352 CollectReceiverTypes(id, name, flags, receiver_types); 308 CollectReceiverTypes(id, name, flags, receiver_types);
353 } 309 }
354 310
355 311
356 void TypeFeedbackOracle::KeyedAssignmentReceiverTypes( 312 void TypeFeedbackOracle::KeyedAssignmentReceiverTypes(
357 TypeFeedbackId id, SmallMapList* receiver_types, 313 TypeFeedbackId id, SmallMapList* receiver_types,
358 KeyedAccessStoreMode* store_mode) { 314 KeyedAccessStoreMode* store_mode) {
359 receiver_types->Clear(); 315 receiver_types->Clear();
360 CollectReceiverTypes(id, receiver_types); 316 CollectReceiverTypes(id, receiver_types);
361 *store_mode = GetStoreMode(id); 317 *store_mode = GetStoreMode(id);
(...skipping 13 matching lines...) Expand all
375 SmallMapList* types) { 331 SmallMapList* types) {
376 Handle<Object> object = GetInfo(ast_id); 332 Handle<Object> object = GetInfo(ast_id);
377 if (object->IsUndefined() || object->IsSmi()) return; 333 if (object->IsUndefined() || object->IsSmi()) return;
378 334
379 ASSERT(object->IsCode()); 335 ASSERT(object->IsCode());
380 Handle<Code> code(Handle<Code>::cast(object)); 336 Handle<Code> code(Handle<Code>::cast(object));
381 337
382 if (FLAG_collect_megamorphic_maps_from_stub_cache && 338 if (FLAG_collect_megamorphic_maps_from_stub_cache &&
383 code->ic_state() == MEGAMORPHIC) { 339 code->ic_state() == MEGAMORPHIC) {
384 types->Reserve(4, zone()); 340 types->Reserve(4, zone());
385 isolate_->stub_cache()->CollectMatchingMaps( 341 isolate()->stub_cache()->CollectMatchingMaps(
386 types, name, flags, native_context_, zone()); 342 types, name, flags, native_context_, zone());
387 } else { 343 } else {
388 CollectReceiverTypes(ast_id, types); 344 CollectReceiverTypes(ast_id, types);
389 } 345 }
390 } 346 }
391 347
392 348
393 // Check if a map originates from a given native context. We use this 349 // Check if a map originates from a given native context. We use this
394 // information to filter out maps from different context to avoid 350 // information to filter out maps from different context to avoid
395 // retaining objects from different tabs in Chrome via optimized code. 351 // retaining objects from different tabs in Chrome via optimized code.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 } 410 }
455 411
456 412
457 // Things are a bit tricky here: The iterator for the RelocInfos and the infos 413 // Things are a bit tricky here: The iterator for the RelocInfos and the infos
458 // themselves are not GC-safe, so we first get all infos, then we create the 414 // themselves are not GC-safe, so we first get all infos, then we create the
459 // dictionary (possibly triggering GC), and finally we relocate the collected 415 // dictionary (possibly triggering GC), and finally we relocate the collected
460 // infos before we process them. 416 // infos before we process them.
461 void TypeFeedbackOracle::BuildDictionary(Handle<Code> code) { 417 void TypeFeedbackOracle::BuildDictionary(Handle<Code> code) {
462 DisallowHeapAllocation no_allocation; 418 DisallowHeapAllocation no_allocation;
463 ZoneList<RelocInfo> infos(16, zone()); 419 ZoneList<RelocInfo> infos(16, zone());
464 HandleScope scope(isolate_); 420 HandleScope scope(isolate());
465 GetRelocInfos(code, &infos); 421 GetRelocInfos(code, &infos);
466 CreateDictionary(code, &infos); 422 CreateDictionary(code, &infos);
467 ProcessRelocInfos(&infos); 423 ProcessRelocInfos(&infos);
468 ProcessTypeFeedbackCells(code);
469 // Allocate handle in the parent scope. 424 // Allocate handle in the parent scope.
470 dictionary_ = scope.CloseAndEscape(dictionary_); 425 dictionary_ = scope.CloseAndEscape(dictionary_);
471 } 426 }
472 427
473 428
474 void TypeFeedbackOracle::GetRelocInfos(Handle<Code> code, 429 void TypeFeedbackOracle::GetRelocInfos(Handle<Code> code,
475 ZoneList<RelocInfo>* infos) { 430 ZoneList<RelocInfo>* infos) {
476 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID); 431 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID);
477 for (RelocIterator it(*code, mask); !it.done(); it.next()) { 432 for (RelocIterator it(*code, mask); !it.done(); it.next()) {
478 infos->Add(*it.rinfo(), zone()); 433 infos->Add(*it.rinfo(), zone());
479 } 434 }
480 } 435 }
481 436
482 437
483 void TypeFeedbackOracle::CreateDictionary(Handle<Code> code, 438 void TypeFeedbackOracle::CreateDictionary(Handle<Code> code,
484 ZoneList<RelocInfo>* infos) { 439 ZoneList<RelocInfo>* infos) {
485 AllowHeapAllocation allocation_allowed; 440 AllowHeapAllocation allocation_allowed;
486 int cell_count = code->type_feedback_info()->IsTypeFeedbackInfo()
487 ? TypeFeedbackInfo::cast(code->type_feedback_info())->
488 type_feedback_cells()->CellCount()
489 : 0;
490 int length = infos->length() + cell_count;
491 byte* old_start = code->instruction_start(); 441 byte* old_start = code->instruction_start();
492 dictionary_ = isolate()->factory()->NewUnseededNumberDictionary(length); 442 dictionary_ =
443 isolate()->factory()->NewUnseededNumberDictionary(infos->length());
493 byte* new_start = code->instruction_start(); 444 byte* new_start = code->instruction_start();
494 RelocateRelocInfos(infos, old_start, new_start); 445 RelocateRelocInfos(infos, old_start, new_start);
495 } 446 }
496 447
497 448
498 void TypeFeedbackOracle::RelocateRelocInfos(ZoneList<RelocInfo>* infos, 449 void TypeFeedbackOracle::RelocateRelocInfos(ZoneList<RelocInfo>* infos,
499 byte* old_start, 450 byte* old_start,
500 byte* new_start) { 451 byte* new_start) {
501 for (int i = 0; i < infos->length(); i++) { 452 for (int i = 0; i < infos->length(); i++) {
502 RelocInfo* info = &(*infos)[i]; 453 RelocInfo* info = &(*infos)[i];
503 info->set_pc(new_start + (info->pc() - old_start)); 454 info->set_pc(new_start + (info->pc() - old_start));
504 } 455 }
505 } 456 }
506 457
507 458
508 void TypeFeedbackOracle::ProcessRelocInfos(ZoneList<RelocInfo>* infos) { 459 void TypeFeedbackOracle::ProcessRelocInfos(ZoneList<RelocInfo>* infos) {
509 for (int i = 0; i < infos->length(); i++) { 460 for (int i = 0; i < infos->length(); i++) {
510 RelocInfo reloc_entry = (*infos)[i]; 461 RelocInfo reloc_entry = (*infos)[i];
511 Address target_address = reloc_entry.target_address(); 462 Address target_address = reloc_entry.target_address();
512 TypeFeedbackId ast_id = 463 TypeFeedbackId ast_id =
513 TypeFeedbackId(static_cast<unsigned>((*infos)[i].data())); 464 TypeFeedbackId(static_cast<unsigned>((*infos)[i].data()));
514 Code* target = Code::GetCodeFromTargetAddress(target_address); 465 Code* target = Code::GetCodeFromTargetAddress(target_address);
515 switch (target->kind()) { 466 switch (target->kind()) {
516 case Code::CALL_IC:
517 if (target->ic_state() == MONOMORPHIC &&
518 target->check_type() != RECEIVER_MAP_CHECK) {
519 SetInfo(ast_id, Smi::FromInt(target->check_type()));
520 break;
521 }
522 case Code::LOAD_IC: 467 case Code::LOAD_IC:
523 case Code::STORE_IC: 468 case Code::STORE_IC:
524 case Code::KEYED_CALL_IC:
525 case Code::KEYED_LOAD_IC: 469 case Code::KEYED_LOAD_IC:
526 case Code::KEYED_STORE_IC: 470 case Code::KEYED_STORE_IC:
527 case Code::BINARY_OP_IC: 471 case Code::BINARY_OP_IC:
528 case Code::COMPARE_IC: 472 case Code::COMPARE_IC:
529 case Code::TO_BOOLEAN_IC: 473 case Code::TO_BOOLEAN_IC:
530 case Code::COMPARE_NIL_IC: 474 case Code::COMPARE_NIL_IC:
531 SetInfo(ast_id, target); 475 SetInfo(ast_id, target);
532 break; 476 break;
533 477
534 default: 478 default:
535 break; 479 break;
536 } 480 }
537 } 481 }
538 } 482 }
539 483
540 484
541 void TypeFeedbackOracle::ProcessTypeFeedbackCells(Handle<Code> code) {
542 Object* raw_info = code->type_feedback_info();
543 if (!raw_info->IsTypeFeedbackInfo()) return;
544 Handle<TypeFeedbackCells> cache(
545 TypeFeedbackInfo::cast(raw_info)->type_feedback_cells());
546 for (int i = 0; i < cache->CellCount(); i++) {
547 TypeFeedbackId ast_id = cache->AstId(i);
548 Cell* cell = cache->GetCell(i);
549 Object* value = cell->value();
550 if (value->IsSmi() ||
551 value->IsAllocationSite() ||
552 (value->IsJSFunction() &&
553 !CanRetainOtherContext(JSFunction::cast(value),
554 *native_context_))) {
555 SetInfo(ast_id, cell);
556 }
557 }
558 }
559
560
561 void TypeFeedbackOracle::SetInfo(TypeFeedbackId ast_id, Object* target) { 485 void TypeFeedbackOracle::SetInfo(TypeFeedbackId ast_id, Object* target) {
562 ASSERT(dictionary_->FindEntry(IdToKey(ast_id)) == 486 ASSERT(dictionary_->FindEntry(IdToKey(ast_id)) ==
563 UnseededNumberDictionary::kNotFound); 487 UnseededNumberDictionary::kNotFound);
564 MaybeObject* maybe_result = dictionary_->AtNumberPut(IdToKey(ast_id), target); 488 MaybeObject* maybe_result = dictionary_->AtNumberPut(IdToKey(ast_id), target);
565 USE(maybe_result); 489 USE(maybe_result);
566 #ifdef DEBUG 490 #ifdef DEBUG
567 Object* result = NULL; 491 Object* result = NULL;
568 // Dictionary has been allocated with sufficient size for all elements. 492 // Dictionary has been allocated with sufficient size for all elements.
569 ASSERT(maybe_result->ToObject(&result)); 493 ASSERT(maybe_result->ToObject(&result));
570 ASSERT(*dictionary_ == result); 494 ASSERT(*dictionary_ == result);
571 #endif 495 #endif
572 } 496 }
573 497
574 498
575 } } // namespace v8::internal 499 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/type-info.h ('k') | src/typedarray.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698