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

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

Issue 6793016: Record AST ids in relocation info at spots where we collect dynamic type feedback. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: last change 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/x64/assembler-x64.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 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(int pos) { 72 Handle<Object> TypeFeedbackOracle::GetInfo(unsigned ast_id) {
73 int entry = dictionary_->FindEntry(pos); 73 int entry = dictionary_->FindEntry(ast_id);
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->position())); 81 Handle<Object> map_or_code(GetInfo(expr->id()));
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->position())); 93 Handle<Object> map_or_code(GetInfo(expr->id()));
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->position()); 105 Handle<Object> value = GetInfo(expr->id());
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->position()))); 113 Handle<HeapObject>::cast(GetInfo(expr->id())));
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->position()))); 125 Handle<HeapObject>::cast(GetInfo(expr->id())));
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->position(), name, flags); 137 return CollectReceiverTypes(expr->id(), 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->position(), name, flags); 144 return CollectReceiverTypes(expr->id(), 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->position(), name, flags); 161 return CollectReceiverTypes(expr->id(), 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->position()); 166 Handle<Object> value = GetInfo(expr->id());
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->position()); 175 Handle<Object> stub = GetInfo(expr->id());
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->position()); 182 Handle<Object> stub = GetInfo(expr->id());
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->position()) == 210 return *GetInfo(expr->id()) ==
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->position()); 216 Handle<Object> object = GetInfo(expr->id());
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->position()); 243 Handle<Object> object = GetInfo(expr->id());
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->position()); 292 Handle<Object> object = GetInfo(clause->label()->id());
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(int position, 318 ZoneMapList* TypeFeedbackOracle::CollectReceiverTypes(unsigned ast_id,
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(position); 322 Handle<Object> object = GetInfo(ast_id);
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(int position, Object* target) { 345 void TypeFeedbackOracle::SetInfo(unsigned ast_id, Object* target) {
346 MaybeObject* maybe_result = dictionary_->AtNumberPut(position, target); 346 ASSERT(dictionary_->FindEntry(ast_id) == NumberDictionary::kNotFound);
347 MaybeObject* maybe_result = dictionary_->AtNumberPut(ast_id, target);
347 USE(maybe_result); 348 USE(maybe_result);
348 #ifdef DEBUG 349 #ifdef DEBUG
349 Object* result; 350 Object* result;
350 // Dictionary has been allocated with sufficient size for all elements. 351 // Dictionary has been allocated with sufficient size for all elements.
351 ASSERT(maybe_result->ToObject(&result)); 352 ASSERT(maybe_result->ToObject(&result));
352 ASSERT(*dictionary_ == result); 353 ASSERT(*dictionary_ == result);
353 #endif 354 #endif
354 } 355 }
355 356
356 357
357 void TypeFeedbackOracle::PopulateMap(Handle<Code> code) { 358 void TypeFeedbackOracle::PopulateMap(Handle<Code> code) {
358 Isolate* isolate = Isolate::Current(); 359 Isolate* isolate = Isolate::Current();
359 HandleScope scope(isolate); 360 HandleScope scope(isolate);
360 361
361 const int kInitialCapacity = 16; 362 const int kInitialCapacity = 16;
362 List<int> code_positions(kInitialCapacity); 363 List<int> code_positions(kInitialCapacity);
363 List<int> source_positions(kInitialCapacity); 364 List<unsigned> ast_ids(kInitialCapacity);
364 CollectPositions(*code, &code_positions, &source_positions); 365 CollectIds(*code, &code_positions, &ast_ids);
365 366
366 ASSERT(dictionary_.is_null()); // Only initialize once. 367 ASSERT(dictionary_.is_null()); // Only initialize once.
367 dictionary_ = isolate->factory()->NewNumberDictionary( 368 dictionary_ = isolate->factory()->NewNumberDictionary(
368 code_positions.length()); 369 code_positions.length());
369 370
370 int length = code_positions.length(); 371 const int length = code_positions.length();
371 ASSERT(source_positions.length() == length); 372 ASSERT(ast_ids.length() == length);
372 for (int i = 0; i < length; i++) { 373 for (int i = 0; i < length; i++) {
373 AssertNoAllocation no_allocation; 374 AssertNoAllocation no_allocation;
374 RelocInfo info(code->instruction_start() + code_positions[i], 375 RelocInfo info(code->instruction_start() + code_positions[i],
375 RelocInfo::CODE_TARGET, 0); 376 RelocInfo::CODE_TARGET, 0);
376 Code* target = Code::GetCodeFromTargetAddress(info.target_address()); 377 Code* target = Code::GetCodeFromTargetAddress(info.target_address());
377 int position = source_positions[i]; 378 unsigned id = ast_ids[i];
378 InlineCacheState state = target->ic_state(); 379 InlineCacheState state = target->ic_state();
379 Code::Kind kind = target->kind(); 380 Code::Kind kind = target->kind();
380 381
381 if (kind == Code::TYPE_RECORDING_BINARY_OP_IC || 382 if (kind == Code::TYPE_RECORDING_BINARY_OP_IC ||
382 kind == Code::COMPARE_IC) { 383 kind == Code::COMPARE_IC) {
383 // TODO(kasperl): Avoid having multiple ICs with the same 384 SetInfo(id, target);
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 }
390 } else if (state == MONOMORPHIC) { 385 } else if (state == MONOMORPHIC) {
391 if (kind == Code::KEYED_EXTERNAL_ARRAY_LOAD_IC || 386 if (kind == Code::KEYED_EXTERNAL_ARRAY_LOAD_IC ||
392 kind == Code::KEYED_EXTERNAL_ARRAY_STORE_IC) { 387 kind == Code::KEYED_EXTERNAL_ARRAY_STORE_IC) {
393 SetInfo(position, target); 388 SetInfo(id, target);
394 } else if (target->kind() != Code::CALL_IC || 389 } else if (kind != Code::CALL_IC ||
395 target->check_type() == RECEIVER_MAP_CHECK) { 390 target->check_type() == RECEIVER_MAP_CHECK) {
396 Map* map = target->FindFirstMap(); 391 Map* map = target->FindFirstMap();
397 if (map == NULL) { 392 if (map == NULL) {
398 SetInfo(position, target); 393 SetInfo(id, target);
399 } else { 394 } else {
400 SetInfo(position, map); 395 SetInfo(id, map);
401 } 396 }
402 } else { 397 } else {
403 ASSERT(target->kind() == Code::CALL_IC); 398 ASSERT(target->kind() == Code::CALL_IC);
404 CheckType check = target->check_type(); 399 CheckType check = target->check_type();
405 ASSERT(check != RECEIVER_MAP_CHECK); 400 ASSERT(check != RECEIVER_MAP_CHECK);
406 SetInfo(position, Smi::FromInt(check)); 401 SetInfo(id, Smi::FromInt(check));
407 } 402 }
408 } else if (state == MEGAMORPHIC) { 403 } else if (state == MEGAMORPHIC) {
409 SetInfo(position, target); 404 SetInfo(id, target);
410 } 405 }
411 } 406 }
412 // Allocate handle in the parent scope. 407 // Allocate handle in the parent scope.
413 dictionary_ = scope.CloseAndEscape(dictionary_); 408 dictionary_ = scope.CloseAndEscape(dictionary_);
414 } 409 }
415 410
416 411
417 void TypeFeedbackOracle::CollectPositions(Code* code, 412 void TypeFeedbackOracle::CollectIds(Code* code,
418 List<int>* code_positions, 413 List<int>* code_positions,
419 List<int>* source_positions) { 414 List<unsigned>* ast_ids) {
420 AssertNoAllocation no_allocation; 415 AssertNoAllocation no_allocation;
421 int position = 0; 416 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID);
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;
427 for (RelocIterator it(code, mask); !it.done(); it.next()) { 417 for (RelocIterator it(code, mask); !it.done(); it.next()) {
428 RelocInfo* info = it.rinfo(); 418 RelocInfo* info = it.rinfo();
429 RelocInfo::Mode mode = info->rmode(); 419 ASSERT(RelocInfo::IsCodeTarget(info->rmode()));
430 if (RelocInfo::IsCodeTarget(mode)) { 420 Code* target = Code::GetCodeFromTargetAddress(info->target_address());
431 Code* target = Code::GetCodeFromTargetAddress(info->target_address()); 421 if (target->is_inline_cache_stub()) {
432 if (target->is_inline_cache_stub()) { 422 InlineCacheState state = target->ic_state();
433 InlineCacheState state = target->ic_state(); 423 Code::Kind kind = target->kind();
434 Code::Kind kind = target->kind(); 424 if (kind == Code::TYPE_RECORDING_BINARY_OP_IC) {
435 if (kind == Code::TYPE_RECORDING_BINARY_OP_IC) { 425 if (target->type_recording_binary_op_type() ==
436 if (target->type_recording_binary_op_type() == 426 TRBinaryOpIC::GENERIC) {
437 TRBinaryOpIC::GENERIC) { 427 continue;
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;
444 } 428 }
445 code_positions->Add( 429 } else if (kind == Code::COMPARE_IC) {
446 static_cast<int>(info->pc() - code->instruction_start())); 430 if (target->compare_state() == CompareIC::GENERIC) continue;
447 source_positions->Add(position); 431 } else {
432 if (state != MONOMORPHIC && state != MEGAMORPHIC) continue;
448 } 433 }
449 } else { 434 code_positions->Add(
450 ASSERT(RelocInfo::IsPosition(mode)); 435 static_cast<int>(info->pc() - code->instruction_start()));
451 position = static_cast<int>(info->data()); 436 ast_ids->Add(static_cast<unsigned>(info->data()));
452 } 437 }
453 } 438 }
454 } 439 }
455 440
456 } } // namespace v8::internal 441 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/type-info.h ('k') | src/x64/assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698