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

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

Issue 6880036: Merge revision 7664 (revert of 7644 and 7632) to trunk. (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 8 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/version.cc » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 62
63 63
64 TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code, 64 TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code,
65 Handle<Context> global_context) { 65 Handle<Context> global_context) {
66 global_context_ = global_context; 66 global_context_ = global_context;
67 PopulateMap(code); 67 PopulateMap(code);
68 ASSERT(reinterpret_cast<Address>(*dictionary_.location()) != kHandleZapValue); 68 ASSERT(reinterpret_cast<Address>(*dictionary_.location()) != kHandleZapValue);
69 } 69 }
70 70
71 71
72 Handle<Object> TypeFeedbackOracle::GetInfo(unsigned ast_id) { 72 Handle<Object> TypeFeedbackOracle::GetInfo(int pos) {
73 int entry = dictionary_->FindEntry(ast_id); 73 int entry = dictionary_->FindEntry(pos);
74 return entry != NumberDictionary::kNotFound 74 return entry != NumberDictionary::kNotFound
75 ? Handle<Object>(dictionary_->ValueAt(entry)) 75 ? Handle<Object>(dictionary_->ValueAt(entry))
76 : Isolate::Current()->factory()->undefined_value(); 76 : Isolate::Current()->factory()->undefined_value();
77 } 77 }
78 78
79 79
80 bool TypeFeedbackOracle::LoadIsMonomorphic(Property* expr) { 80 bool TypeFeedbackOracle::LoadIsMonomorphic(Property* expr) {
81 Handle<Object> map_or_code(GetInfo(expr->id())); 81 Handle<Object> map_or_code(GetInfo(expr->position()));
82 if (map_or_code->IsMap()) return true; 82 if (map_or_code->IsMap()) return true;
83 if (map_or_code->IsCode()) { 83 if (map_or_code->IsCode()) {
84 Handle<Code> code(Code::cast(*map_or_code)); 84 Handle<Code> code(Code::cast(*map_or_code));
85 return code->kind() == Code::KEYED_EXTERNAL_ARRAY_LOAD_IC && 85 return code->kind() == Code::KEYED_EXTERNAL_ARRAY_LOAD_IC &&
86 code->FindFirstMap() != NULL; 86 code->FindFirstMap() != NULL;
87 } 87 }
88 return false; 88 return false;
89 } 89 }
90 90
91 91
92 bool TypeFeedbackOracle::StoreIsMonomorphic(Expression* expr) { 92 bool TypeFeedbackOracle::StoreIsMonomorphic(Expression* expr) {
93 Handle<Object> map_or_code(GetInfo(expr->id())); 93 Handle<Object> map_or_code(GetInfo(expr->position()));
94 if (map_or_code->IsMap()) return true; 94 if (map_or_code->IsMap()) return true;
95 if (map_or_code->IsCode()) { 95 if (map_or_code->IsCode()) {
96 Handle<Code> code(Code::cast(*map_or_code)); 96 Handle<Code> code(Code::cast(*map_or_code));
97 return code->kind() == Code::KEYED_EXTERNAL_ARRAY_STORE_IC && 97 return code->kind() == Code::KEYED_EXTERNAL_ARRAY_STORE_IC &&
98 code->FindFirstMap() != NULL; 98 code->FindFirstMap() != NULL;
99 } 99 }
100 return false; 100 return false;
101 } 101 }
102 102
103 103
104 bool TypeFeedbackOracle::CallIsMonomorphic(Call* expr) { 104 bool TypeFeedbackOracle::CallIsMonomorphic(Call* expr) {
105 Handle<Object> value = GetInfo(expr->id()); 105 Handle<Object> value = GetInfo(expr->position());
106 return value->IsMap() || value->IsSmi(); 106 return value->IsMap() || value->IsSmi();
107 } 107 }
108 108
109 109
110 Handle<Map> TypeFeedbackOracle::LoadMonomorphicReceiverType(Property* expr) { 110 Handle<Map> TypeFeedbackOracle::LoadMonomorphicReceiverType(Property* expr) {
111 ASSERT(LoadIsMonomorphic(expr)); 111 ASSERT(LoadIsMonomorphic(expr));
112 Handle<Object> map_or_code( 112 Handle<Object> map_or_code(
113 Handle<HeapObject>::cast(GetInfo(expr->id()))); 113 Handle<HeapObject>::cast(GetInfo(expr->position())));
114 if (map_or_code->IsCode()) { 114 if (map_or_code->IsCode()) {
115 Handle<Code> code(Code::cast(*map_or_code)); 115 Handle<Code> code(Code::cast(*map_or_code));
116 return Handle<Map>(code->FindFirstMap()); 116 return Handle<Map>(code->FindFirstMap());
117 } 117 }
118 return Handle<Map>(Map::cast(*map_or_code)); 118 return Handle<Map>(Map::cast(*map_or_code));
119 } 119 }
120 120
121 121
122 Handle<Map> TypeFeedbackOracle::StoreMonomorphicReceiverType(Expression* expr) { 122 Handle<Map> TypeFeedbackOracle::StoreMonomorphicReceiverType(Expression* expr) {
123 ASSERT(StoreIsMonomorphic(expr)); 123 ASSERT(StoreIsMonomorphic(expr));
124 Handle<HeapObject> map_or_code( 124 Handle<HeapObject> map_or_code(
125 Handle<HeapObject>::cast(GetInfo(expr->id()))); 125 Handle<HeapObject>::cast(GetInfo(expr->position())));
126 if (map_or_code->IsCode()) { 126 if (map_or_code->IsCode()) {
127 Handle<Code> code(Code::cast(*map_or_code)); 127 Handle<Code> code(Code::cast(*map_or_code));
128 return Handle<Map>(code->FindFirstMap()); 128 return Handle<Map>(code->FindFirstMap());
129 } 129 }
130 return Handle<Map>(Map::cast(*map_or_code)); 130 return Handle<Map>(Map::cast(*map_or_code));
131 } 131 }
132 132
133 133
134 ZoneMapList* TypeFeedbackOracle::LoadReceiverTypes(Property* expr, 134 ZoneMapList* TypeFeedbackOracle::LoadReceiverTypes(Property* expr,
135 Handle<String> name) { 135 Handle<String> name) {
136 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL); 136 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL);
137 return CollectReceiverTypes(expr->id(), name, flags); 137 return CollectReceiverTypes(expr->position(), name, flags);
138 } 138 }
139 139
140 140
141 ZoneMapList* TypeFeedbackOracle::StoreReceiverTypes(Assignment* expr, 141 ZoneMapList* TypeFeedbackOracle::StoreReceiverTypes(Assignment* expr,
142 Handle<String> name) { 142 Handle<String> name) {
143 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, NORMAL); 143 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, NORMAL);
144 return CollectReceiverTypes(expr->id(), name, flags); 144 return CollectReceiverTypes(expr->position(), name, flags);
145 } 145 }
146 146
147 147
148 ZoneMapList* TypeFeedbackOracle::CallReceiverTypes(Call* expr, 148 ZoneMapList* TypeFeedbackOracle::CallReceiverTypes(Call* expr,
149 Handle<String> name) { 149 Handle<String> name) {
150 int arity = expr->arguments()->length(); 150 int arity = expr->arguments()->length();
151 // Note: these flags won't let us get maps from stubs with 151 // Note: these flags won't let us get maps from stubs with
152 // non-default extra ic state in the megamorphic case. In the more 152 // non-default extra ic state in the megamorphic case. In the more
153 // important monomorphic case the map is obtained directly, so it's 153 // important monomorphic case the map is obtained directly, so it's
154 // not a problem until we decide to emit more polymorphic code. 154 // not a problem until we decide to emit more polymorphic code.
155 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC, 155 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC,
156 NORMAL, 156 NORMAL,
157 Code::kNoExtraICState, 157 Code::kNoExtraICState,
158 OWN_MAP, 158 OWN_MAP,
159 NOT_IN_LOOP, 159 NOT_IN_LOOP,
160 arity); 160 arity);
161 return CollectReceiverTypes(expr->id(), name, flags); 161 return CollectReceiverTypes(expr->position(), name, flags);
162 } 162 }
163 163
164 164
165 CheckType TypeFeedbackOracle::GetCallCheckType(Call* expr) { 165 CheckType TypeFeedbackOracle::GetCallCheckType(Call* expr) {
166 Handle<Object> value = GetInfo(expr->id()); 166 Handle<Object> value = GetInfo(expr->position());
167 if (!value->IsSmi()) return RECEIVER_MAP_CHECK; 167 if (!value->IsSmi()) return RECEIVER_MAP_CHECK;
168 CheckType check = static_cast<CheckType>(Smi::cast(*value)->value()); 168 CheckType check = static_cast<CheckType>(Smi::cast(*value)->value());
169 ASSERT(check != RECEIVER_MAP_CHECK); 169 ASSERT(check != RECEIVER_MAP_CHECK);
170 return check; 170 return check;
171 } 171 }
172 172
173 ExternalArrayType TypeFeedbackOracle::GetKeyedLoadExternalArrayType( 173 ExternalArrayType TypeFeedbackOracle::GetKeyedLoadExternalArrayType(
174 Property* expr) { 174 Property* expr) {
175 Handle<Object> stub = GetInfo(expr->id()); 175 Handle<Object> stub = GetInfo(expr->position());
176 ASSERT(stub->IsCode()); 176 ASSERT(stub->IsCode());
177 return Code::cast(*stub)->external_array_type(); 177 return Code::cast(*stub)->external_array_type();
178 } 178 }
179 179
180 ExternalArrayType TypeFeedbackOracle::GetKeyedStoreExternalArrayType( 180 ExternalArrayType TypeFeedbackOracle::GetKeyedStoreExternalArrayType(
181 Expression* expr) { 181 Expression* expr) {
182 Handle<Object> stub = GetInfo(expr->id()); 182 Handle<Object> stub = GetInfo(expr->position());
183 ASSERT(stub->IsCode()); 183 ASSERT(stub->IsCode());
184 return Code::cast(*stub)->external_array_type(); 184 return Code::cast(*stub)->external_array_type();
185 } 185 }
186 186
187 Handle<JSObject> TypeFeedbackOracle::GetPrototypeForPrimitiveCheck( 187 Handle<JSObject> TypeFeedbackOracle::GetPrototypeForPrimitiveCheck(
188 CheckType check) { 188 CheckType check) {
189 JSFunction* function = NULL; 189 JSFunction* function = NULL;
190 switch (check) { 190 switch (check) {
191 case RECEIVER_MAP_CHECK: 191 case RECEIVER_MAP_CHECK:
192 UNREACHABLE(); 192 UNREACHABLE();
193 break; 193 break;
194 case STRING_CHECK: 194 case STRING_CHECK:
195 function = global_context_->string_function(); 195 function = global_context_->string_function();
196 break; 196 break;
197 case NUMBER_CHECK: 197 case NUMBER_CHECK:
198 function = global_context_->number_function(); 198 function = global_context_->number_function();
199 break; 199 break;
200 case BOOLEAN_CHECK: 200 case BOOLEAN_CHECK:
201 function = global_context_->boolean_function(); 201 function = global_context_->boolean_function();
202 break; 202 break;
203 } 203 }
204 ASSERT(function != NULL); 204 ASSERT(function != NULL);
205 return Handle<JSObject>(JSObject::cast(function->instance_prototype())); 205 return Handle<JSObject>(JSObject::cast(function->instance_prototype()));
206 } 206 }
207 207
208 208
209 bool TypeFeedbackOracle::LoadIsBuiltin(Property* expr, Builtins::Name id) { 209 bool TypeFeedbackOracle::LoadIsBuiltin(Property* expr, Builtins::Name id) {
210 return *GetInfo(expr->id()) == 210 return *GetInfo(expr->position()) ==
211 Isolate::Current()->builtins()->builtin(id); 211 Isolate::Current()->builtins()->builtin(id);
212 } 212 }
213 213
214 214
215 TypeInfo TypeFeedbackOracle::CompareType(CompareOperation* expr) { 215 TypeInfo TypeFeedbackOracle::CompareType(CompareOperation* expr) {
216 Handle<Object> object = GetInfo(expr->id()); 216 Handle<Object> object = GetInfo(expr->position());
217 TypeInfo unknown = TypeInfo::Unknown(); 217 TypeInfo unknown = TypeInfo::Unknown();
218 if (!object->IsCode()) return unknown; 218 if (!object->IsCode()) return unknown;
219 Handle<Code> code = Handle<Code>::cast(object); 219 Handle<Code> code = Handle<Code>::cast(object);
220 if (!code->is_compare_ic_stub()) return unknown; 220 if (!code->is_compare_ic_stub()) return unknown;
221 221
222 CompareIC::State state = static_cast<CompareIC::State>(code->compare_state()); 222 CompareIC::State state = static_cast<CompareIC::State>(code->compare_state());
223 switch (state) { 223 switch (state) {
224 case CompareIC::UNINITIALIZED: 224 case CompareIC::UNINITIALIZED:
225 // Uninitialized means never executed. 225 // Uninitialized means never executed.
226 // TODO(fschneider): Introduce a separate value for never-executed ICs. 226 // TODO(fschneider): Introduce a separate value for never-executed ICs.
227 return unknown; 227 return unknown;
228 case CompareIC::SMIS: 228 case CompareIC::SMIS:
229 return TypeInfo::Smi(); 229 return TypeInfo::Smi();
230 case CompareIC::HEAP_NUMBERS: 230 case CompareIC::HEAP_NUMBERS:
231 return TypeInfo::Number(); 231 return TypeInfo::Number();
232 case CompareIC::OBJECTS: 232 case CompareIC::OBJECTS:
233 // TODO(kasperl): We really need a type for JS objects here. 233 // TODO(kasperl): We really need a type for JS objects here.
234 return TypeInfo::NonPrimitive(); 234 return TypeInfo::NonPrimitive();
235 case CompareIC::GENERIC: 235 case CompareIC::GENERIC:
236 default: 236 default:
237 return unknown; 237 return unknown;
238 } 238 }
239 } 239 }
240 240
241 241
242 TypeInfo TypeFeedbackOracle::BinaryType(BinaryOperation* expr) { 242 TypeInfo TypeFeedbackOracle::BinaryType(BinaryOperation* expr) {
243 Handle<Object> object = GetInfo(expr->id()); 243 Handle<Object> object = GetInfo(expr->position());
244 TypeInfo unknown = TypeInfo::Unknown(); 244 TypeInfo unknown = TypeInfo::Unknown();
245 if (!object->IsCode()) return unknown; 245 if (!object->IsCode()) return unknown;
246 Handle<Code> code = Handle<Code>::cast(object); 246 Handle<Code> code = Handle<Code>::cast(object);
247 if (code->is_type_recording_binary_op_stub()) { 247 if (code->is_type_recording_binary_op_stub()) {
248 TRBinaryOpIC::TypeInfo type = static_cast<TRBinaryOpIC::TypeInfo>( 248 TRBinaryOpIC::TypeInfo type = static_cast<TRBinaryOpIC::TypeInfo>(
249 code->type_recording_binary_op_type()); 249 code->type_recording_binary_op_type());
250 TRBinaryOpIC::TypeInfo result_type = static_cast<TRBinaryOpIC::TypeInfo>( 250 TRBinaryOpIC::TypeInfo result_type = static_cast<TRBinaryOpIC::TypeInfo>(
251 code->type_recording_binary_op_result_type()); 251 code->type_recording_binary_op_result_type());
252 252
253 switch (type) { 253 switch (type) {
(...skipping 28 matching lines...) Expand all
282 return unknown; 282 return unknown;
283 default: 283 default:
284 return unknown; 284 return unknown;
285 } 285 }
286 } 286 }
287 return unknown; 287 return unknown;
288 } 288 }
289 289
290 290
291 TypeInfo TypeFeedbackOracle::SwitchType(CaseClause* clause) { 291 TypeInfo TypeFeedbackOracle::SwitchType(CaseClause* clause) {
292 Handle<Object> object = GetInfo(clause->label()->id()); 292 Handle<Object> object = GetInfo(clause->position());
293 TypeInfo unknown = TypeInfo::Unknown(); 293 TypeInfo unknown = TypeInfo::Unknown();
294 if (!object->IsCode()) return unknown; 294 if (!object->IsCode()) return unknown;
295 Handle<Code> code = Handle<Code>::cast(object); 295 Handle<Code> code = Handle<Code>::cast(object);
296 if (!code->is_compare_ic_stub()) return unknown; 296 if (!code->is_compare_ic_stub()) return unknown;
297 297
298 CompareIC::State state = static_cast<CompareIC::State>(code->compare_state()); 298 CompareIC::State state = static_cast<CompareIC::State>(code->compare_state());
299 switch (state) { 299 switch (state) {
300 case CompareIC::UNINITIALIZED: 300 case CompareIC::UNINITIALIZED:
301 // Uninitialized means never executed. 301 // Uninitialized means never executed.
302 // TODO(fschneider): Introduce a separate value for never-executed ICs. 302 // TODO(fschneider): Introduce a separate value for never-executed ICs.
303 return unknown; 303 return unknown;
304 case CompareIC::SMIS: 304 case CompareIC::SMIS:
305 return TypeInfo::Smi(); 305 return TypeInfo::Smi();
306 case CompareIC::HEAP_NUMBERS: 306 case CompareIC::HEAP_NUMBERS:
307 return TypeInfo::Number(); 307 return TypeInfo::Number();
308 case CompareIC::OBJECTS: 308 case CompareIC::OBJECTS:
309 // TODO(kasperl): We really need a type for JS objects here. 309 // TODO(kasperl): We really need a type for JS objects here.
310 return TypeInfo::NonPrimitive(); 310 return TypeInfo::NonPrimitive();
311 case CompareIC::GENERIC: 311 case CompareIC::GENERIC:
312 default: 312 default:
313 return unknown; 313 return unknown;
314 } 314 }
315 } 315 }
316 316
317 317
318 ZoneMapList* TypeFeedbackOracle::CollectReceiverTypes(unsigned ast_id, 318 ZoneMapList* TypeFeedbackOracle::CollectReceiverTypes(int position,
319 Handle<String> name, 319 Handle<String> name,
320 Code::Flags flags) { 320 Code::Flags flags) {
321 Isolate* isolate = Isolate::Current(); 321 Isolate* isolate = Isolate::Current();
322 Handle<Object> object = GetInfo(ast_id); 322 Handle<Object> object = GetInfo(position);
323 if (object->IsUndefined() || object->IsSmi()) return NULL; 323 if (object->IsUndefined() || object->IsSmi()) return NULL;
324 324
325 if (*object == isolate->builtins()->builtin(Builtins::kStoreIC_GlobalProxy)) { 325 if (*object == isolate->builtins()->builtin(Builtins::kStoreIC_GlobalProxy)) {
326 // TODO(fschneider): We could collect the maps and signal that 326 // TODO(fschneider): We could collect the maps and signal that
327 // we need a generic store (or load) here. 327 // we need a generic store (or load) here.
328 ASSERT(Handle<Code>::cast(object)->ic_state() == MEGAMORPHIC); 328 ASSERT(Handle<Code>::cast(object)->ic_state() == MEGAMORPHIC);
329 return NULL; 329 return NULL;
330 } else if (object->IsMap()) { 330 } else if (object->IsMap()) {
331 ZoneMapList* types = new ZoneMapList(1); 331 ZoneMapList* types = new ZoneMapList(1);
332 types->Add(Handle<Map>::cast(object)); 332 types->Add(Handle<Map>::cast(object));
333 return types; 333 return types;
334 } else if (Handle<Code>::cast(object)->ic_state() == MEGAMORPHIC) { 334 } else if (Handle<Code>::cast(object)->ic_state() == MEGAMORPHIC) {
335 ZoneMapList* types = new ZoneMapList(4); 335 ZoneMapList* types = new ZoneMapList(4);
336 ASSERT(object->IsCode()); 336 ASSERT(object->IsCode());
337 isolate->stub_cache()->CollectMatchingMaps(types, *name, flags); 337 isolate->stub_cache()->CollectMatchingMaps(types, *name, flags);
338 return types->length() > 0 ? types : NULL; 338 return types->length() > 0 ? types : NULL;
339 } else { 339 } else {
340 return NULL; 340 return NULL;
341 } 341 }
342 } 342 }
343 343
344 344
345 void TypeFeedbackOracle::SetInfo(unsigned ast_id, Object* target) { 345 void TypeFeedbackOracle::SetInfo(int position, Object* target) {
346 ASSERT(dictionary_->FindEntry(ast_id) == NumberDictionary::kNotFound); 346 MaybeObject* maybe_result = dictionary_->AtNumberPut(position, target);
347 MaybeObject* maybe_result = dictionary_->AtNumberPut(ast_id, target);
348 USE(maybe_result); 347 USE(maybe_result);
349 #ifdef DEBUG 348 #ifdef DEBUG
350 Object* result; 349 Object* result;
351 // Dictionary has been allocated with sufficient size for all elements. 350 // Dictionary has been allocated with sufficient size for all elements.
352 ASSERT(maybe_result->ToObject(&result)); 351 ASSERT(maybe_result->ToObject(&result));
353 ASSERT(*dictionary_ == result); 352 ASSERT(*dictionary_ == result);
354 #endif 353 #endif
355 } 354 }
356 355
357 356
358 void TypeFeedbackOracle::PopulateMap(Handle<Code> code) { 357 void TypeFeedbackOracle::PopulateMap(Handle<Code> code) {
359 Isolate* isolate = Isolate::Current(); 358 Isolate* isolate = Isolate::Current();
360 HandleScope scope(isolate); 359 HandleScope scope(isolate);
361 360
362 const int kInitialCapacity = 16; 361 const int kInitialCapacity = 16;
363 List<int> code_positions(kInitialCapacity); 362 List<int> code_positions(kInitialCapacity);
364 List<unsigned> ast_ids(kInitialCapacity); 363 List<int> source_positions(kInitialCapacity);
365 CollectIds(*code, &code_positions, &ast_ids); 364 CollectPositions(*code, &code_positions, &source_positions);
366 365
367 ASSERT(dictionary_.is_null()); // Only initialize once. 366 ASSERT(dictionary_.is_null()); // Only initialize once.
368 dictionary_ = isolate->factory()->NewNumberDictionary( 367 dictionary_ = isolate->factory()->NewNumberDictionary(
369 code_positions.length()); 368 code_positions.length());
370 369
371 const int length = code_positions.length(); 370 int length = code_positions.length();
372 ASSERT(ast_ids.length() == length); 371 ASSERT(source_positions.length() == length);
373 for (int i = 0; i < length; i++) { 372 for (int i = 0; i < length; i++) {
374 AssertNoAllocation no_allocation; 373 AssertNoAllocation no_allocation;
375 RelocInfo info(code->instruction_start() + code_positions[i], 374 RelocInfo info(code->instruction_start() + code_positions[i],
376 RelocInfo::CODE_TARGET, 0); 375 RelocInfo::CODE_TARGET, 0);
377 Code* target = Code::GetCodeFromTargetAddress(info.target_address()); 376 Code* target = Code::GetCodeFromTargetAddress(info.target_address());
378 unsigned id = ast_ids[i]; 377 int position = source_positions[i];
379 InlineCacheState state = target->ic_state(); 378 InlineCacheState state = target->ic_state();
380 Code::Kind kind = target->kind(); 379 Code::Kind kind = target->kind();
381 380
382 if (kind == Code::TYPE_RECORDING_BINARY_OP_IC || 381 if (kind == Code::TYPE_RECORDING_BINARY_OP_IC ||
383 kind == Code::COMPARE_IC) { 382 kind == Code::COMPARE_IC) {
384 SetInfo(id, target); 383 // TODO(kasperl): Avoid having multiple ICs with the same
384 // position by making sure that we have position information
385 // recorded for all binary ICs.
386 int entry = dictionary_->FindEntry(position);
387 if (entry == NumberDictionary::kNotFound) {
388 SetInfo(position, target);
389 }
385 } else if (state == MONOMORPHIC) { 390 } else if (state == MONOMORPHIC) {
386 if (kind == Code::KEYED_EXTERNAL_ARRAY_LOAD_IC || 391 if (kind == Code::KEYED_EXTERNAL_ARRAY_LOAD_IC ||
387 kind == Code::KEYED_EXTERNAL_ARRAY_STORE_IC) { 392 kind == Code::KEYED_EXTERNAL_ARRAY_STORE_IC) {
388 SetInfo(id, target); 393 SetInfo(position, target);
389 } else if (kind != Code::CALL_IC || 394 } else if (target->kind() != Code::CALL_IC ||
390 target->check_type() == RECEIVER_MAP_CHECK) { 395 target->check_type() == RECEIVER_MAP_CHECK) {
391 Map* map = target->FindFirstMap(); 396 Map* map = target->FindFirstMap();
392 if (map == NULL) { 397 if (map == NULL) {
393 SetInfo(id, target); 398 SetInfo(position, target);
394 } else { 399 } else {
395 SetInfo(id, map); 400 SetInfo(position, map);
396 } 401 }
397 } else { 402 } else {
398 ASSERT(target->kind() == Code::CALL_IC); 403 ASSERT(target->kind() == Code::CALL_IC);
399 CheckType check = target->check_type(); 404 CheckType check = target->check_type();
400 ASSERT(check != RECEIVER_MAP_CHECK); 405 ASSERT(check != RECEIVER_MAP_CHECK);
401 SetInfo(id, Smi::FromInt(check)); 406 SetInfo(position, Smi::FromInt(check));
402 } 407 }
403 } else if (state == MEGAMORPHIC) { 408 } else if (state == MEGAMORPHIC) {
404 SetInfo(id, target); 409 SetInfo(position, target);
405 } 410 }
406 } 411 }
407 // Allocate handle in the parent scope. 412 // Allocate handle in the parent scope.
408 dictionary_ = scope.CloseAndEscape(dictionary_); 413 dictionary_ = scope.CloseAndEscape(dictionary_);
409 } 414 }
410 415
411 416
412 void TypeFeedbackOracle::CollectIds(Code* code, 417 void TypeFeedbackOracle::CollectPositions(Code* code,
413 List<int>* code_positions, 418 List<int>* code_positions,
414 List<unsigned>* ast_ids) { 419 List<int>* source_positions) {
415 AssertNoAllocation no_allocation; 420 AssertNoAllocation no_allocation;
416 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID); 421 int position = 0;
422 // Because the ICs we use for global variables access in the full
423 // code generator do not have any meaningful positions, we avoid
424 // collecting those by filtering out contextual code targets.
425 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
426 RelocInfo::kPositionMask;
417 for (RelocIterator it(code, mask); !it.done(); it.next()) { 427 for (RelocIterator it(code, mask); !it.done(); it.next()) {
418 RelocInfo* info = it.rinfo(); 428 RelocInfo* info = it.rinfo();
419 ASSERT(RelocInfo::IsCodeTarget(info->rmode())); 429 RelocInfo::Mode mode = info->rmode();
420 Code* target = Code::GetCodeFromTargetAddress(info->target_address()); 430 if (RelocInfo::IsCodeTarget(mode)) {
421 if (target->is_inline_cache_stub()) { 431 Code* target = Code::GetCodeFromTargetAddress(info->target_address());
422 InlineCacheState state = target->ic_state(); 432 if (target->is_inline_cache_stub()) {
423 Code::Kind kind = target->kind(); 433 InlineCacheState state = target->ic_state();
424 if (kind == Code::TYPE_RECORDING_BINARY_OP_IC) { 434 Code::Kind kind = target->kind();
425 if (target->type_recording_binary_op_type() == 435 if (kind == Code::TYPE_RECORDING_BINARY_OP_IC) {
426 TRBinaryOpIC::GENERIC) { 436 if (target->type_recording_binary_op_type() ==
427 continue; 437 TRBinaryOpIC::GENERIC) {
438 continue;
439 }
440 } else if (kind == Code::COMPARE_IC) {
441 if (target->compare_state() == CompareIC::GENERIC) continue;
442 } else {
443 if (state != MONOMORPHIC && state != MEGAMORPHIC) continue;
428 } 444 }
429 } else if (kind == Code::COMPARE_IC) { 445 code_positions->Add(
430 if (target->compare_state() == CompareIC::GENERIC) continue; 446 static_cast<int>(info->pc() - code->instruction_start()));
431 } else { 447 source_positions->Add(position);
432 if (state != MONOMORPHIC && state != MEGAMORPHIC) continue;
433 } 448 }
434 code_positions->Add( 449 } else {
435 static_cast<int>(info->pc() - code->instruction_start())); 450 ASSERT(RelocInfo::IsPosition(mode));
436 ast_ids->Add(static_cast<unsigned>(info->data())); 451 position = static_cast<int>(info->data());
437 } 452 }
438 } 453 }
439 } 454 }
440 455
441 } } // namespace v8::internal 456 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/type-info.h ('k') | src/version.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698