blob: 1940601c4782dd157d8cb773c3de71aae7034fb2 [file] [log] [blame]
Ben Murdoch8b112d22011-06-08 16:22:53 +01001// Copyright 2011 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
Steve Block6ded16b2010-05-10 14:33:55 +010028#include "v8.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010029
30#include "ast.h"
31#include "compiler.h"
32#include "ic.h"
33#include "macro-assembler.h"
34#include "stub-cache.h"
Steve Block6ded16b2010-05-10 14:33:55 +010035#include "type-info.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010036
37#include "ic-inl.h"
Steve Block6ded16b2010-05-10 14:33:55 +010038#include "objects-inl.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000039
40namespace v8 {
41namespace internal {
42
Steve Block6ded16b2010-05-10 14:33:55 +010043
44TypeInfo TypeInfo::TypeFromValue(Handle<Object> value) {
45 TypeInfo info;
46 if (value->IsSmi()) {
47 info = TypeInfo::Smi();
48 } else if (value->IsHeapNumber()) {
49 info = TypeInfo::IsInt32Double(HeapNumber::cast(*value)->value())
50 ? TypeInfo::Integer32()
51 : TypeInfo::Double();
52 } else if (value->IsString()) {
53 info = TypeInfo::String();
54 } else {
55 info = TypeInfo::Unknown();
56 }
57 return info;
58}
59
Steve Blocka7e24c12009-10-30 11:49:00 +000060
Ben Murdochb8e0da22011-05-16 14:20:40 +010061STATIC_ASSERT(DEFAULT_STRING_STUB == Code::kNoExtraICState);
62
63
64TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code,
65 Handle<Context> global_context) {
66 global_context_ = global_context;
Steve Block44f0eee2011-05-26 01:26:41 +010067 PopulateMap(code);
68 ASSERT(reinterpret_cast<Address>(*dictionary_.location()) != kHandleZapValue);
Ben Murdochb0fe1622011-05-05 13:52:32 +010069}
70
71
Steve Block44f0eee2011-05-26 01:26:41 +010072Handle<Object> TypeFeedbackOracle::GetInfo(int pos) {
73 int entry = dictionary_->FindEntry(pos);
74 return entry != NumberDictionary::kNotFound
75 ? Handle<Object>(dictionary_->ValueAt(entry))
76 : Isolate::Current()->factory()->undefined_value();
Ben Murdochb0fe1622011-05-05 13:52:32 +010077}
78
79
80bool TypeFeedbackOracle::LoadIsMonomorphic(Property* expr) {
Steve Block44f0eee2011-05-26 01:26:41 +010081 Handle<Object> map_or_code(GetInfo(expr->position()));
82 if (map_or_code->IsMap()) return true;
83 if (map_or_code->IsCode()) {
84 Handle<Code> code(Code::cast(*map_or_code));
85 return code->kind() == Code::KEYED_EXTERNAL_ARRAY_LOAD_IC &&
86 code->FindFirstMap() != NULL;
87 }
88 return false;
Ben Murdochb0fe1622011-05-05 13:52:32 +010089}
90
91
Ben Murdoch8b112d22011-06-08 16:22:53 +010092bool TypeFeedbackOracle::StoreIsMonomorphic(Expression* expr) {
Steve Block44f0eee2011-05-26 01:26:41 +010093 Handle<Object> map_or_code(GetInfo(expr->position()));
94 if (map_or_code->IsMap()) return true;
95 if (map_or_code->IsCode()) {
96 Handle<Code> code(Code::cast(*map_or_code));
97 return code->kind() == Code::KEYED_EXTERNAL_ARRAY_STORE_IC &&
98 code->FindFirstMap() != NULL;
99 }
100 return false;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100101}
102
103
104bool TypeFeedbackOracle::CallIsMonomorphic(Call* expr) {
Steve Block44f0eee2011-05-26 01:26:41 +0100105 Handle<Object> value = GetInfo(expr->position());
Ben Murdochb8e0da22011-05-16 14:20:40 +0100106 return value->IsMap() || value->IsSmi();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100107}
108
109
110Handle<Map> TypeFeedbackOracle::LoadMonomorphicReceiverType(Property* expr) {
111 ASSERT(LoadIsMonomorphic(expr));
Steve Block44f0eee2011-05-26 01:26:41 +0100112 Handle<Object> map_or_code(
113 Handle<HeapObject>::cast(GetInfo(expr->position())));
114 if (map_or_code->IsCode()) {
115 Handle<Code> code(Code::cast(*map_or_code));
116 return Handle<Map>(code->FindFirstMap());
117 }
118 return Handle<Map>(Map::cast(*map_or_code));
Ben Murdochb0fe1622011-05-05 13:52:32 +0100119}
120
121
Ben Murdoch8b112d22011-06-08 16:22:53 +0100122Handle<Map> TypeFeedbackOracle::StoreMonomorphicReceiverType(Expression* expr) {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100123 ASSERT(StoreIsMonomorphic(expr));
Steve Block44f0eee2011-05-26 01:26:41 +0100124 Handle<HeapObject> map_or_code(
125 Handle<HeapObject>::cast(GetInfo(expr->position())));
126 if (map_or_code->IsCode()) {
127 Handle<Code> code(Code::cast(*map_or_code));
128 return Handle<Map>(code->FindFirstMap());
129 }
130 return Handle<Map>(Map::cast(*map_or_code));
Ben Murdochb0fe1622011-05-05 13:52:32 +0100131}
132
133
Ben Murdochb0fe1622011-05-05 13:52:32 +0100134ZoneMapList* TypeFeedbackOracle::LoadReceiverTypes(Property* expr,
135 Handle<String> name) {
136 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL);
137 return CollectReceiverTypes(expr->position(), name, flags);
138}
139
140
141ZoneMapList* TypeFeedbackOracle::StoreReceiverTypes(Assignment* expr,
142 Handle<String> name) {
143 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, NORMAL);
144 return CollectReceiverTypes(expr->position(), name, flags);
145}
146
147
148ZoneMapList* TypeFeedbackOracle::CallReceiverTypes(Call* expr,
149 Handle<String> name) {
150 int arity = expr->arguments()->length();
Ben Murdochb8e0da22011-05-16 14:20:40 +0100151 // 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
153 // important monomorphic case the map is obtained directly, so it's
154 // not a problem until we decide to emit more polymorphic code.
155 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC,
156 NORMAL,
157 Code::kNoExtraICState,
158 OWN_MAP,
159 NOT_IN_LOOP,
160 arity);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100161 return CollectReceiverTypes(expr->position(), name, flags);
162}
163
164
Ben Murdochb8e0da22011-05-16 14:20:40 +0100165CheckType TypeFeedbackOracle::GetCallCheckType(Call* expr) {
Steve Block44f0eee2011-05-26 01:26:41 +0100166 Handle<Object> value = GetInfo(expr->position());
Ben Murdochb8e0da22011-05-16 14:20:40 +0100167 if (!value->IsSmi()) return RECEIVER_MAP_CHECK;
168 CheckType check = static_cast<CheckType>(Smi::cast(*value)->value());
169 ASSERT(check != RECEIVER_MAP_CHECK);
170 return check;
171}
172
Steve Block44f0eee2011-05-26 01:26:41 +0100173ExternalArrayType TypeFeedbackOracle::GetKeyedLoadExternalArrayType(
174 Property* expr) {
175 Handle<Object> stub = GetInfo(expr->position());
176 ASSERT(stub->IsCode());
177 return Code::cast(*stub)->external_array_type();
178}
179
180ExternalArrayType TypeFeedbackOracle::GetKeyedStoreExternalArrayType(
Ben Murdoch8b112d22011-06-08 16:22:53 +0100181 Expression* expr) {
Steve Block44f0eee2011-05-26 01:26:41 +0100182 Handle<Object> stub = GetInfo(expr->position());
183 ASSERT(stub->IsCode());
184 return Code::cast(*stub)->external_array_type();
185}
Ben Murdochb8e0da22011-05-16 14:20:40 +0100186
187Handle<JSObject> TypeFeedbackOracle::GetPrototypeForPrimitiveCheck(
188 CheckType check) {
189 JSFunction* function = NULL;
190 switch (check) {
191 case RECEIVER_MAP_CHECK:
192 UNREACHABLE();
193 break;
194 case STRING_CHECK:
195 function = global_context_->string_function();
196 break;
197 case NUMBER_CHECK:
198 function = global_context_->number_function();
199 break;
200 case BOOLEAN_CHECK:
201 function = global_context_->boolean_function();
202 break;
203 }
204 ASSERT(function != NULL);
205 return Handle<JSObject>(JSObject::cast(function->instance_prototype()));
206}
207
208
Ben Murdochb0fe1622011-05-05 13:52:32 +0100209bool TypeFeedbackOracle::LoadIsBuiltin(Property* expr, Builtins::Name id) {
Steve Block44f0eee2011-05-26 01:26:41 +0100210 return *GetInfo(expr->position()) ==
211 Isolate::Current()->builtins()->builtin(id);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100212}
213
214
Steve Block1e0659c2011-05-24 12:43:12 +0100215TypeInfo TypeFeedbackOracle::CompareType(CompareOperation* expr) {
Steve Block44f0eee2011-05-26 01:26:41 +0100216 Handle<Object> object = GetInfo(expr->position());
Ben Murdochb0fe1622011-05-05 13:52:32 +0100217 TypeInfo unknown = TypeInfo::Unknown();
218 if (!object->IsCode()) return unknown;
219 Handle<Code> code = Handle<Code>::cast(object);
220 if (!code->is_compare_ic_stub()) return unknown;
221
222 CompareIC::State state = static_cast<CompareIC::State>(code->compare_state());
223 switch (state) {
224 case CompareIC::UNINITIALIZED:
225 // Uninitialized means never executed.
226 // TODO(fschneider): Introduce a separate value for never-executed ICs.
227 return unknown;
228 case CompareIC::SMIS:
229 return TypeInfo::Smi();
230 case CompareIC::HEAP_NUMBERS:
231 return TypeInfo::Number();
232 case CompareIC::OBJECTS:
233 // TODO(kasperl): We really need a type for JS objects here.
234 return TypeInfo::NonPrimitive();
235 case CompareIC::GENERIC:
236 default:
237 return unknown;
238 }
239}
240
241
Steve Block1e0659c2011-05-24 12:43:12 +0100242TypeInfo TypeFeedbackOracle::BinaryType(BinaryOperation* expr) {
Steve Block44f0eee2011-05-26 01:26:41 +0100243 Handle<Object> object = GetInfo(expr->position());
Ben Murdochb0fe1622011-05-05 13:52:32 +0100244 TypeInfo unknown = TypeInfo::Unknown();
245 if (!object->IsCode()) return unknown;
246 Handle<Code> code = Handle<Code>::cast(object);
Ben Murdoch8b112d22011-06-08 16:22:53 +0100247 if (code->is_type_recording_binary_op_stub()) {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100248 TRBinaryOpIC::TypeInfo type = static_cast<TRBinaryOpIC::TypeInfo>(
249 code->type_recording_binary_op_type());
250 TRBinaryOpIC::TypeInfo result_type = static_cast<TRBinaryOpIC::TypeInfo>(
251 code->type_recording_binary_op_result_type());
252
253 switch (type) {
254 case TRBinaryOpIC::UNINITIALIZED:
255 // Uninitialized means never executed.
256 // TODO(fschneider): Introduce a separate value for never-executed ICs
257 return unknown;
258 case TRBinaryOpIC::SMI:
259 switch (result_type) {
260 case TRBinaryOpIC::UNINITIALIZED:
261 case TRBinaryOpIC::SMI:
262 return TypeInfo::Smi();
263 case TRBinaryOpIC::INT32:
264 return TypeInfo::Integer32();
265 case TRBinaryOpIC::HEAP_NUMBER:
266 return TypeInfo::Double();
267 default:
268 return unknown;
269 }
270 case TRBinaryOpIC::INT32:
271 if (expr->op() == Token::DIV ||
272 result_type == TRBinaryOpIC::HEAP_NUMBER) {
273 return TypeInfo::Double();
274 }
275 return TypeInfo::Integer32();
276 case TRBinaryOpIC::HEAP_NUMBER:
277 return TypeInfo::Double();
Ben Murdoch8b112d22011-06-08 16:22:53 +0100278 case TRBinaryOpIC::BOTH_STRING:
279 return TypeInfo::String();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100280 case TRBinaryOpIC::STRING:
281 case TRBinaryOpIC::GENERIC:
282 return unknown;
283 default:
284 return unknown;
285 }
286 }
287 return unknown;
288}
289
Ben Murdochb8e0da22011-05-16 14:20:40 +0100290
Ben Murdochb0fe1622011-05-05 13:52:32 +0100291TypeInfo TypeFeedbackOracle::SwitchType(CaseClause* clause) {
Steve Block44f0eee2011-05-26 01:26:41 +0100292 Handle<Object> object = GetInfo(clause->position());
Ben Murdochb0fe1622011-05-05 13:52:32 +0100293 TypeInfo unknown = TypeInfo::Unknown();
294 if (!object->IsCode()) return unknown;
295 Handle<Code> code = Handle<Code>::cast(object);
296 if (!code->is_compare_ic_stub()) return unknown;
297
298 CompareIC::State state = static_cast<CompareIC::State>(code->compare_state());
299 switch (state) {
300 case CompareIC::UNINITIALIZED:
301 // Uninitialized means never executed.
302 // TODO(fschneider): Introduce a separate value for never-executed ICs.
303 return unknown;
304 case CompareIC::SMIS:
305 return TypeInfo::Smi();
306 case CompareIC::HEAP_NUMBERS:
307 return TypeInfo::Number();
308 case CompareIC::OBJECTS:
309 // TODO(kasperl): We really need a type for JS objects here.
310 return TypeInfo::NonPrimitive();
311 case CompareIC::GENERIC:
312 default:
313 return unknown;
314 }
315}
316
317
Ben Murdochb0fe1622011-05-05 13:52:32 +0100318ZoneMapList* TypeFeedbackOracle::CollectReceiverTypes(int position,
319 Handle<String> name,
320 Code::Flags flags) {
Steve Block44f0eee2011-05-26 01:26:41 +0100321 Isolate* isolate = Isolate::Current();
322 Handle<Object> object = GetInfo(position);
Ben Murdochb8e0da22011-05-16 14:20:40 +0100323 if (object->IsUndefined() || object->IsSmi()) return NULL;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100324
Steve Block44f0eee2011-05-26 01:26:41 +0100325 if (*object == isolate->builtins()->builtin(Builtins::kStoreIC_GlobalProxy)) {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100326 // TODO(fschneider): We could collect the maps and signal that
327 // we need a generic store (or load) here.
328 ASSERT(Handle<Code>::cast(object)->ic_state() == MEGAMORPHIC);
329 return NULL;
330 } else if (object->IsMap()) {
331 ZoneMapList* types = new ZoneMapList(1);
332 types->Add(Handle<Map>::cast(object));
333 return types;
334 } else if (Handle<Code>::cast(object)->ic_state() == MEGAMORPHIC) {
335 ZoneMapList* types = new ZoneMapList(4);
336 ASSERT(object->IsCode());
Steve Block44f0eee2011-05-26 01:26:41 +0100337 isolate->stub_cache()->CollectMatchingMaps(types, *name, flags);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100338 return types->length() > 0 ? types : NULL;
339 } else {
340 return NULL;
341 }
342}
343
344
Ben Murdoch8b112d22011-06-08 16:22:53 +0100345void TypeFeedbackOracle::SetInfo(int position, Object* target) {
346 MaybeObject* maybe_result = dictionary_->AtNumberPut(position, target);
347 USE(maybe_result);
348#ifdef DEBUG
349 Object* result;
350 // Dictionary has been allocated with sufficient size for all elements.
351 ASSERT(maybe_result->ToObject(&result));
352 ASSERT(*dictionary_ == result);
353#endif
354}
355
356
Ben Murdochb0fe1622011-05-05 13:52:32 +0100357void TypeFeedbackOracle::PopulateMap(Handle<Code> code) {
Steve Block44f0eee2011-05-26 01:26:41 +0100358 Isolate* isolate = Isolate::Current();
359 HandleScope scope(isolate);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100360
361 const int kInitialCapacity = 16;
362 List<int> code_positions(kInitialCapacity);
363 List<int> source_positions(kInitialCapacity);
364 CollectPositions(*code, &code_positions, &source_positions);
365
Steve Block44f0eee2011-05-26 01:26:41 +0100366 ASSERT(dictionary_.is_null()); // Only initialize once.
367 dictionary_ = isolate->factory()->NewNumberDictionary(
368 code_positions.length());
369
Ben Murdochb0fe1622011-05-05 13:52:32 +0100370 int length = code_positions.length();
371 ASSERT(source_positions.length() == length);
372 for (int i = 0; i < length; i++) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100373 AssertNoAllocation no_allocation;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100374 RelocInfo info(code->instruction_start() + code_positions[i],
375 RelocInfo::CODE_TARGET, 0);
Ben Murdoch8b112d22011-06-08 16:22:53 +0100376 Code* target = Code::GetCodeFromTargetAddress(info.target_address());
Ben Murdochb0fe1622011-05-05 13:52:32 +0100377 int position = source_positions[i];
378 InlineCacheState state = target->ic_state();
379 Code::Kind kind = target->kind();
Ben Murdoch8b112d22011-06-08 16:22:53 +0100380
381 if (kind == Code::TYPE_RECORDING_BINARY_OP_IC ||
Ben Murdochb0fe1622011-05-05 13:52:32 +0100382 kind == Code::COMPARE_IC) {
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.
Steve Block44f0eee2011-05-26 01:26:41 +0100386 int entry = dictionary_->FindEntry(position);
387 if (entry == NumberDictionary::kNotFound) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100388 SetInfo(position, target);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100389 }
390 } else if (state == MONOMORPHIC) {
Steve Block44f0eee2011-05-26 01:26:41 +0100391 if (kind == Code::KEYED_EXTERNAL_ARRAY_LOAD_IC ||
392 kind == Code::KEYED_EXTERNAL_ARRAY_STORE_IC) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100393 SetInfo(position, target);
Steve Block44f0eee2011-05-26 01:26:41 +0100394 } else if (target->kind() != Code::CALL_IC ||
Ben Murdochb8e0da22011-05-16 14:20:40 +0100395 target->check_type() == RECEIVER_MAP_CHECK) {
Steve Block44f0eee2011-05-26 01:26:41 +0100396 Map* map = target->FindFirstMap();
397 if (map == NULL) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100398 SetInfo(position, target);
Ben Murdochb8e0da22011-05-16 14:20:40 +0100399 } else {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100400 SetInfo(position, map);
Ben Murdochb8e0da22011-05-16 14:20:40 +0100401 }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100402 } else {
Ben Murdochb8e0da22011-05-16 14:20:40 +0100403 ASSERT(target->kind() == Code::CALL_IC);
404 CheckType check = target->check_type();
405 ASSERT(check != RECEIVER_MAP_CHECK);
Ben Murdoch8b112d22011-06-08 16:22:53 +0100406 SetInfo(position, Smi::FromInt(check));
Ben Murdochb0fe1622011-05-05 13:52:32 +0100407 }
408 } else if (state == MEGAMORPHIC) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100409 SetInfo(position, target);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100410 }
411 }
Steve Block44f0eee2011-05-26 01:26:41 +0100412 // Allocate handle in the parent scope.
413 dictionary_ = scope.CloseAndEscape(dictionary_);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100414}
415
416
417void TypeFeedbackOracle::CollectPositions(Code* code,
418 List<int>* code_positions,
419 List<int>* source_positions) {
420 AssertNoAllocation no_allocation;
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;
427 for (RelocIterator it(code, mask); !it.done(); it.next()) {
428 RelocInfo* info = it.rinfo();
429 RelocInfo::Mode mode = info->rmode();
430 if (RelocInfo::IsCodeTarget(mode)) {
431 Code* target = Code::GetCodeFromTargetAddress(info->target_address());
432 if (target->is_inline_cache_stub()) {
433 InlineCacheState state = target->ic_state();
434 Code::Kind kind = target->kind();
Ben Murdoch8b112d22011-06-08 16:22:53 +0100435 if (kind == Code::TYPE_RECORDING_BINARY_OP_IC) {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100436 if (target->type_recording_binary_op_type() ==
437 TRBinaryOpIC::GENERIC) {
438 continue;
439 }
440 } else if (kind == Code::COMPARE_IC) {
441 if (target->compare_state() == CompareIC::GENERIC) continue;
442 } else {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100443 if (state != MONOMORPHIC && state != MEGAMORPHIC) continue;
444 }
445 code_positions->Add(
446 static_cast<int>(info->pc() - code->instruction_start()));
447 source_positions->Add(position);
448 }
449 } else {
450 ASSERT(RelocInfo::IsPosition(mode));
451 position = static_cast<int>(info->data());
452 }
453 }
454}
455
Steve Blocka7e24c12009-10-30 11:49:00 +0000456} } // namespace v8::internal