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

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

Issue 157503002: A64: Synchronize with r18444. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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/typing.h » ('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 24 matching lines...) Expand all
35 #include "stub-cache.h" 35 #include "stub-cache.h"
36 #include "type-info.h" 36 #include "type-info.h"
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 TypeInfo TypeInfo::FromValue(Handle<Object> value) {
46 if (value->IsSmi()) {
47 return TypeInfo::Smi();
48 } else if (value->IsHeapNumber()) {
49 return TypeInfo::IsInt32Double(HeapNumber::cast(*value)->value())
50 ? TypeInfo::Integer32()
51 : TypeInfo::Double();
52 } else if (value->IsString()) {
53 return TypeInfo::String();
54 }
55 return TypeInfo::Unknown();
56 }
57
58
59 TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code, 45 TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code,
60 Handle<Context> native_context, 46 Handle<Context> native_context,
61 Isolate* isolate, 47 Isolate* isolate,
62 Zone* zone) 48 Zone* zone)
63 : native_context_(native_context), 49 : native_context_(native_context),
64 isolate_(isolate), 50 isolate_(isolate),
65 zone_(zone) { 51 zone_(zone) {
66 BuildDictionary(code); 52 BuildDictionary(code);
67 ASSERT(dictionary_->IsDictionary()); 53 ASSERT(dictionary_->IsDictionary());
68 } 54 }
(...skipping 24 matching lines...) Expand all
93 int entry = dictionary_->FindEntry(IdToKey(ast_id)); 79 int entry = dictionary_->FindEntry(IdToKey(ast_id));
94 if (entry != UnseededNumberDictionary::kNotFound) { 80 if (entry != UnseededNumberDictionary::kNotFound) {
95 Cell* cell = Cell::cast(dictionary_->ValueAt(entry)); 81 Cell* cell = Cell::cast(dictionary_->ValueAt(entry));
96 return Handle<Cell>(cell, isolate_); 82 return Handle<Cell>(cell, isolate_);
97 } 83 }
98 return Handle<Cell>::null(); 84 return Handle<Cell>::null();
99 } 85 }
100 86
101 87
102 bool TypeFeedbackOracle::LoadIsUninitialized(TypeFeedbackId id) { 88 bool TypeFeedbackOracle::LoadIsUninitialized(TypeFeedbackId id) {
103 Handle<Object> map_or_code = GetInfo(id); 89 Handle<Object> maybe_code = GetInfo(id);
104 if (map_or_code->IsMap()) return false; 90 if (maybe_code->IsCode()) {
105 if (map_or_code->IsCode()) { 91 Handle<Code> code = Handle<Code>::cast(maybe_code);
106 Handle<Code> code = Handle<Code>::cast(map_or_code);
107 return code->is_inline_cache_stub() && code->ic_state() == UNINITIALIZED; 92 return code->is_inline_cache_stub() && code->ic_state() == UNINITIALIZED;
108 } 93 }
109 return false; 94 return false;
110 } 95 }
111 96
112 97
113 bool TypeFeedbackOracle::LoadIsMonomorphicNormal(TypeFeedbackId id) {
114 Handle<Object> map_or_code = GetInfo(id);
115 if (map_or_code->IsMap()) return true;
116 if (map_or_code->IsCode()) {
117 Handle<Code> code = Handle<Code>::cast(map_or_code);
118 bool preliminary_checks = code->is_keyed_load_stub() &&
119 code->ic_state() == MONOMORPHIC &&
120 Code::ExtractTypeFromFlags(code->flags()) == Code::NORMAL;
121 if (!preliminary_checks) return false;
122 Map* map = code->FindFirstMap();
123 if (map == NULL) return false;
124 map = map->CurrentMapForDeprecated();
125 return map != NULL && !CanRetainOtherContext(map, *native_context_);
126 }
127 return false;
128 }
129
130
131 bool TypeFeedbackOracle::LoadIsPreMonomorphic(TypeFeedbackId id) { 98 bool TypeFeedbackOracle::LoadIsPreMonomorphic(TypeFeedbackId id) {
132 Handle<Object> map_or_code = GetInfo(id); 99 Handle<Object> maybe_code = GetInfo(id);
133 if (map_or_code->IsCode()) { 100 if (maybe_code->IsCode()) {
134 Handle<Code> code = Handle<Code>::cast(map_or_code); 101 Handle<Code> code = Handle<Code>::cast(maybe_code);
135 return code->is_inline_cache_stub() && code->ic_state() == PREMONOMORPHIC; 102 return code->is_inline_cache_stub() && code->ic_state() == PREMONOMORPHIC;
136 } 103 }
137 return false; 104 return false;
138 } 105 }
139 106
140 107
141 bool TypeFeedbackOracle::LoadIsPolymorphic(TypeFeedbackId id) {
142 Handle<Object> map_or_code = GetInfo(id);
143 if (map_or_code->IsCode()) {
144 Handle<Code> code = Handle<Code>::cast(map_or_code);
145 return code->is_keyed_load_stub() && code->ic_state() == POLYMORPHIC;
146 }
147 return false;
148 }
149
150
151 bool TypeFeedbackOracle::StoreIsUninitialized(TypeFeedbackId ast_id) { 108 bool TypeFeedbackOracle::StoreIsUninitialized(TypeFeedbackId ast_id) {
152 Handle<Object> map_or_code = GetInfo(ast_id); 109 Handle<Object> maybe_code = GetInfo(ast_id);
153 if (map_or_code->IsMap()) return false; 110 if (!maybe_code->IsCode()) return false;
154 if (!map_or_code->IsCode()) return false; 111 Handle<Code> code = Handle<Code>::cast(maybe_code);
155 Handle<Code> code = Handle<Code>::cast(map_or_code);
156 return code->ic_state() == UNINITIALIZED; 112 return code->ic_state() == UNINITIALIZED;
157 } 113 }
158 114
159 115
160 bool TypeFeedbackOracle::StoreIsMonomorphicNormal(TypeFeedbackId ast_id) {
161 Handle<Object> map_or_code = GetInfo(ast_id);
162 if (map_or_code->IsMap()) return true;
163 if (map_or_code->IsCode()) {
164 Handle<Code> code = Handle<Code>::cast(map_or_code);
165 bool preliminary_checks =
166 code->is_keyed_store_stub() &&
167 code->ic_state() == MONOMORPHIC &&
168 Code::ExtractTypeFromFlags(code->flags()) == Code::NORMAL;
169 if (!preliminary_checks) return false;
170 Map* map = code->FindFirstMap();
171 if (map == NULL) return false;
172 map = map->CurrentMapForDeprecated();
173 return map != NULL && !CanRetainOtherContext(map, *native_context_);
174 }
175 return false;
176 }
177
178
179 bool TypeFeedbackOracle::StoreIsPreMonomorphic(TypeFeedbackId ast_id) { 116 bool TypeFeedbackOracle::StoreIsPreMonomorphic(TypeFeedbackId ast_id) {
180 Handle<Object> map_or_code = GetInfo(ast_id); 117 Handle<Object> maybe_code = GetInfo(ast_id);
181 if (map_or_code->IsCode()) { 118 if (maybe_code->IsCode()) {
182 Handle<Code> code = Handle<Code>::cast(map_or_code); 119 Handle<Code> code = Handle<Code>::cast(maybe_code);
183 return code->ic_state() == PREMONOMORPHIC; 120 return code->ic_state() == PREMONOMORPHIC;
184 } 121 }
185 return false; 122 return false;
186 } 123 }
187 124
188 125
189 bool TypeFeedbackOracle::StoreIsKeyedPolymorphic(TypeFeedbackId ast_id) { 126 bool TypeFeedbackOracle::StoreIsKeyedPolymorphic(TypeFeedbackId ast_id) {
190 Handle<Object> map_or_code = GetInfo(ast_id); 127 Handle<Object> maybe_code = GetInfo(ast_id);
191 if (map_or_code->IsCode()) { 128 if (maybe_code->IsCode()) {
192 Handle<Code> code = Handle<Code>::cast(map_or_code); 129 Handle<Code> code = Handle<Code>::cast(maybe_code);
193 return code->is_keyed_store_stub() && 130 return code->is_keyed_store_stub() &&
194 code->ic_state() == POLYMORPHIC; 131 code->ic_state() == POLYMORPHIC;
195 } 132 }
196 return false; 133 return false;
197 } 134 }
198 135
199 136
200 bool TypeFeedbackOracle::CallIsMonomorphic(TypeFeedbackId id) { 137 bool TypeFeedbackOracle::CallIsMonomorphic(TypeFeedbackId id) {
201 Handle<Object> value = GetInfo(id); 138 Handle<Object> value = GetInfo(id);
202 return value->IsMap() || value->IsAllocationSite() || value->IsJSFunction() || 139 return value->IsAllocationSite() || value->IsJSFunction() || value->IsSmi() ||
203 value->IsSmi() ||
204 (value->IsCode() && Handle<Code>::cast(value)->ic_state() == MONOMORPHIC); 140 (value->IsCode() && Handle<Code>::cast(value)->ic_state() == MONOMORPHIC);
205 } 141 }
206 142
207 143
208 bool TypeFeedbackOracle::KeyedArrayCallIsHoley(TypeFeedbackId id) { 144 bool TypeFeedbackOracle::KeyedArrayCallIsHoley(TypeFeedbackId id) {
209 Handle<Object> value = GetInfo(id); 145 Handle<Object> value = GetInfo(id);
210 Handle<Code> code = Handle<Code>::cast(value); 146 Handle<Code> code = Handle<Code>::cast(value);
211 return KeyedArrayCallStub::IsHoley(code); 147 return KeyedArrayCallStub::IsHoley(code);
212 } 148 }
213 149
214 150
215 bool TypeFeedbackOracle::CallNewIsMonomorphic(TypeFeedbackId id) { 151 bool TypeFeedbackOracle::CallNewIsMonomorphic(TypeFeedbackId id) {
216 Handle<Object> info = GetInfo(id); 152 Handle<Object> info = GetInfo(id);
217 return info->IsAllocationSite() || info->IsJSFunction(); 153 return info->IsAllocationSite() || info->IsJSFunction();
218 } 154 }
219 155
220 156
221 bool TypeFeedbackOracle::ObjectLiteralStoreIsMonomorphic(TypeFeedbackId id) {
222 Handle<Object> map_or_code = GetInfo(id);
223 return map_or_code->IsMap();
224 }
225
226
227 byte TypeFeedbackOracle::ForInType(TypeFeedbackId id) { 157 byte TypeFeedbackOracle::ForInType(TypeFeedbackId id) {
228 Handle<Object> value = GetInfo(id); 158 Handle<Object> value = GetInfo(id);
229 return value->IsSmi() && 159 return value->IsSmi() &&
230 Smi::cast(*value)->value() == TypeFeedbackCells::kForInFastCaseMarker 160 Smi::cast(*value)->value() == TypeFeedbackCells::kForInFastCaseMarker
231 ? ForInStatement::FAST_FOR_IN : ForInStatement::SLOW_FOR_IN; 161 ? ForInStatement::FAST_FOR_IN : ForInStatement::SLOW_FOR_IN;
232 } 162 }
233 163
234 164
235 Handle<Map> TypeFeedbackOracle::LoadMonomorphicReceiverType(TypeFeedbackId id) {
236 ASSERT(LoadIsMonomorphicNormal(id));
237 Handle<Object> map_or_code = GetInfo(id);
238 if (map_or_code->IsCode()) {
239 Handle<Code> code = Handle<Code>::cast(map_or_code);
240 Map* map = code->FindFirstMap()->CurrentMapForDeprecated();
241 return map == NULL || CanRetainOtherContext(map, *native_context_)
242 ? Handle<Map>::null()
243 : Handle<Map>(map);
244 }
245 return Handle<Map>::cast(map_or_code);
246 }
247
248
249 Handle<Map> TypeFeedbackOracle::StoreMonomorphicReceiverType(
250 TypeFeedbackId ast_id) {
251 ASSERT(StoreIsMonomorphicNormal(ast_id));
252 Handle<Object> map_or_code = GetInfo(ast_id);
253 if (map_or_code->IsCode()) {
254 Handle<Code> code = Handle<Code>::cast(map_or_code);
255 Map* map = code->FindFirstMap()->CurrentMapForDeprecated();
256 return map == NULL || CanRetainOtherContext(map, *native_context_)
257 ? Handle<Map>::null()
258 : Handle<Map>(map);
259 }
260 return Handle<Map>::cast(map_or_code);
261 }
262
263
264 KeyedAccessStoreMode TypeFeedbackOracle::GetStoreMode( 165 KeyedAccessStoreMode TypeFeedbackOracle::GetStoreMode(
265 TypeFeedbackId ast_id) { 166 TypeFeedbackId ast_id) {
266 Handle<Object> map_or_code = GetInfo(ast_id); 167 Handle<Object> maybe_code = GetInfo(ast_id);
267 if (map_or_code->IsCode()) { 168 if (maybe_code->IsCode()) {
268 Handle<Code> code = Handle<Code>::cast(map_or_code); 169 Handle<Code> code = Handle<Code>::cast(maybe_code);
269 if (code->kind() == Code::KEYED_STORE_IC) { 170 if (code->kind() == Code::KEYED_STORE_IC) {
270 return KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state()); 171 return KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state());
271 } 172 }
272 } 173 }
273 return STANDARD_STORE; 174 return STANDARD_STORE;
274 } 175 }
275 176
276 177
277 void TypeFeedbackOracle::LoadReceiverTypes(TypeFeedbackId id,
278 Handle<String> name,
279 SmallMapList* types) {
280 Code::Flags flags = Code::ComputeFlags(
281 Code::HANDLER, MONOMORPHIC, kNoExtraICState,
282 Code::NORMAL, Code::LOAD_IC);
283 CollectReceiverTypes(id, name, flags, types);
284 }
285
286
287 void TypeFeedbackOracle::StoreReceiverTypes(TypeFeedbackId id,
288 Handle<String> name,
289 SmallMapList* types) {
290 Code::Flags flags = Code::ComputeFlags(
291 Code::HANDLER, MONOMORPHIC, kNoExtraICState,
292 Code::NORMAL, Code::STORE_IC);
293 CollectReceiverTypes(id, name, flags, types);
294 }
295
296
297 void TypeFeedbackOracle::CallReceiverTypes(TypeFeedbackId id, 178 void TypeFeedbackOracle::CallReceiverTypes(TypeFeedbackId id,
298 Handle<String> name, 179 Handle<String> name,
299 int arity, 180 int arity,
300 CallKind call_kind, 181 CallKind call_kind,
301 SmallMapList* types) { 182 SmallMapList* types) {
302 // Note: Currently we do not take string extra ic data into account 183 // Note: Currently we do not take string extra ic data into account
303 // here. 184 // here.
304 ContextualMode contextual_mode = call_kind == CALL_AS_FUNCTION 185 ContextualMode contextual_mode = call_kind == CALL_AS_FUNCTION
305 ? CONTEXTUAL 186 ? CONTEXTUAL
306 : NOT_CONTEXTUAL; 187 : NOT_CONTEXTUAL;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 } 222 }
342 } 223 }
343 224
344 225
345 Handle<Cell> TypeFeedbackOracle::GetCallNewAllocationInfoCell( 226 Handle<Cell> TypeFeedbackOracle::GetCallNewAllocationInfoCell(
346 TypeFeedbackId id) { 227 TypeFeedbackId id) {
347 return GetInfoCell(id); 228 return GetInfoCell(id);
348 } 229 }
349 230
350 231
351 Handle<Map> TypeFeedbackOracle::GetObjectLiteralStoreMap(TypeFeedbackId id) {
352 ASSERT(ObjectLiteralStoreIsMonomorphic(id));
353 return Handle<Map>::cast(GetInfo(id));
354 }
355
356
357 bool TypeFeedbackOracle::LoadIsBuiltin( 232 bool TypeFeedbackOracle::LoadIsBuiltin(
358 TypeFeedbackId id, Builtins::Name builtin) { 233 TypeFeedbackId id, Builtins::Name builtin) {
359 return *GetInfo(id) == isolate_->builtins()->builtin(builtin); 234 return *GetInfo(id) == isolate_->builtins()->builtin(builtin);
360 } 235 }
361 236
362 237
363 bool TypeFeedbackOracle::LoadIsStub(TypeFeedbackId id, ICStub* stub) { 238 bool TypeFeedbackOracle::LoadIsStub(TypeFeedbackId id, ICStub* stub) {
364 Handle<Object> object = GetInfo(id); 239 Handle<Object> object = GetInfo(id);
365 if (!object->IsCode()) return false; 240 if (!object->IsCode()) return false;
366 Handle<Code> code = Handle<Code>::cast(object); 241 Handle<Code> code = Handle<Code>::cast(object);
(...skipping 11 matching lines...) Expand all
378 if (!info->IsCode()) { 253 if (!info->IsCode()) {
379 // For some comparisons we don't have ICs, e.g. LiteralCompareTypeof. 254 // For some comparisons we don't have ICs, e.g. LiteralCompareTypeof.
380 *left_type = *right_type = *combined_type = handle(Type::None(), isolate_); 255 *left_type = *right_type = *combined_type = handle(Type::None(), isolate_);
381 return; 256 return;
382 } 257 }
383 Handle<Code> code = Handle<Code>::cast(info); 258 Handle<Code> code = Handle<Code>::cast(info);
384 259
385 Handle<Map> map; 260 Handle<Map> map;
386 Map* raw_map = code->FindFirstMap(); 261 Map* raw_map = code->FindFirstMap();
387 if (raw_map != NULL) { 262 if (raw_map != NULL) {
388 raw_map = raw_map->CurrentMapForDeprecated(); 263 map = Map::CurrentMapForDeprecated(handle(raw_map));
389 if (raw_map != NULL && !CanRetainOtherContext(raw_map, *native_context_)) { 264 if (!map.is_null() && CanRetainOtherContext(*map, *native_context_)) {
390 map = handle(raw_map, isolate_); 265 map = Handle<Map>::null();
391 } 266 }
392 } 267 }
393 268
394 if (code->is_compare_ic_stub()) { 269 if (code->is_compare_ic_stub()) {
395 int stub_minor_key = code->stub_info(); 270 int stub_minor_key = code->stub_info();
396 CompareIC::StubInfoToType( 271 CompareIC::StubInfoToType(
397 stub_minor_key, left_type, right_type, combined_type, map, isolate()); 272 stub_minor_key, left_type, right_type, combined_type, map, isolate());
398 } else if (code->is_compare_nil_ic_stub()) { 273 } else if (code->is_compare_nil_ic_stub()) {
399 CompareNilICStub stub(code->extended_extra_ic_state()); 274 CompareNilICStub stub(code->extended_extra_ic_state());
400 *combined_type = stub.GetType(isolate_, map); 275 *combined_type = stub.GetType(isolate_, map);
401 *left_type = *right_type = stub.GetInputType(isolate_, map); 276 *left_type = *right_type = stub.GetInputType(isolate_, map);
402 } 277 }
403 } 278 }
404 279
405 280
406 void TypeFeedbackOracle::BinaryType(TypeFeedbackId id, 281 void TypeFeedbackOracle::BinaryType(TypeFeedbackId id,
407 Handle<Type>* left, 282 Handle<Type>* left,
408 Handle<Type>* right, 283 Handle<Type>* right,
409 Handle<Type>* result, 284 Handle<Type>* result,
410 Maybe<int>* fixed_right_arg, 285 Maybe<int>* fixed_right_arg,
286 Handle<AllocationSite>* allocation_site,
411 Token::Value op) { 287 Token::Value op) {
412 Handle<Object> object = GetInfo(id); 288 Handle<Object> object = GetInfo(id);
413 if (!object->IsCode()) { 289 if (!object->IsCode()) {
414 // For some binary ops we don't have ICs, e.g. Token::COMMA, but for the 290 // For some binary ops we don't have ICs, e.g. Token::COMMA, but for the
415 // operations covered by the BinaryOpIC we should always have them. 291 // operations covered by the BinaryOpIC we should always have them.
416 ASSERT(op < BinaryOpIC::State::FIRST_TOKEN || 292 ASSERT(op < BinaryOpIC::State::FIRST_TOKEN ||
417 op > BinaryOpIC::State::LAST_TOKEN); 293 op > BinaryOpIC::State::LAST_TOKEN);
418 *left = *right = *result = handle(Type::None(), isolate_); 294 *left = *right = *result = handle(Type::None(), isolate_);
419 *fixed_right_arg = Maybe<int>(); 295 *fixed_right_arg = Maybe<int>();
296 *allocation_site = Handle<AllocationSite>::null();
420 return; 297 return;
421 } 298 }
422 Handle<Code> code = Handle<Code>::cast(object); 299 Handle<Code> code = Handle<Code>::cast(object);
423 ASSERT_EQ(Code::BINARY_OP_IC, code->kind()); 300 ASSERT_EQ(Code::BINARY_OP_IC, code->kind());
424 BinaryOpIC::State state(code->extended_extra_ic_state()); 301 BinaryOpIC::State state(code->extended_extra_ic_state());
425 ASSERT_EQ(op, state.op()); 302 ASSERT_EQ(op, state.op());
426 303
427 *left = state.GetLeftType(isolate()); 304 *left = state.GetLeftType(isolate());
428 *right = state.GetRightType(isolate()); 305 *right = state.GetRightType(isolate());
429 *result = state.GetResultType(isolate()); 306 *result = state.GetResultType(isolate());
430 *fixed_right_arg = state.fixed_right_arg(); 307 *fixed_right_arg = state.fixed_right_arg();
308
309 AllocationSite* first_allocation_site = code->FindFirstAllocationSite();
310 if (first_allocation_site != NULL) {
311 *allocation_site = handle(first_allocation_site);
312 } else {
313 *allocation_site = Handle<AllocationSite>::null();
314 }
431 } 315 }
432 316
433 317
434 Handle<Type> TypeFeedbackOracle::ClauseType(TypeFeedbackId id) {
435 Handle<Object> info = GetInfo(id);
436 Handle<Type> result(Type::None(), isolate_);
437 if (info->IsCode() && Handle<Code>::cast(info)->is_compare_ic_stub()) {
438 Handle<Code> code = Handle<Code>::cast(info);
439 CompareIC::State state = ICCompareStub::CompareState(code->stub_info());
440 result = CompareIC::StateToType(isolate_, state);
441 }
442 return result;
443 }
444
445
446 Handle<Type> TypeFeedbackOracle::CountType(TypeFeedbackId id) { 318 Handle<Type> TypeFeedbackOracle::CountType(TypeFeedbackId id) {
447 Handle<Object> object = GetInfo(id); 319 Handle<Object> object = GetInfo(id);
448 if (!object->IsCode()) return handle(Type::None(), isolate_); 320 if (!object->IsCode()) return handle(Type::None(), isolate_);
449 Handle<Code> code = Handle<Code>::cast(object); 321 Handle<Code> code = Handle<Code>::cast(object);
450 ASSERT_EQ(Code::BINARY_OP_IC, code->kind()); 322 ASSERT_EQ(Code::BINARY_OP_IC, code->kind());
451 BinaryOpIC::State state(code->extended_extra_ic_state()); 323 BinaryOpIC::State state(code->extended_extra_ic_state());
452 return state.GetLeftType(isolate()); 324 return state.GetLeftType(isolate());
453 } 325 }
454 326
455 327
456 void TypeFeedbackOracle::PropertyReceiverTypes( 328 void TypeFeedbackOracle::PropertyReceiverTypes(
457 TypeFeedbackId id, Handle<String> name, 329 TypeFeedbackId id, Handle<String> name,
458 SmallMapList* receiver_types, bool* is_prototype) { 330 SmallMapList* receiver_types, bool* is_prototype) {
459 receiver_types->Clear(); 331 receiver_types->Clear();
460 FunctionPrototypeStub proto_stub(Code::LOAD_IC); 332 FunctionPrototypeStub proto_stub(Code::LOAD_IC);
461 *is_prototype = LoadIsStub(id, &proto_stub); 333 *is_prototype = LoadIsStub(id, &proto_stub);
462 if (!*is_prototype) { 334 if (!*is_prototype) {
463 LoadReceiverTypes(id, name, receiver_types); 335 Code::Flags flags = Code::ComputeFlags(
336 Code::HANDLER, MONOMORPHIC, kNoExtraICState,
337 Code::NORMAL, Code::LOAD_IC);
338 CollectReceiverTypes(id, name, flags, receiver_types);
464 } 339 }
465 } 340 }
466 341
467 342
468 void TypeFeedbackOracle::KeyedPropertyReceiverTypes( 343 void TypeFeedbackOracle::KeyedPropertyReceiverTypes(
469 TypeFeedbackId id, SmallMapList* receiver_types, bool* is_string) { 344 TypeFeedbackId id, SmallMapList* receiver_types, bool* is_string) {
470 receiver_types->Clear(); 345 receiver_types->Clear();
471 *is_string = false; 346 *is_string = false;
472 if (LoadIsBuiltin(id, Builtins::kKeyedLoadIC_String)) { 347 if (LoadIsBuiltin(id, Builtins::kKeyedLoadIC_String)) {
473 *is_string = true; 348 *is_string = true;
474 } else if (LoadIsMonomorphicNormal(id)) { 349 } else {
475 receiver_types->Add(LoadMonomorphicReceiverType(id), zone()); 350 CollectReceiverTypes(id, receiver_types);
476 } else if (LoadIsPolymorphic(id)) {
477 receiver_types->Reserve(kMaxKeyedPolymorphism, zone());
478 CollectKeyedReceiverTypes(id, receiver_types);
479 } 351 }
480 } 352 }
481 353
482 354
483 void TypeFeedbackOracle::AssignmentReceiverTypes( 355 void TypeFeedbackOracle::AssignmentReceiverTypes(
484 TypeFeedbackId id, Handle<String> name, SmallMapList* receiver_types) { 356 TypeFeedbackId id, Handle<String> name, SmallMapList* receiver_types) {
485 receiver_types->Clear(); 357 receiver_types->Clear();
486 StoreReceiverTypes(id, name, receiver_types); 358 Code::Flags flags = Code::ComputeFlags(
359 Code::HANDLER, MONOMORPHIC, kNoExtraICState,
360 Code::NORMAL, Code::STORE_IC);
361 CollectReceiverTypes(id, name, flags, receiver_types);
487 } 362 }
488 363
489 364
490 void TypeFeedbackOracle::KeyedAssignmentReceiverTypes( 365 void TypeFeedbackOracle::KeyedAssignmentReceiverTypes(
491 TypeFeedbackId id, SmallMapList* receiver_types, 366 TypeFeedbackId id, SmallMapList* receiver_types,
492 KeyedAccessStoreMode* store_mode) { 367 KeyedAccessStoreMode* store_mode) {
493 receiver_types->Clear(); 368 receiver_types->Clear();
494 if (StoreIsMonomorphicNormal(id)) { 369 CollectReceiverTypes(id, receiver_types);
495 // Record receiver type for monomorphic keyed stores.
496 receiver_types->Add(StoreMonomorphicReceiverType(id), zone());
497 } else if (StoreIsKeyedPolymorphic(id)) {
498 receiver_types->Reserve(kMaxKeyedPolymorphism, zone());
499 CollectKeyedReceiverTypes(id, receiver_types);
500 }
501 *store_mode = GetStoreMode(id); 370 *store_mode = GetStoreMode(id);
502 } 371 }
503 372
504 373
505 void TypeFeedbackOracle::CountReceiverTypes( 374 void TypeFeedbackOracle::CountReceiverTypes(TypeFeedbackId id,
506 TypeFeedbackId id, SmallMapList* receiver_types) { 375 SmallMapList* receiver_types) {
507 receiver_types->Clear(); 376 receiver_types->Clear();
508 if (StoreIsMonomorphicNormal(id)) { 377 CollectReceiverTypes(id, receiver_types);
509 // Record receiver type for monomorphic keyed stores.
510 receiver_types->Add(StoreMonomorphicReceiverType(id), zone());
511 } else if (StoreIsKeyedPolymorphic(id)) {
512 receiver_types->Reserve(kMaxKeyedPolymorphism, zone());
513 CollectKeyedReceiverTypes(id, receiver_types);
514 } else {
515 CollectPolymorphicStoreReceiverTypes(id, receiver_types);
516 }
517 } 378 }
518 379
519 380
520 void TypeFeedbackOracle::CollectPolymorphicMaps(Handle<Code> code,
521 SmallMapList* types) {
522 MapHandleList maps;
523 code->FindAllMaps(&maps);
524 types->Reserve(maps.length(), zone());
525 for (int i = 0; i < maps.length(); i++) {
526 Handle<Map> map(maps.at(i));
527 if (!CanRetainOtherContext(*map, *native_context_)) {
528 types->AddMapIfMissing(map, zone());
529 }
530 }
531 }
532
533
534 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id, 381 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id,
535 Handle<String> name, 382 Handle<String> name,
536 Code::Flags flags, 383 Code::Flags flags,
537 SmallMapList* types) { 384 SmallMapList* types) {
538 Handle<Object> object = GetInfo(ast_id); 385 Handle<Object> object = GetInfo(ast_id);
539 if (object->IsUndefined() || object->IsSmi()) return; 386 if (object->IsUndefined() || object->IsSmi()) return;
540 387
541 if (object->IsMap()) { 388 ASSERT(object->IsCode());
542 types->AddMapIfMissing(Handle<Map>::cast(object), zone()); 389 Handle<Code> code(Handle<Code>::cast(object));
543 } else if (Handle<Code>::cast(object)->ic_state() == POLYMORPHIC || 390
544 Handle<Code>::cast(object)->ic_state() == MONOMORPHIC) { 391 if (FLAG_collect_megamorphic_maps_from_stub_cache &&
545 CollectPolymorphicMaps(Handle<Code>::cast(object), types); 392 code->ic_state() == MEGAMORPHIC) {
546 } else if (FLAG_collect_megamorphic_maps_from_stub_cache &&
547 Handle<Code>::cast(object)->ic_state() == MEGAMORPHIC) {
548 types->Reserve(4, zone()); 393 types->Reserve(4, zone());
549 ASSERT(object->IsCode()); 394 isolate_->stub_cache()->CollectMatchingMaps(
550 isolate_->stub_cache()->CollectMatchingMaps(types, 395 types, name, flags, native_context_, zone());
551 name, 396 } else {
552 flags, 397 CollectReceiverTypes(ast_id, types);
553 native_context_,
554 zone());
555 } 398 }
556 } 399 }
557 400
558 401
559 // Check if a map originates from a given native context. We use this 402 // Check if a map originates from a given native context. We use this
560 // information to filter out maps from different context to avoid 403 // information to filter out maps from different context to avoid
561 // retaining objects from different tabs in Chrome via optimized code. 404 // retaining objects from different tabs in Chrome via optimized code.
562 bool TypeFeedbackOracle::CanRetainOtherContext(Map* map, 405 bool TypeFeedbackOracle::CanRetainOtherContext(Map* map,
563 Context* native_context) { 406 Context* native_context) {
564 Object* constructor = NULL; 407 Object* constructor = NULL;
(...skipping 18 matching lines...) Expand all
583 } 426 }
584 427
585 428
586 bool TypeFeedbackOracle::CanRetainOtherContext(JSFunction* function, 429 bool TypeFeedbackOracle::CanRetainOtherContext(JSFunction* function,
587 Context* native_context) { 430 Context* native_context) {
588 return function->context()->global_object() != native_context->global_object() 431 return function->context()->global_object() != native_context->global_object()
589 && function->context()->global_object() != native_context->builtins(); 432 && function->context()->global_object() != native_context->builtins();
590 } 433 }
591 434
592 435
593 void TypeFeedbackOracle::CollectKeyedReceiverTypes(TypeFeedbackId ast_id, 436 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id,
594 SmallMapList* types) { 437 SmallMapList* types) {
595 Handle<Object> object = GetInfo(ast_id); 438 Handle<Object> object = GetInfo(ast_id);
596 if (!object->IsCode()) return; 439 if (!object->IsCode()) return;
597 Handle<Code> code = Handle<Code>::cast(object); 440 Handle<Code> code = Handle<Code>::cast(object);
598 if (code->kind() == Code::KEYED_LOAD_IC || 441 MapHandleList maps;
599 code->kind() == Code::KEYED_STORE_IC) { 442 if (code->ic_state() == MONOMORPHIC) {
600 CollectPolymorphicMaps(code, types); 443 Map* map = code->FindFirstMap();
444 if (map != NULL) maps.Add(handle(map));
445 } else if (code->ic_state() == POLYMORPHIC) {
446 code->FindAllMaps(&maps);
447 } else {
448 return;
449 }
450 types->Reserve(maps.length(), zone());
451 for (int i = 0; i < maps.length(); i++) {
452 Handle<Map> map(maps.at(i));
453 if (!CanRetainOtherContext(*map, *native_context_)) {
454 types->AddMapIfMissing(map, zone());
455 }
601 } 456 }
602 } 457 }
603 458
604
605 void TypeFeedbackOracle::CollectPolymorphicStoreReceiverTypes(
606 TypeFeedbackId ast_id,
607 SmallMapList* types) {
608 Handle<Object> object = GetInfo(ast_id);
609 if (!object->IsCode()) return;
610 Handle<Code> code = Handle<Code>::cast(object);
611 if (code->kind() == Code::STORE_IC && code->ic_state() == POLYMORPHIC) {
612 CollectPolymorphicMaps(code, types);
613 }
614 }
615
616 459
617 byte TypeFeedbackOracle::ToBooleanTypes(TypeFeedbackId id) { 460 byte TypeFeedbackOracle::ToBooleanTypes(TypeFeedbackId id) {
618 Handle<Object> object = GetInfo(id); 461 Handle<Object> object = GetInfo(id);
619 return object->IsCode() ? Handle<Code>::cast(object)->to_boolean_state() : 0; 462 return object->IsCode() ? Handle<Code>::cast(object)->to_boolean_state() : 0;
620 } 463 }
621 464
622 465
623 // Things are a bit tricky here: The iterator for the RelocInfos and the infos 466 // Things are a bit tricky here: The iterator for the RelocInfos and the infos
624 // themselves are not GC-safe, so we first get all infos, then we create the 467 // themselves are not GC-safe, so we first get all infos, then we create the
625 // dictionary (possibly triggering GC), and finally we relocate the collected 468 // dictionary (possibly triggering GC), and finally we relocate the collected
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 515
673 516
674 void TypeFeedbackOracle::ProcessRelocInfos(ZoneList<RelocInfo>* infos) { 517 void TypeFeedbackOracle::ProcessRelocInfos(ZoneList<RelocInfo>* infos) {
675 for (int i = 0; i < infos->length(); i++) { 518 for (int i = 0; i < infos->length(); i++) {
676 RelocInfo reloc_entry = (*infos)[i]; 519 RelocInfo reloc_entry = (*infos)[i];
677 Address target_address = reloc_entry.target_address(); 520 Address target_address = reloc_entry.target_address();
678 TypeFeedbackId ast_id = 521 TypeFeedbackId ast_id =
679 TypeFeedbackId(static_cast<unsigned>((*infos)[i].data())); 522 TypeFeedbackId(static_cast<unsigned>((*infos)[i].data()));
680 Code* target = Code::GetCodeFromTargetAddress(target_address); 523 Code* target = Code::GetCodeFromTargetAddress(target_address);
681 switch (target->kind()) { 524 switch (target->kind()) {
525 case Code::CALL_IC:
526 if (target->ic_state() == MONOMORPHIC &&
527 target->check_type() != RECEIVER_MAP_CHECK) {
528 SetInfo(ast_id, Smi::FromInt(target->check_type()));
529 break;
530 }
682 case Code::LOAD_IC: 531 case Code::LOAD_IC:
683 case Code::STORE_IC: 532 case Code::STORE_IC:
684 case Code::CALL_IC:
685 if (target->ic_state() == MONOMORPHIC) {
686 if (target->kind() == Code::CALL_IC &&
687 target->check_type() != RECEIVER_MAP_CHECK) {
688 SetInfo(ast_id, Smi::FromInt(target->check_type()));
689 } else {
690 Object* map = target->FindFirstMap();
691 if (map == NULL) {
692 SetInfo(ast_id, static_cast<Object*>(target));
693 } else if (!CanRetainOtherContext(Map::cast(map),
694 *native_context_)) {
695 Map* feedback = Map::cast(map)->CurrentMapForDeprecated();
696 if (feedback != NULL) SetInfo(ast_id, feedback);
697 }
698 }
699 } else {
700 SetInfo(ast_id, target);
701 }
702 break;
703
704 case Code::KEYED_CALL_IC: 533 case Code::KEYED_CALL_IC:
705 case Code::KEYED_LOAD_IC: 534 case Code::KEYED_LOAD_IC:
706 case Code::KEYED_STORE_IC: 535 case Code::KEYED_STORE_IC:
707 case Code::BINARY_OP_IC: 536 case Code::BINARY_OP_IC:
708 case Code::COMPARE_IC: 537 case Code::COMPARE_IC:
709 case Code::TO_BOOLEAN_IC: 538 case Code::TO_BOOLEAN_IC:
710 case Code::COMPARE_NIL_IC: 539 case Code::COMPARE_NIL_IC:
711 SetInfo(ast_id, target); 540 SetInfo(ast_id, target);
712 break; 541 break;
713 542
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 USE(maybe_result); 574 USE(maybe_result);
746 #ifdef DEBUG 575 #ifdef DEBUG
747 Object* result = NULL; 576 Object* result = NULL;
748 // Dictionary has been allocated with sufficient size for all elements. 577 // Dictionary has been allocated with sufficient size for all elements.
749 ASSERT(maybe_result->ToObject(&result)); 578 ASSERT(maybe_result->ToObject(&result));
750 ASSERT(*dictionary_ == result); 579 ASSERT(*dictionary_ == result);
751 #endif 580 #endif
752 } 581 }
753 582
754 583
755 Representation Representation::FromType(TypeInfo info) {
756 if (info.IsUninitialized()) return Representation::None();
757 if (info.IsSmi()) return Representation::Smi();
758 if (info.IsInteger32()) return Representation::Integer32();
759 if (info.IsDouble()) return Representation::Double();
760 if (info.IsNumber()) return Representation::Double();
761 return Representation::Tagged();
762 }
763
764
765 } } // namespace v8::internal 584 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/type-info.h ('k') | src/typing.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698