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

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

Issue 10831172: Introduced TypeFeedbackId and BailoutId types. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Incorporated review feedback. Created 8 years, 4 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/utils.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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 Isolate* isolate, 64 Isolate* isolate,
65 Zone* zone) { 65 Zone* zone) {
66 global_context_ = global_context; 66 global_context_ = global_context;
67 isolate_ = isolate; 67 isolate_ = isolate;
68 zone_ = zone; 68 zone_ = zone;
69 BuildDictionary(code); 69 BuildDictionary(code);
70 ASSERT(reinterpret_cast<Address>(*dictionary_.location()) != kHandleZapValue); 70 ASSERT(reinterpret_cast<Address>(*dictionary_.location()) != kHandleZapValue);
71 } 71 }
72 72
73 73
74 Handle<Object> TypeFeedbackOracle::GetInfo(unsigned ast_id) { 74 static uint32_t IdToKey(TypeFeedbackId ast_id) {
75 int entry = dictionary_->FindEntry(ast_id); 75 return static_cast<uint32_t>(ast_id.ToInt());
76 }
77
78
79 Handle<Object> TypeFeedbackOracle::GetInfo(TypeFeedbackId ast_id) {
80 int entry = dictionary_->FindEntry(IdToKey(ast_id));
76 return entry != UnseededNumberDictionary::kNotFound 81 return entry != UnseededNumberDictionary::kNotFound
77 ? Handle<Object>(dictionary_->ValueAt(entry)) 82 ? Handle<Object>(dictionary_->ValueAt(entry))
78 : Handle<Object>::cast(isolate_->factory()->undefined_value()); 83 : Handle<Object>::cast(isolate_->factory()->undefined_value());
79 } 84 }
80 85
81 86
82 bool TypeFeedbackOracle::LoadIsUninitialized(Property* expr) { 87 bool TypeFeedbackOracle::LoadIsUninitialized(Property* expr) {
83 Handle<Object> map_or_code = GetInfo(expr->id()); 88 Handle<Object> map_or_code = GetInfo(expr->PropertyFeedbackId());
84 if (map_or_code->IsMap()) return false; 89 if (map_or_code->IsMap()) return false;
85 if (map_or_code->IsCode()) { 90 if (map_or_code->IsCode()) {
86 Handle<Code> code = Handle<Code>::cast(map_or_code); 91 Handle<Code> code = Handle<Code>::cast(map_or_code);
87 return code->is_inline_cache_stub() && code->ic_state() == UNINITIALIZED; 92 return code->is_inline_cache_stub() && code->ic_state() == UNINITIALIZED;
88 } 93 }
89 return false; 94 return false;
90 } 95 }
91 96
92 97
93 bool TypeFeedbackOracle::LoadIsMonomorphicNormal(Property* expr) { 98 bool TypeFeedbackOracle::LoadIsMonomorphicNormal(Property* expr) {
94 Handle<Object> map_or_code = GetInfo(expr->id()); 99 Handle<Object> map_or_code = GetInfo(expr->PropertyFeedbackId());
95 if (map_or_code->IsMap()) return true; 100 if (map_or_code->IsMap()) return true;
96 if (map_or_code->IsCode()) { 101 if (map_or_code->IsCode()) {
97 Handle<Code> code = Handle<Code>::cast(map_or_code); 102 Handle<Code> code = Handle<Code>::cast(map_or_code);
98 return code->is_keyed_load_stub() && 103 return code->is_keyed_load_stub() &&
99 code->ic_state() == MONOMORPHIC && 104 code->ic_state() == MONOMORPHIC &&
100 Code::ExtractTypeFromFlags(code->flags()) == Code::NORMAL && 105 Code::ExtractTypeFromFlags(code->flags()) == Code::NORMAL &&
101 code->FindFirstMap() != NULL && 106 code->FindFirstMap() != NULL &&
102 !CanRetainOtherContext(code->FindFirstMap(), *global_context_); 107 !CanRetainOtherContext(code->FindFirstMap(), *global_context_);
103 } 108 }
104 return false; 109 return false;
105 } 110 }
106 111
107 112
108 bool TypeFeedbackOracle::LoadIsMegamorphicWithTypeInfo(Property* expr) { 113 bool TypeFeedbackOracle::LoadIsMegamorphicWithTypeInfo(Property* expr) {
109 Handle<Object> map_or_code = GetInfo(expr->id()); 114 Handle<Object> map_or_code = GetInfo(expr->PropertyFeedbackId());
110 if (map_or_code->IsCode()) { 115 if (map_or_code->IsCode()) {
111 Handle<Code> code = Handle<Code>::cast(map_or_code); 116 Handle<Code> code = Handle<Code>::cast(map_or_code);
112 Builtins* builtins = isolate_->builtins(); 117 Builtins* builtins = isolate_->builtins();
113 return code->is_keyed_load_stub() && 118 return code->is_keyed_load_stub() &&
114 *code != builtins->builtin(Builtins::kKeyedLoadIC_Generic) && 119 *code != builtins->builtin(Builtins::kKeyedLoadIC_Generic) &&
115 code->ic_state() == MEGAMORPHIC; 120 code->ic_state() == MEGAMORPHIC;
116 } 121 }
117 return false; 122 return false;
118 } 123 }
119 124
120 125
121 bool TypeFeedbackOracle::StoreIsMonomorphicNormal(Expression* expr) { 126 bool TypeFeedbackOracle::StoreIsMonomorphicNormal(TypeFeedbackId ast_id) {
122 Handle<Object> map_or_code = GetInfo(expr->id()); 127 Handle<Object> map_or_code = GetInfo(ast_id);
123 if (map_or_code->IsMap()) return true; 128 if (map_or_code->IsMap()) return true;
124 if (map_or_code->IsCode()) { 129 if (map_or_code->IsCode()) {
125 Handle<Code> code = Handle<Code>::cast(map_or_code); 130 Handle<Code> code = Handle<Code>::cast(map_or_code);
126 bool allow_growth = 131 bool allow_growth =
127 Code::GetKeyedAccessGrowMode(code->extra_ic_state()) == 132 Code::GetKeyedAccessGrowMode(code->extra_ic_state()) ==
128 ALLOW_JSARRAY_GROWTH; 133 ALLOW_JSARRAY_GROWTH;
129 return code->is_keyed_store_stub() && 134 return code->is_keyed_store_stub() &&
130 !allow_growth && 135 !allow_growth &&
131 code->ic_state() == MONOMORPHIC && 136 code->ic_state() == MONOMORPHIC &&
132 Code::ExtractTypeFromFlags(code->flags()) == Code::NORMAL && 137 Code::ExtractTypeFromFlags(code->flags()) == Code::NORMAL &&
133 code->FindFirstMap() != NULL && 138 code->FindFirstMap() != NULL &&
134 !CanRetainOtherContext(code->FindFirstMap(), *global_context_); 139 !CanRetainOtherContext(code->FindFirstMap(), *global_context_);
135 } 140 }
136 return false; 141 return false;
137 } 142 }
138 143
139 144
140 bool TypeFeedbackOracle::StoreIsMegamorphicWithTypeInfo(Expression* expr) { 145 bool TypeFeedbackOracle::StoreIsMegamorphicWithTypeInfo(TypeFeedbackId ast_id) {
141 Handle<Object> map_or_code = GetInfo(expr->id()); 146 Handle<Object> map_or_code = GetInfo(ast_id);
142 if (map_or_code->IsCode()) { 147 if (map_or_code->IsCode()) {
143 Handle<Code> code = Handle<Code>::cast(map_or_code); 148 Handle<Code> code = Handle<Code>::cast(map_or_code);
144 Builtins* builtins = isolate_->builtins(); 149 Builtins* builtins = isolate_->builtins();
145 bool allow_growth = 150 bool allow_growth =
146 Code::GetKeyedAccessGrowMode(code->extra_ic_state()) == 151 Code::GetKeyedAccessGrowMode(code->extra_ic_state()) ==
147 ALLOW_JSARRAY_GROWTH; 152 ALLOW_JSARRAY_GROWTH;
148 return code->is_keyed_store_stub() && 153 return code->is_keyed_store_stub() &&
149 !allow_growth && 154 !allow_growth &&
150 *code != builtins->builtin(Builtins::kKeyedStoreIC_Generic) && 155 *code != builtins->builtin(Builtins::kKeyedStoreIC_Generic) &&
151 *code != builtins->builtin(Builtins::kKeyedStoreIC_Generic_Strict) && 156 *code != builtins->builtin(Builtins::kKeyedStoreIC_Generic_Strict) &&
152 code->ic_state() == MEGAMORPHIC; 157 code->ic_state() == MEGAMORPHIC;
153 } 158 }
154 return false; 159 return false;
155 } 160 }
156 161
157 162
158 bool TypeFeedbackOracle::CallIsMonomorphic(Call* expr) { 163 bool TypeFeedbackOracle::CallIsMonomorphic(Call* expr) {
159 Handle<Object> value = GetInfo(expr->id()); 164 Handle<Object> value = GetInfo(expr->CallFeedbackId());
160 return value->IsMap() || value->IsSmi() || value->IsJSFunction(); 165 return value->IsMap() || value->IsSmi() || value->IsJSFunction();
161 } 166 }
162 167
163 168
164 bool TypeFeedbackOracle::CallNewIsMonomorphic(CallNew* expr) { 169 bool TypeFeedbackOracle::CallNewIsMonomorphic(CallNew* expr) {
165 Handle<Object> value = GetInfo(expr->id()); 170 Handle<Object> value = GetInfo(expr->CallNewFeedbackId());
166 return value->IsJSFunction(); 171 return value->IsJSFunction();
167 } 172 }
168 173
169 174
170 bool TypeFeedbackOracle::ObjectLiteralStoreIsMonomorphic( 175 bool TypeFeedbackOracle::ObjectLiteralStoreIsMonomorphic(
171 ObjectLiteral::Property* prop) { 176 ObjectLiteral::Property* prop) {
172 Handle<Object> map_or_code = GetInfo(prop->key()->id()); 177 Handle<Object> map_or_code = GetInfo(prop->key()->LiteralFeedbackId());
173 return map_or_code->IsMap(); 178 return map_or_code->IsMap();
174 } 179 }
175 180
176 181
177 bool TypeFeedbackOracle::IsForInFastCase(ForInStatement* stmt) { 182 bool TypeFeedbackOracle::IsForInFastCase(ForInStatement* stmt) {
178 Handle<Object> value = GetInfo(stmt->PrepareId()); 183 Handle<Object> value = GetInfo(stmt->ForInFeedbackId());
179 return value->IsSmi() && 184 return value->IsSmi() &&
180 Smi::cast(*value)->value() == TypeFeedbackCells::kForInFastCaseMarker; 185 Smi::cast(*value)->value() == TypeFeedbackCells::kForInFastCaseMarker;
181 } 186 }
182 187
183 188
184 Handle<Map> TypeFeedbackOracle::LoadMonomorphicReceiverType(Property* expr) { 189 Handle<Map> TypeFeedbackOracle::LoadMonomorphicReceiverType(Property* expr) {
185 ASSERT(LoadIsMonomorphicNormal(expr)); 190 ASSERT(LoadIsMonomorphicNormal(expr));
186 Handle<Object> map_or_code = GetInfo(expr->id()); 191 Handle<Object> map_or_code = GetInfo(expr->PropertyFeedbackId());
187 if (map_or_code->IsCode()) { 192 if (map_or_code->IsCode()) {
188 Handle<Code> code = Handle<Code>::cast(map_or_code); 193 Handle<Code> code = Handle<Code>::cast(map_or_code);
189 Map* first_map = code->FindFirstMap(); 194 Map* first_map = code->FindFirstMap();
190 ASSERT(first_map != NULL); 195 ASSERT(first_map != NULL);
191 return CanRetainOtherContext(first_map, *global_context_) 196 return CanRetainOtherContext(first_map, *global_context_)
192 ? Handle<Map>::null() 197 ? Handle<Map>::null()
193 : Handle<Map>(first_map); 198 : Handle<Map>(first_map);
194 } 199 }
195 return Handle<Map>::cast(map_or_code); 200 return Handle<Map>::cast(map_or_code);
196 } 201 }
197 202
198 203
199 Handle<Map> TypeFeedbackOracle::StoreMonomorphicReceiverType(Expression* expr) { 204 Handle<Map> TypeFeedbackOracle::StoreMonomorphicReceiverType(
200 ASSERT(StoreIsMonomorphicNormal(expr)); 205 TypeFeedbackId ast_id) {
201 Handle<Object> map_or_code = GetInfo(expr->id()); 206 ASSERT(StoreIsMonomorphicNormal(ast_id));
207 Handle<Object> map_or_code = GetInfo(ast_id);
202 if (map_or_code->IsCode()) { 208 if (map_or_code->IsCode()) {
203 Handle<Code> code = Handle<Code>::cast(map_or_code); 209 Handle<Code> code = Handle<Code>::cast(map_or_code);
204 Map* first_map = code->FindFirstMap(); 210 Map* first_map = code->FindFirstMap();
205 ASSERT(first_map != NULL); 211 ASSERT(first_map != NULL);
206 return CanRetainOtherContext(first_map, *global_context_) 212 return CanRetainOtherContext(first_map, *global_context_)
207 ? Handle<Map>::null() 213 ? Handle<Map>::null()
208 : Handle<Map>(first_map); 214 : Handle<Map>(first_map);
209 } 215 }
210 return Handle<Map>::cast(map_or_code); 216 return Handle<Map>::cast(map_or_code);
211 } 217 }
212 218
213 219
214 void TypeFeedbackOracle::LoadReceiverTypes(Property* expr, 220 void TypeFeedbackOracle::LoadReceiverTypes(Property* expr,
215 Handle<String> name, 221 Handle<String> name,
216 SmallMapList* types) { 222 SmallMapList* types) {
217 Code::Flags flags = 223 Code::Flags flags =
218 Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::NORMAL); 224 Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::NORMAL);
219 CollectReceiverTypes(expr->id(), name, flags, types); 225 CollectReceiverTypes(expr->PropertyFeedbackId(), name, flags, types);
220 } 226 }
221 227
222 228
223 void TypeFeedbackOracle::StoreReceiverTypes(Assignment* expr, 229 void TypeFeedbackOracle::StoreReceiverTypes(Assignment* expr,
224 Handle<String> name, 230 Handle<String> name,
225 SmallMapList* types) { 231 SmallMapList* types) {
226 Code::Flags flags = 232 Code::Flags flags =
227 Code::ComputeMonomorphicFlags(Code::STORE_IC, Code::NORMAL); 233 Code::ComputeMonomorphicFlags(Code::STORE_IC, Code::NORMAL);
228 CollectReceiverTypes(expr->id(), name, flags, types); 234 CollectReceiverTypes(expr->AssignmentFeedbackId(), name, flags, types);
229 } 235 }
230 236
231 237
232 void TypeFeedbackOracle::CallReceiverTypes(Call* expr, 238 void TypeFeedbackOracle::CallReceiverTypes(Call* expr,
233 Handle<String> name, 239 Handle<String> name,
234 CallKind call_kind, 240 CallKind call_kind,
235 SmallMapList* types) { 241 SmallMapList* types) {
236 int arity = expr->arguments()->length(); 242 int arity = expr->arguments()->length();
237 243
238 // Note: Currently we do not take string extra ic data into account 244 // Note: Currently we do not take string extra ic data into account
239 // here. 245 // here.
240 Code::ExtraICState extra_ic_state = 246 Code::ExtraICState extra_ic_state =
241 CallIC::Contextual::encode(call_kind == CALL_AS_FUNCTION); 247 CallIC::Contextual::encode(call_kind == CALL_AS_FUNCTION);
242 248
243 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC, 249 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC,
244 Code::NORMAL, 250 Code::NORMAL,
245 extra_ic_state, 251 extra_ic_state,
246 OWN_MAP, 252 OWN_MAP,
247 arity); 253 arity);
248 CollectReceiverTypes(expr->id(), name, flags, types); 254 CollectReceiverTypes(expr->CallFeedbackId(), name, flags, types);
249 } 255 }
250 256
251 257
252 CheckType TypeFeedbackOracle::GetCallCheckType(Call* expr) { 258 CheckType TypeFeedbackOracle::GetCallCheckType(Call* expr) {
253 Handle<Object> value = GetInfo(expr->id()); 259 Handle<Object> value = GetInfo(expr->CallFeedbackId());
254 if (!value->IsSmi()) return RECEIVER_MAP_CHECK; 260 if (!value->IsSmi()) return RECEIVER_MAP_CHECK;
255 CheckType check = static_cast<CheckType>(Smi::cast(*value)->value()); 261 CheckType check = static_cast<CheckType>(Smi::cast(*value)->value());
256 ASSERT(check != RECEIVER_MAP_CHECK); 262 ASSERT(check != RECEIVER_MAP_CHECK);
257 return check; 263 return check;
258 } 264 }
259 265
260 266
261 Handle<JSObject> TypeFeedbackOracle::GetPrototypeForPrimitiveCheck( 267 Handle<JSObject> TypeFeedbackOracle::GetPrototypeForPrimitiveCheck(
262 CheckType check) { 268 CheckType check) {
263 JSFunction* function = NULL; 269 JSFunction* function = NULL;
(...skipping 10 matching lines...) Expand all
274 case BOOLEAN_CHECK: 280 case BOOLEAN_CHECK:
275 function = global_context_->boolean_function(); 281 function = global_context_->boolean_function();
276 break; 282 break;
277 } 283 }
278 ASSERT(function != NULL); 284 ASSERT(function != NULL);
279 return Handle<JSObject>(JSObject::cast(function->instance_prototype())); 285 return Handle<JSObject>(JSObject::cast(function->instance_prototype()));
280 } 286 }
281 287
282 288
283 Handle<JSFunction> TypeFeedbackOracle::GetCallTarget(Call* expr) { 289 Handle<JSFunction> TypeFeedbackOracle::GetCallTarget(Call* expr) {
284 return Handle<JSFunction>::cast(GetInfo(expr->id())); 290 return Handle<JSFunction>::cast(GetInfo(expr->CallFeedbackId()));
285 } 291 }
286 292
287 293
288 Handle<JSFunction> TypeFeedbackOracle::GetCallNewTarget(CallNew* expr) { 294 Handle<JSFunction> TypeFeedbackOracle::GetCallNewTarget(CallNew* expr) {
289 return Handle<JSFunction>::cast(GetInfo(expr->id())); 295 return Handle<JSFunction>::cast(GetInfo(expr->CallNewFeedbackId()));
290 } 296 }
291 297
292 298
293 Handle<Map> TypeFeedbackOracle::GetObjectLiteralStoreMap( 299 Handle<Map> TypeFeedbackOracle::GetObjectLiteralStoreMap(
294 ObjectLiteral::Property* prop) { 300 ObjectLiteral::Property* prop) {
295 ASSERT(ObjectLiteralStoreIsMonomorphic(prop)); 301 ASSERT(ObjectLiteralStoreIsMonomorphic(prop));
296 return Handle<Map>::cast(GetInfo(prop->key()->id())); 302 return Handle<Map>::cast(GetInfo(prop->key()->LiteralFeedbackId()));
297 } 303 }
298 304
299 305
300 bool TypeFeedbackOracle::LoadIsBuiltin(Property* expr, Builtins::Name id) { 306 bool TypeFeedbackOracle::LoadIsBuiltin(Property* expr, Builtins::Name id) {
301 return *GetInfo(expr->id()) == 307 return *GetInfo(expr->PropertyFeedbackId()) ==
302 isolate_->builtins()->builtin(id); 308 isolate_->builtins()->builtin(id);
303 } 309 }
304 310
305 311
306 TypeInfo TypeFeedbackOracle::CompareType(CompareOperation* expr) { 312 TypeInfo TypeFeedbackOracle::CompareType(CompareOperation* expr) {
307 Handle<Object> object = GetInfo(expr->id()); 313 Handle<Object> object = GetInfo(expr->CompareOperationFeedbackId());
308 TypeInfo unknown = TypeInfo::Unknown(); 314 TypeInfo unknown = TypeInfo::Unknown();
309 if (!object->IsCode()) return unknown; 315 if (!object->IsCode()) return unknown;
310 Handle<Code> code = Handle<Code>::cast(object); 316 Handle<Code> code = Handle<Code>::cast(object);
311 if (!code->is_compare_ic_stub()) return unknown; 317 if (!code->is_compare_ic_stub()) return unknown;
312 318
313 CompareIC::State state = static_cast<CompareIC::State>(code->compare_state()); 319 CompareIC::State state = static_cast<CompareIC::State>(code->compare_state());
314 switch (state) { 320 switch (state) {
315 case CompareIC::UNINITIALIZED: 321 case CompareIC::UNINITIALIZED:
316 // Uninitialized means never executed. 322 // Uninitialized means never executed.
317 return TypeInfo::Uninitialized(); 323 return TypeInfo::Uninitialized();
318 case CompareIC::SMIS: 324 case CompareIC::SMIS:
319 return TypeInfo::Smi(); 325 return TypeInfo::Smi();
320 case CompareIC::HEAP_NUMBERS: 326 case CompareIC::HEAP_NUMBERS:
321 return TypeInfo::Number(); 327 return TypeInfo::Number();
322 case CompareIC::SYMBOLS: 328 case CompareIC::SYMBOLS:
323 case CompareIC::STRINGS: 329 case CompareIC::STRINGS:
324 return TypeInfo::String(); 330 return TypeInfo::String();
325 case CompareIC::OBJECTS: 331 case CompareIC::OBJECTS:
326 case CompareIC::KNOWN_OBJECTS: 332 case CompareIC::KNOWN_OBJECTS:
327 // TODO(kasperl): We really need a type for JS objects here. 333 // TODO(kasperl): We really need a type for JS objects here.
328 return TypeInfo::NonPrimitive(); 334 return TypeInfo::NonPrimitive();
329 case CompareIC::GENERIC: 335 case CompareIC::GENERIC:
330 default: 336 default:
331 return unknown; 337 return unknown;
332 } 338 }
333 } 339 }
334 340
335 341
336 bool TypeFeedbackOracle::IsSymbolCompare(CompareOperation* expr) { 342 bool TypeFeedbackOracle::IsSymbolCompare(CompareOperation* expr) {
337 Handle<Object> object = GetInfo(expr->id()); 343 Handle<Object> object = GetInfo(expr->CompareOperationFeedbackId());
338 if (!object->IsCode()) return false; 344 if (!object->IsCode()) return false;
339 Handle<Code> code = Handle<Code>::cast(object); 345 Handle<Code> code = Handle<Code>::cast(object);
340 if (!code->is_compare_ic_stub()) return false; 346 if (!code->is_compare_ic_stub()) return false;
341 CompareIC::State state = static_cast<CompareIC::State>(code->compare_state()); 347 CompareIC::State state = static_cast<CompareIC::State>(code->compare_state());
342 return state == CompareIC::SYMBOLS; 348 return state == CompareIC::SYMBOLS;
343 } 349 }
344 350
345 351
346 Handle<Map> TypeFeedbackOracle::GetCompareMap(CompareOperation* expr) { 352 Handle<Map> TypeFeedbackOracle::GetCompareMap(CompareOperation* expr) {
347 Handle<Object> object = GetInfo(expr->id()); 353 Handle<Object> object = GetInfo(expr->CompareOperationFeedbackId());
348 if (!object->IsCode()) return Handle<Map>::null(); 354 if (!object->IsCode()) return Handle<Map>::null();
349 Handle<Code> code = Handle<Code>::cast(object); 355 Handle<Code> code = Handle<Code>::cast(object);
350 if (!code->is_compare_ic_stub()) return Handle<Map>::null(); 356 if (!code->is_compare_ic_stub()) return Handle<Map>::null();
351 CompareIC::State state = static_cast<CompareIC::State>(code->compare_state()); 357 CompareIC::State state = static_cast<CompareIC::State>(code->compare_state());
352 if (state != CompareIC::KNOWN_OBJECTS) { 358 if (state != CompareIC::KNOWN_OBJECTS) {
353 return Handle<Map>::null(); 359 return Handle<Map>::null();
354 } 360 }
355 Map* first_map = code->FindFirstMap(); 361 Map* first_map = code->FindFirstMap();
356 ASSERT(first_map != NULL); 362 ASSERT(first_map != NULL);
357 return CanRetainOtherContext(first_map, *global_context_) 363 return CanRetainOtherContext(first_map, *global_context_)
358 ? Handle<Map>::null() 364 ? Handle<Map>::null()
359 : Handle<Map>(first_map); 365 : Handle<Map>(first_map);
360 } 366 }
361 367
362 368
363 TypeInfo TypeFeedbackOracle::UnaryType(UnaryOperation* expr) { 369 TypeInfo TypeFeedbackOracle::UnaryType(UnaryOperation* expr) {
364 Handle<Object> object = GetInfo(expr->id()); 370 Handle<Object> object = GetInfo(expr->UnaryOperationFeedbackId());
365 TypeInfo unknown = TypeInfo::Unknown(); 371 TypeInfo unknown = TypeInfo::Unknown();
366 if (!object->IsCode()) return unknown; 372 if (!object->IsCode()) return unknown;
367 Handle<Code> code = Handle<Code>::cast(object); 373 Handle<Code> code = Handle<Code>::cast(object);
368 ASSERT(code->is_unary_op_stub()); 374 ASSERT(code->is_unary_op_stub());
369 UnaryOpIC::TypeInfo type = static_cast<UnaryOpIC::TypeInfo>( 375 UnaryOpIC::TypeInfo type = static_cast<UnaryOpIC::TypeInfo>(
370 code->unary_op_type()); 376 code->unary_op_type());
371 switch (type) { 377 switch (type) {
372 case UnaryOpIC::SMI: 378 case UnaryOpIC::SMI:
373 return TypeInfo::Smi(); 379 return TypeInfo::Smi();
374 case UnaryOpIC::HEAP_NUMBER: 380 case UnaryOpIC::HEAP_NUMBER:
375 return TypeInfo::Double(); 381 return TypeInfo::Double();
376 default: 382 default:
377 return unknown; 383 return unknown;
378 } 384 }
379 } 385 }
380 386
381 387
382 TypeInfo TypeFeedbackOracle::BinaryType(BinaryOperation* expr) { 388 TypeInfo TypeFeedbackOracle::BinaryType(BinaryOperation* expr) {
383 Handle<Object> object = GetInfo(expr->id()); 389 Handle<Object> object = GetInfo(expr->BinaryOperationFeedbackId());
384 TypeInfo unknown = TypeInfo::Unknown(); 390 TypeInfo unknown = TypeInfo::Unknown();
385 if (!object->IsCode()) return unknown; 391 if (!object->IsCode()) return unknown;
386 Handle<Code> code = Handle<Code>::cast(object); 392 Handle<Code> code = Handle<Code>::cast(object);
387 if (code->is_binary_op_stub()) { 393 if (code->is_binary_op_stub()) {
388 BinaryOpIC::TypeInfo type = static_cast<BinaryOpIC::TypeInfo>( 394 BinaryOpIC::TypeInfo type = static_cast<BinaryOpIC::TypeInfo>(
389 code->binary_op_type()); 395 code->binary_op_type());
390 BinaryOpIC::TypeInfo result_type = static_cast<BinaryOpIC::TypeInfo>( 396 BinaryOpIC::TypeInfo result_type = static_cast<BinaryOpIC::TypeInfo>(
391 code->binary_op_result_type()); 397 code->binary_op_result_type());
392 398
393 switch (type) { 399 switch (type) {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 // TODO(kasperl): We really need a type for JS objects here. 463 // TODO(kasperl): We really need a type for JS objects here.
458 return TypeInfo::NonPrimitive(); 464 return TypeInfo::NonPrimitive();
459 case CompareIC::GENERIC: 465 case CompareIC::GENERIC:
460 default: 466 default:
461 return unknown; 467 return unknown;
462 } 468 }
463 } 469 }
464 470
465 471
466 TypeInfo TypeFeedbackOracle::IncrementType(CountOperation* expr) { 472 TypeInfo TypeFeedbackOracle::IncrementType(CountOperation* expr) {
467 Handle<Object> object = GetInfo(expr->CountId()); 473 Handle<Object> object = GetInfo(expr->CountBinOpFeedbackId());
468 TypeInfo unknown = TypeInfo::Unknown(); 474 TypeInfo unknown = TypeInfo::Unknown();
469 if (!object->IsCode()) return unknown; 475 if (!object->IsCode()) return unknown;
470 Handle<Code> code = Handle<Code>::cast(object); 476 Handle<Code> code = Handle<Code>::cast(object);
471 if (!code->is_binary_op_stub()) return unknown; 477 if (!code->is_binary_op_stub()) return unknown;
472 478
473 BinaryOpIC::TypeInfo type = static_cast<BinaryOpIC::TypeInfo>( 479 BinaryOpIC::TypeInfo type = static_cast<BinaryOpIC::TypeInfo>(
474 code->binary_op_type()); 480 code->binary_op_type());
475 switch (type) { 481 switch (type) {
476 case BinaryOpIC::UNINITIALIZED: 482 case BinaryOpIC::UNINITIALIZED:
477 case BinaryOpIC::SMI: 483 case BinaryOpIC::SMI:
478 return TypeInfo::Smi(); 484 return TypeInfo::Smi();
479 case BinaryOpIC::INT32: 485 case BinaryOpIC::INT32:
480 return TypeInfo::Integer32(); 486 return TypeInfo::Integer32();
481 case BinaryOpIC::HEAP_NUMBER: 487 case BinaryOpIC::HEAP_NUMBER:
482 return TypeInfo::Double(); 488 return TypeInfo::Double();
483 case BinaryOpIC::BOTH_STRING: 489 case BinaryOpIC::BOTH_STRING:
484 case BinaryOpIC::STRING: 490 case BinaryOpIC::STRING:
485 case BinaryOpIC::GENERIC: 491 case BinaryOpIC::GENERIC:
486 return unknown; 492 return unknown;
487 default: 493 default:
488 return unknown; 494 return unknown;
489 } 495 }
490 UNREACHABLE(); 496 UNREACHABLE();
491 return unknown; 497 return unknown;
492 } 498 }
493 499
494 500
495 void TypeFeedbackOracle::CollectReceiverTypes(unsigned ast_id, 501 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id,
496 Handle<String> name, 502 Handle<String> name,
497 Code::Flags flags, 503 Code::Flags flags,
498 SmallMapList* types) { 504 SmallMapList* types) {
499 Handle<Object> object = GetInfo(ast_id); 505 Handle<Object> object = GetInfo(ast_id);
500 if (object->IsUndefined() || object->IsSmi()) return; 506 if (object->IsUndefined() || object->IsSmi()) return;
501 507
502 if (*object == 508 if (*object ==
503 isolate_->builtins()->builtin(Builtins::kStoreIC_GlobalProxy)) { 509 isolate_->builtins()->builtin(Builtins::kStoreIC_GlobalProxy)) {
504 // TODO(fschneider): We could collect the maps and signal that 510 // TODO(fschneider): We could collect the maps and signal that
505 // we need a generic store (or load) here. 511 // we need a generic store (or load) here.
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 561
556 static void AddMapIfMissing(Handle<Map> map, SmallMapList* list, 562 static void AddMapIfMissing(Handle<Map> map, SmallMapList* list,
557 Zone* zone) { 563 Zone* zone) {
558 for (int i = 0; i < list->length(); ++i) { 564 for (int i = 0; i < list->length(); ++i) {
559 if (list->at(i).is_identical_to(map)) return; 565 if (list->at(i).is_identical_to(map)) return;
560 } 566 }
561 list->Add(map, zone); 567 list->Add(map, zone);
562 } 568 }
563 569
564 570
565 void TypeFeedbackOracle::CollectKeyedReceiverTypes(unsigned ast_id, 571 void TypeFeedbackOracle::CollectKeyedReceiverTypes(TypeFeedbackId ast_id,
566 SmallMapList* types) { 572 SmallMapList* types) {
567 Handle<Object> object = GetInfo(ast_id); 573 Handle<Object> object = GetInfo(ast_id);
568 if (!object->IsCode()) return; 574 if (!object->IsCode()) return;
569 Handle<Code> code = Handle<Code>::cast(object); 575 Handle<Code> code = Handle<Code>::cast(object);
570 if (code->kind() == Code::KEYED_LOAD_IC || 576 if (code->kind() == Code::KEYED_LOAD_IC ||
571 code->kind() == Code::KEYED_STORE_IC) { 577 code->kind() == Code::KEYED_STORE_IC) {
572 AssertNoAllocation no_allocation; 578 AssertNoAllocation no_allocation;
573 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); 579 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
574 for (RelocIterator it(*code, mask); !it.done(); it.next()) { 580 for (RelocIterator it(*code, mask); !it.done(); it.next()) {
575 RelocInfo* info = it.rinfo(); 581 RelocInfo* info = it.rinfo();
576 Object* object = info->target_object(); 582 Object* object = info->target_object();
577 if (object->IsMap()) { 583 if (object->IsMap()) {
578 Map* map = Map::cast(object); 584 Map* map = Map::cast(object);
579 if (!CanRetainOtherContext(map, *global_context_)) { 585 if (!CanRetainOtherContext(map, *global_context_)) {
580 AddMapIfMissing(Handle<Map>(map), types, zone()); 586 AddMapIfMissing(Handle<Map>(map), types, zone());
581 } 587 }
582 } 588 }
583 } 589 }
584 } 590 }
585 } 591 }
586 592
587 593
588 byte TypeFeedbackOracle::ToBooleanTypes(unsigned ast_id) { 594 byte TypeFeedbackOracle::ToBooleanTypes(TypeFeedbackId ast_id) {
589 Handle<Object> object = GetInfo(ast_id); 595 Handle<Object> object = GetInfo(ast_id);
590 return object->IsCode() ? Handle<Code>::cast(object)->to_boolean_state() : 0; 596 return object->IsCode() ? Handle<Code>::cast(object)->to_boolean_state() : 0;
591 } 597 }
592 598
593 599
594 // Things are a bit tricky here: The iterator for the RelocInfos and the infos 600 // Things are a bit tricky here: The iterator for the RelocInfos and the infos
595 // themselves are not GC-safe, so we first get all infos, then we create the 601 // themselves are not GC-safe, so we first get all infos, then we create the
596 // dictionary (possibly triggering GC), and finally we relocate the collected 602 // dictionary (possibly triggering GC), and finally we relocate the collected
597 // infos before we process them. 603 // infos before we process them.
598 void TypeFeedbackOracle::BuildDictionary(Handle<Code> code) { 604 void TypeFeedbackOracle::BuildDictionary(Handle<Code> code) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 RelocInfo* info = &(*infos)[i]; 645 RelocInfo* info = &(*infos)[i];
640 info->set_pc(new_start + (info->pc() - old_start)); 646 info->set_pc(new_start + (info->pc() - old_start));
641 } 647 }
642 } 648 }
643 649
644 650
645 void TypeFeedbackOracle::ProcessRelocInfos(ZoneList<RelocInfo>* infos) { 651 void TypeFeedbackOracle::ProcessRelocInfos(ZoneList<RelocInfo>* infos) {
646 for (int i = 0; i < infos->length(); i++) { 652 for (int i = 0; i < infos->length(); i++) {
647 RelocInfo reloc_entry = (*infos)[i]; 653 RelocInfo reloc_entry = (*infos)[i];
648 Address target_address = reloc_entry.target_address(); 654 Address target_address = reloc_entry.target_address();
649 unsigned ast_id = static_cast<unsigned>((*infos)[i].data()); 655 TypeFeedbackId ast_id =
656 TypeFeedbackId(static_cast<unsigned>((*infos)[i].data()));
650 Code* target = Code::GetCodeFromTargetAddress(target_address); 657 Code* target = Code::GetCodeFromTargetAddress(target_address);
651 switch (target->kind()) { 658 switch (target->kind()) {
652 case Code::LOAD_IC: 659 case Code::LOAD_IC:
653 case Code::STORE_IC: 660 case Code::STORE_IC:
654 case Code::CALL_IC: 661 case Code::CALL_IC:
655 case Code::KEYED_CALL_IC: 662 case Code::KEYED_CALL_IC:
656 if (target->ic_state() == MONOMORPHIC) { 663 if (target->ic_state() == MONOMORPHIC) {
657 if (target->kind() == Code::CALL_IC && 664 if (target->kind() == Code::CALL_IC &&
658 target->check_type() != RECEIVER_MAP_CHECK) { 665 target->check_type() != RECEIVER_MAP_CHECK) {
659 SetInfo(ast_id, Smi::FromInt(target->check_type())); 666 SetInfo(ast_id, Smi::FromInt(target->check_type()));
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 } 699 }
693 } 700 }
694 701
695 702
696 void TypeFeedbackOracle::ProcessTypeFeedbackCells(Handle<Code> code) { 703 void TypeFeedbackOracle::ProcessTypeFeedbackCells(Handle<Code> code) {
697 Object* raw_info = code->type_feedback_info(); 704 Object* raw_info = code->type_feedback_info();
698 if (!raw_info->IsTypeFeedbackInfo()) return; 705 if (!raw_info->IsTypeFeedbackInfo()) return;
699 Handle<TypeFeedbackCells> cache( 706 Handle<TypeFeedbackCells> cache(
700 TypeFeedbackInfo::cast(raw_info)->type_feedback_cells()); 707 TypeFeedbackInfo::cast(raw_info)->type_feedback_cells());
701 for (int i = 0; i < cache->CellCount(); i++) { 708 for (int i = 0; i < cache->CellCount(); i++) {
702 unsigned ast_id = cache->AstId(i)->value(); 709 TypeFeedbackId ast_id = cache->AstId(i);
703 Object* value = cache->Cell(i)->value(); 710 Object* value = cache->Cell(i)->value();
704 if (value->IsSmi() || 711 if (value->IsSmi() ||
705 (value->IsJSFunction() && 712 (value->IsJSFunction() &&
706 !CanRetainOtherContext(JSFunction::cast(value), 713 !CanRetainOtherContext(JSFunction::cast(value),
707 *global_context_))) { 714 *global_context_))) {
708 SetInfo(ast_id, value); 715 SetInfo(ast_id, value);
709 } 716 }
710 } 717 }
711 } 718 }
712 719
713 720
714 void TypeFeedbackOracle::SetInfo(unsigned ast_id, Object* target) { 721 void TypeFeedbackOracle::SetInfo(TypeFeedbackId ast_id, Object* target) {
715 ASSERT(dictionary_->FindEntry(ast_id) == UnseededNumberDictionary::kNotFound); 722 ASSERT(dictionary_->FindEntry(IdToKey(ast_id)) ==
716 MaybeObject* maybe_result = dictionary_->AtNumberPut(ast_id, target); 723 UnseededNumberDictionary::kNotFound);
724 MaybeObject* maybe_result = dictionary_->AtNumberPut(IdToKey(ast_id), target);
717 USE(maybe_result); 725 USE(maybe_result);
718 #ifdef DEBUG 726 #ifdef DEBUG
719 Object* result = NULL; 727 Object* result = NULL;
720 // Dictionary has been allocated with sufficient size for all elements. 728 // Dictionary has been allocated with sufficient size for all elements.
721 ASSERT(maybe_result->ToObject(&result)); 729 ASSERT(maybe_result->ToObject(&result));
722 ASSERT(*dictionary_ == result); 730 ASSERT(*dictionary_ == result);
723 #endif 731 #endif
724 } 732 }
725 733
726 } } // namespace v8::internal 734 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/type-info.h ('k') | src/utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698