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

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

Issue 143633007: A64: Synchronize with r18764. (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/types.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 26 matching lines...) Expand all
37 37
38 #include "ic-inl.h" 38 #include "ic-inl.h"
39 #include "objects-inl.h" 39 #include "objects-inl.h"
40 40
41 namespace v8 { 41 namespace v8 {
42 namespace internal { 42 namespace internal {
43 43
44 44
45 TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code, 45 TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code,
46 Handle<Context> native_context, 46 Handle<Context> native_context,
47 Isolate* isolate,
48 Zone* zone) 47 Zone* zone)
49 : native_context_(native_context), 48 : native_context_(native_context),
50 isolate_(isolate),
51 zone_(zone) { 49 zone_(zone) {
52 BuildDictionary(code); 50 BuildDictionary(code);
53 ASSERT(dictionary_->IsDictionary()); 51 ASSERT(dictionary_->IsDictionary());
54 } 52 }
55 53
56 54
57 static uint32_t IdToKey(TypeFeedbackId ast_id) { 55 static uint32_t IdToKey(TypeFeedbackId ast_id) {
58 return static_cast<uint32_t>(ast_id.ToInt()); 56 return static_cast<uint32_t>(ast_id.ToInt());
59 } 57 }
60 58
61 59
62 Handle<Object> TypeFeedbackOracle::GetInfo(TypeFeedbackId ast_id) { 60 Handle<Object> TypeFeedbackOracle::GetInfo(TypeFeedbackId ast_id) {
63 int entry = dictionary_->FindEntry(IdToKey(ast_id)); 61 int entry = dictionary_->FindEntry(IdToKey(ast_id));
64 if (entry != UnseededNumberDictionary::kNotFound) { 62 if (entry != UnseededNumberDictionary::kNotFound) {
65 Object* value = dictionary_->ValueAt(entry); 63 Object* value = dictionary_->ValueAt(entry);
66 if (value->IsCell()) { 64 if (value->IsCell()) {
67 Cell* cell = Cell::cast(value); 65 Cell* cell = Cell::cast(value);
68 return Handle<Object>(cell->value(), isolate_); 66 return Handle<Object>(cell->value(), isolate());
69 } else { 67 } else {
70 return Handle<Object>(value, isolate_); 68 return Handle<Object>(value, isolate());
71 } 69 }
72 } 70 }
73 return Handle<Object>::cast(isolate_->factory()->undefined_value()); 71 return Handle<Object>::cast(isolate()->factory()->undefined_value());
74 } 72 }
75 73
76 74
77 Handle<Cell> TypeFeedbackOracle::GetInfoCell(
78 TypeFeedbackId ast_id) {
79 int entry = dictionary_->FindEntry(IdToKey(ast_id));
80 if (entry != UnseededNumberDictionary::kNotFound) {
81 Cell* cell = Cell::cast(dictionary_->ValueAt(entry));
82 return Handle<Cell>(cell, isolate_);
83 }
84 return Handle<Cell>::null();
85 }
86
87
88 bool TypeFeedbackOracle::LoadIsUninitialized(TypeFeedbackId id) { 75 bool TypeFeedbackOracle::LoadIsUninitialized(TypeFeedbackId id) {
89 Handle<Object> maybe_code = GetInfo(id); 76 Handle<Object> maybe_code = GetInfo(id);
90 if (maybe_code->IsCode()) { 77 if (maybe_code->IsCode()) {
91 Handle<Code> code = Handle<Code>::cast(maybe_code); 78 Handle<Code> code = Handle<Code>::cast(maybe_code);
92 return code->is_inline_cache_stub() && code->ic_state() == UNINITIALIZED; 79 return code->is_inline_cache_stub() && code->ic_state() == UNINITIALIZED;
93 } 80 }
94 return false; 81 return false;
95 } 82 }
96 83
97 84
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 } 159 }
173 } 160 }
174 return STANDARD_STORE; 161 return STANDARD_STORE;
175 } 162 }
176 163
177 164
178 void TypeFeedbackOracle::CallReceiverTypes(TypeFeedbackId id, 165 void TypeFeedbackOracle::CallReceiverTypes(TypeFeedbackId id,
179 Handle<String> name, 166 Handle<String> name,
180 int arity, 167 int arity,
181 SmallMapList* types) { 168 SmallMapList* types) {
182 // Note: Currently we do not take string extra ic data into account
183 // here.
184 Code::Flags flags = Code::ComputeMonomorphicFlags( 169 Code::Flags flags = Code::ComputeMonomorphicFlags(
185 Code::CALL_IC, kNoExtraICState, OWN_MAP, Code::NORMAL, arity); 170 Code::CALL_IC, kNoExtraICState, OWN_MAP, Code::NORMAL, arity);
186 CollectReceiverTypes(id, name, flags, types); 171 CollectReceiverTypes(id, name, flags, types);
187 } 172 }
188 173
189 174
190 CheckType TypeFeedbackOracle::GetCallCheckType(TypeFeedbackId id) { 175 CheckType TypeFeedbackOracle::GetCallCheckType(TypeFeedbackId id) {
191 Handle<Object> value = GetInfo(id); 176 Handle<Object> value = GetInfo(id);
192 if (!value->IsSmi()) return RECEIVER_MAP_CHECK; 177 if (!value->IsSmi()) return RECEIVER_MAP_CHECK;
193 CheckType check = static_cast<CheckType>(Smi::cast(*value)->value()); 178 CheckType check = static_cast<CheckType>(Smi::cast(*value)->value());
194 ASSERT(check != RECEIVER_MAP_CHECK); 179 ASSERT(check != RECEIVER_MAP_CHECK);
195 return check; 180 return check;
196 } 181 }
197 182
198 183
199 Handle<JSFunction> TypeFeedbackOracle::GetCallTarget(TypeFeedbackId id) { 184 Handle<JSFunction> TypeFeedbackOracle::GetCallTarget(TypeFeedbackId id) {
200 Handle<Object> info = GetInfo(id); 185 Handle<Object> info = GetInfo(id);
201 if (info->IsAllocationSite()) { 186 if (info->IsAllocationSite()) {
202 return Handle<JSFunction>(isolate_->global_context()->array_function()); 187 return Handle<JSFunction>(isolate()->global_context()->array_function());
203 } else { 188 } else {
204 return Handle<JSFunction>::cast(info); 189 return Handle<JSFunction>::cast(info);
205 } 190 }
206 } 191 }
207 192
208 193
209 Handle<JSFunction> TypeFeedbackOracle::GetCallNewTarget(TypeFeedbackId id) { 194 Handle<JSFunction> TypeFeedbackOracle::GetCallNewTarget(TypeFeedbackId id) {
210 Handle<Object> info = GetInfo(id); 195 Handle<Object> info = GetInfo(id);
211 if (info->IsAllocationSite()) { 196 if (info->IsAllocationSite()) {
212 return Handle<JSFunction>(isolate_->global_context()->array_function()); 197 return Handle<JSFunction>(isolate()->global_context()->array_function());
213 } else { 198 } else {
214 return Handle<JSFunction>::cast(info); 199 return Handle<JSFunction>::cast(info);
215 } 200 }
216 } 201 }
217 202
218 203
219 Handle<Cell> TypeFeedbackOracle::GetCallNewAllocationInfoCell( 204 Handle<AllocationSite> TypeFeedbackOracle::GetCallNewAllocationSite(
220 TypeFeedbackId id) { 205 TypeFeedbackId id) {
221 return GetInfoCell(id); 206 Handle<Object> info = GetInfo(id);
207 if (info->IsAllocationSite()) {
208 return Handle<AllocationSite>::cast(info);
209 }
210 return Handle<AllocationSite>::null();
222 } 211 }
223 212
224 213
225 bool TypeFeedbackOracle::LoadIsBuiltin( 214 bool TypeFeedbackOracle::LoadIsBuiltin(
226 TypeFeedbackId id, Builtins::Name builtin) { 215 TypeFeedbackId id, Builtins::Name builtin) {
227 return *GetInfo(id) == isolate_->builtins()->builtin(builtin); 216 return *GetInfo(id) == isolate()->builtins()->builtin(builtin);
228 } 217 }
229 218
230 219
231 bool TypeFeedbackOracle::LoadIsStub(TypeFeedbackId id, ICStub* stub) { 220 bool TypeFeedbackOracle::LoadIsStub(TypeFeedbackId id, ICStub* stub) {
232 Handle<Object> object = GetInfo(id); 221 Handle<Object> object = GetInfo(id);
233 if (!object->IsCode()) return false; 222 if (!object->IsCode()) return false;
234 Handle<Code> code = Handle<Code>::cast(object); 223 Handle<Code> code = Handle<Code>::cast(object);
235 if (!code->is_load_stub()) return false; 224 if (!code->is_load_stub()) return false;
236 if (code->ic_state() != MONOMORPHIC) return false; 225 if (code->ic_state() != MONOMORPHIC) return false;
237 return stub->Describes(*code); 226 return stub->Describes(*code);
238 } 227 }
239 228
240 229
241 void TypeFeedbackOracle::CompareType(TypeFeedbackId id, 230 void TypeFeedbackOracle::CompareType(TypeFeedbackId id,
242 Handle<Type>* left_type, 231 Type** left_type,
243 Handle<Type>* right_type, 232 Type** right_type,
244 Handle<Type>* combined_type) { 233 Type** combined_type) {
245 Handle<Object> info = GetInfo(id); 234 Handle<Object> info = GetInfo(id);
246 if (!info->IsCode()) { 235 if (!info->IsCode()) {
247 // For some comparisons we don't have ICs, e.g. LiteralCompareTypeof. 236 // For some comparisons we don't have ICs, e.g. LiteralCompareTypeof.
248 *left_type = *right_type = *combined_type = Type::None(isolate_); 237 *left_type = *right_type = *combined_type = Type::None(zone());
249 return; 238 return;
250 } 239 }
251 Handle<Code> code = Handle<Code>::cast(info); 240 Handle<Code> code = Handle<Code>::cast(info);
252 241
253 Handle<Map> map; 242 Handle<Map> map;
254 Map* raw_map = code->FindFirstMap(); 243 Map* raw_map = code->FindFirstMap();
255 if (raw_map != NULL) { 244 if (raw_map != NULL) {
256 map = Map::CurrentMapForDeprecated(handle(raw_map)); 245 map = Map::CurrentMapForDeprecated(handle(raw_map));
257 if (!map.is_null() && CanRetainOtherContext(*map, *native_context_)) { 246 if (!map.is_null() && CanRetainOtherContext(*map, *native_context_)) {
258 map = Handle<Map>::null(); 247 map = Handle<Map>::null();
259 } 248 }
260 } 249 }
261 250
262 if (code->is_compare_ic_stub()) { 251 if (code->is_compare_ic_stub()) {
263 int stub_minor_key = code->stub_info(); 252 int stub_minor_key = code->stub_info();
264 CompareIC::StubInfoToType( 253 CompareIC::StubInfoToType(
265 stub_minor_key, left_type, right_type, combined_type, map, isolate()); 254 stub_minor_key, left_type, right_type, combined_type, map, zone());
266 } else if (code->is_compare_nil_ic_stub()) { 255 } else if (code->is_compare_nil_ic_stub()) {
267 CompareNilICStub stub(code->extended_extra_ic_state()); 256 CompareNilICStub stub(code->extended_extra_ic_state());
268 *combined_type = stub.GetType(isolate_, map); 257 *combined_type = stub.GetType(zone(), map);
269 *left_type = *right_type = stub.GetInputType(isolate_, map); 258 *left_type = *right_type = stub.GetInputType(zone(), map);
270 } 259 }
271 } 260 }
272 261
273 262
274 void TypeFeedbackOracle::BinaryType(TypeFeedbackId id, 263 void TypeFeedbackOracle::BinaryType(TypeFeedbackId id,
275 Handle<Type>* left, 264 Type** left,
276 Handle<Type>* right, 265 Type** right,
277 Handle<Type>* result, 266 Type** result,
278 Maybe<int>* fixed_right_arg, 267 Maybe<int>* fixed_right_arg,
279 Handle<AllocationSite>* allocation_site, 268 Handle<AllocationSite>* allocation_site,
280 Token::Value op) { 269 Token::Value op) {
281 Handle<Object> object = GetInfo(id); 270 Handle<Object> object = GetInfo(id);
282 if (!object->IsCode()) { 271 if (!object->IsCode()) {
283 // For some binary ops we don't have ICs, e.g. Token::COMMA, but for the 272 // For some binary ops we don't have ICs, e.g. Token::COMMA, but for the
284 // operations covered by the BinaryOpIC we should always have them. 273 // operations covered by the BinaryOpIC we should always have them.
285 ASSERT(op < BinaryOpIC::State::FIRST_TOKEN || 274 ASSERT(op < BinaryOpIC::State::FIRST_TOKEN ||
286 op > BinaryOpIC::State::LAST_TOKEN); 275 op > BinaryOpIC::State::LAST_TOKEN);
287 *left = *right = *result = Type::None(isolate_); 276 *left = *right = *result = Type::None(zone());
288 *fixed_right_arg = Maybe<int>(); 277 *fixed_right_arg = Maybe<int>();
289 *allocation_site = Handle<AllocationSite>::null(); 278 *allocation_site = Handle<AllocationSite>::null();
290 return; 279 return;
291 } 280 }
292 Handle<Code> code = Handle<Code>::cast(object); 281 Handle<Code> code = Handle<Code>::cast(object);
293 ASSERT_EQ(Code::BINARY_OP_IC, code->kind()); 282 ASSERT_EQ(Code::BINARY_OP_IC, code->kind());
294 BinaryOpIC::State state(code->extended_extra_ic_state()); 283 BinaryOpIC::State state(code->extended_extra_ic_state());
295 ASSERT_EQ(op, state.op()); 284 ASSERT_EQ(op, state.op());
296 285
297 *left = state.GetLeftType(isolate()); 286 *left = state.GetLeftType(zone());
298 *right = state.GetRightType(isolate()); 287 *right = state.GetRightType(zone());
299 *result = state.GetResultType(isolate()); 288 *result = state.GetResultType(zone());
300 *fixed_right_arg = state.fixed_right_arg(); 289 *fixed_right_arg = state.fixed_right_arg();
301 290
302 AllocationSite* first_allocation_site = code->FindFirstAllocationSite(); 291 AllocationSite* first_allocation_site = code->FindFirstAllocationSite();
303 if (first_allocation_site != NULL) { 292 if (first_allocation_site != NULL) {
304 *allocation_site = handle(first_allocation_site); 293 *allocation_site = handle(first_allocation_site);
305 } else { 294 } else {
306 *allocation_site = Handle<AllocationSite>::null(); 295 *allocation_site = Handle<AllocationSite>::null();
307 } 296 }
308 } 297 }
309 298
310 299
311 Handle<Type> TypeFeedbackOracle::CountType(TypeFeedbackId id) { 300 Type* TypeFeedbackOracle::CountType(TypeFeedbackId id) {
312 Handle<Object> object = GetInfo(id); 301 Handle<Object> object = GetInfo(id);
313 if (!object->IsCode()) return Type::None(isolate_); 302 if (!object->IsCode()) return Type::None(zone());
314 Handle<Code> code = Handle<Code>::cast(object); 303 Handle<Code> code = Handle<Code>::cast(object);
315 ASSERT_EQ(Code::BINARY_OP_IC, code->kind()); 304 ASSERT_EQ(Code::BINARY_OP_IC, code->kind());
316 BinaryOpIC::State state(code->extended_extra_ic_state()); 305 BinaryOpIC::State state(code->extended_extra_ic_state());
317 return state.GetLeftType(isolate()); 306 return state.GetLeftType(zone());
318 } 307 }
319 308
320 309
321 void TypeFeedbackOracle::PropertyReceiverTypes( 310 void TypeFeedbackOracle::PropertyReceiverTypes(
322 TypeFeedbackId id, Handle<String> name, 311 TypeFeedbackId id, Handle<String> name,
323 SmallMapList* receiver_types, bool* is_prototype) { 312 SmallMapList* receiver_types, bool* is_prototype) {
324 receiver_types->Clear(); 313 receiver_types->Clear();
325 FunctionPrototypeStub proto_stub(Code::LOAD_IC); 314 FunctionPrototypeStub proto_stub(Code::LOAD_IC);
326 *is_prototype = LoadIsStub(id, &proto_stub); 315 *is_prototype = LoadIsStub(id, &proto_stub);
327 if (!*is_prototype) { 316 if (!*is_prototype) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 SmallMapList* types) { 366 SmallMapList* types) {
378 Handle<Object> object = GetInfo(ast_id); 367 Handle<Object> object = GetInfo(ast_id);
379 if (object->IsUndefined() || object->IsSmi()) return; 368 if (object->IsUndefined() || object->IsSmi()) return;
380 369
381 ASSERT(object->IsCode()); 370 ASSERT(object->IsCode());
382 Handle<Code> code(Handle<Code>::cast(object)); 371 Handle<Code> code(Handle<Code>::cast(object));
383 372
384 if (FLAG_collect_megamorphic_maps_from_stub_cache && 373 if (FLAG_collect_megamorphic_maps_from_stub_cache &&
385 code->ic_state() == MEGAMORPHIC) { 374 code->ic_state() == MEGAMORPHIC) {
386 types->Reserve(4, zone()); 375 types->Reserve(4, zone());
387 isolate_->stub_cache()->CollectMatchingMaps( 376 isolate()->stub_cache()->CollectMatchingMaps(
388 types, name, flags, native_context_, zone()); 377 types, name, flags, native_context_, zone());
389 } else { 378 } else {
390 CollectReceiverTypes(ast_id, types); 379 CollectReceiverTypes(ast_id, types);
391 } 380 }
392 } 381 }
393 382
394 383
395 // Check if a map originates from a given native context. We use this 384 // Check if a map originates from a given native context. We use this
396 // information to filter out maps from different context to avoid 385 // information to filter out maps from different context to avoid
397 // retaining objects from different tabs in Chrome via optimized code. 386 // retaining objects from different tabs in Chrome via optimized code.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 } 445 }
457 446
458 447
459 // Things are a bit tricky here: The iterator for the RelocInfos and the infos 448 // Things are a bit tricky here: The iterator for the RelocInfos and the infos
460 // themselves are not GC-safe, so we first get all infos, then we create the 449 // themselves are not GC-safe, so we first get all infos, then we create the
461 // dictionary (possibly triggering GC), and finally we relocate the collected 450 // dictionary (possibly triggering GC), and finally we relocate the collected
462 // infos before we process them. 451 // infos before we process them.
463 void TypeFeedbackOracle::BuildDictionary(Handle<Code> code) { 452 void TypeFeedbackOracle::BuildDictionary(Handle<Code> code) {
464 DisallowHeapAllocation no_allocation; 453 DisallowHeapAllocation no_allocation;
465 ZoneList<RelocInfo> infos(16, zone()); 454 ZoneList<RelocInfo> infos(16, zone());
466 HandleScope scope(isolate_); 455 HandleScope scope(isolate());
467 GetRelocInfos(code, &infos); 456 GetRelocInfos(code, &infos);
468 CreateDictionary(code, &infos); 457 CreateDictionary(code, &infos);
469 ProcessRelocInfos(&infos); 458 ProcessRelocInfos(&infos);
470 ProcessTypeFeedbackCells(code); 459 ProcessTypeFeedbackCells(code);
471 // Allocate handle in the parent scope. 460 // Allocate handle in the parent scope.
472 dictionary_ = scope.CloseAndEscape(dictionary_); 461 dictionary_ = scope.CloseAndEscape(dictionary_);
473 } 462 }
474 463
475 464
476 void TypeFeedbackOracle::GetRelocInfos(Handle<Code> code, 465 void TypeFeedbackOracle::GetRelocInfos(Handle<Code> code,
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 #ifdef DEBUG 557 #ifdef DEBUG
569 Object* result = NULL; 558 Object* result = NULL;
570 // Dictionary has been allocated with sufficient size for all elements. 559 // Dictionary has been allocated with sufficient size for all elements.
571 ASSERT(maybe_result->ToObject(&result)); 560 ASSERT(maybe_result->ToObject(&result));
572 ASSERT(*dictionary_ == result); 561 ASSERT(*dictionary_ == result);
573 #endif 562 #endif
574 } 563 }
575 564
576 565
577 } } // namespace v8::internal 566 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/type-info.h ('k') | src/types.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698