| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 return CollectReceiverTypes(expr->position(), name, flags); | 125 return CollectReceiverTypes(expr->position(), name, flags); |
| 126 } | 126 } |
| 127 | 127 |
| 128 | 128 |
| 129 bool TypeFeedbackOracle::LoadIsBuiltin(Property* expr, Builtins::Name id) { | 129 bool TypeFeedbackOracle::LoadIsBuiltin(Property* expr, Builtins::Name id) { |
| 130 Handle<Object> object = GetElement(map_, expr->position()); | 130 Handle<Object> object = GetElement(map_, expr->position()); |
| 131 return *object == Builtins::builtin(id); | 131 return *object == Builtins::builtin(id); |
| 132 } | 132 } |
| 133 | 133 |
| 134 | 134 |
| 135 TypeInfo TypeFeedbackOracle::CompareType(CompareOperation* expr) { | 135 TypeInfo TypeFeedbackOracle::CompareType(CompareOperation* expr, Side side) { |
| 136 Handle<Object> object = GetElement(map_, expr->position()); | 136 Handle<Object> object = GetElement(map_, expr->position()); |
| 137 TypeInfo unknown = TypeInfo::Unknown(); | 137 TypeInfo unknown = TypeInfo::Unknown(); |
| 138 if (!object->IsCode()) return unknown; | 138 if (!object->IsCode()) return unknown; |
| 139 Handle<Code> code = Handle<Code>::cast(object); | 139 Handle<Code> code = Handle<Code>::cast(object); |
| 140 if (!code->is_compare_ic_stub()) return unknown; | 140 if (!code->is_compare_ic_stub()) return unknown; |
| 141 | 141 |
| 142 CompareIC::State state = static_cast<CompareIC::State>(code->compare_state()); | 142 CompareIC::State state = static_cast<CompareIC::State>(code->compare_state()); |
| 143 switch (state) { | 143 switch (state) { |
| 144 case CompareIC::UNINITIALIZED: | 144 case CompareIC::UNINITIALIZED: |
| 145 // Uninitialized means never executed. | 145 // Uninitialized means never executed. |
| 146 // TODO(fschneider): Introduce a separate value for never-executed ICs. | 146 // TODO(fschneider): Introduce a separate value for never-executed ICs. |
| 147 return unknown; | 147 return unknown; |
| 148 case CompareIC::SMIS: | 148 case CompareIC::SMIS: |
| 149 return TypeInfo::Smi(); | 149 return TypeInfo::Smi(); |
| 150 case CompareIC::HEAP_NUMBERS: | 150 case CompareIC::HEAP_NUMBERS: |
| 151 return TypeInfo::Number(); | 151 return TypeInfo::Number(); |
| 152 case CompareIC::OBJECTS: | 152 case CompareIC::OBJECTS: |
| 153 // TODO(kasperl): We really need a type for JS objects here. | 153 // TODO(kasperl): We really need a type for JS objects here. |
| 154 return TypeInfo::NonPrimitive(); | 154 return TypeInfo::NonPrimitive(); |
| 155 case CompareIC::GENERIC: | 155 case CompareIC::GENERIC: |
| 156 default: | 156 default: |
| 157 return unknown; | 157 return unknown; |
| 158 } | 158 } |
| 159 } | 159 } |
| 160 | 160 |
| 161 | 161 |
| 162 TypeInfo TypeFeedbackOracle::BinaryType(BinaryOperation* expr) { | 162 TypeInfo TypeFeedbackOracle::BinaryType(BinaryOperation* expr, Side side) { |
| 163 Handle<Object> object = GetElement(map_, expr->position()); | 163 Handle<Object> object = GetElement(map_, expr->position()); |
| 164 TypeInfo unknown = TypeInfo::Unknown(); | 164 TypeInfo unknown = TypeInfo::Unknown(); |
| 165 if (!object->IsCode()) return unknown; | 165 if (!object->IsCode()) return unknown; |
| 166 Handle<Code> code = Handle<Code>::cast(object); | 166 Handle<Code> code = Handle<Code>::cast(object); |
| 167 if (code->is_type_recording_binary_op_stub()) { | 167 if (code->is_binary_op_stub()) { |
| 168 BinaryOpIC::TypeInfo type = static_cast<BinaryOpIC::TypeInfo>( |
| 169 code->binary_op_type()); |
| 170 switch (type) { |
| 171 case BinaryOpIC::UNINIT_OR_SMI: |
| 172 return TypeInfo::Smi(); |
| 173 case BinaryOpIC::DEFAULT: |
| 174 return (expr->op() == Token::DIV || expr->op() == Token::MUL) |
| 175 ? TypeInfo::Double() |
| 176 : TypeInfo::Integer32(); |
| 177 case BinaryOpIC::HEAP_NUMBERS: |
| 178 return TypeInfo::Double(); |
| 179 default: |
| 180 return unknown; |
| 181 } |
| 182 } else if (code->is_type_recording_binary_op_stub()) { |
| 168 TRBinaryOpIC::TypeInfo type = static_cast<TRBinaryOpIC::TypeInfo>( | 183 TRBinaryOpIC::TypeInfo type = static_cast<TRBinaryOpIC::TypeInfo>( |
| 169 code->type_recording_binary_op_type()); | 184 code->type_recording_binary_op_type()); |
| 170 TRBinaryOpIC::TypeInfo result_type = static_cast<TRBinaryOpIC::TypeInfo>( | 185 TRBinaryOpIC::TypeInfo result_type = static_cast<TRBinaryOpIC::TypeInfo>( |
| 171 code->type_recording_binary_op_result_type()); | 186 code->type_recording_binary_op_result_type()); |
| 172 | 187 |
| 173 switch (type) { | 188 switch (type) { |
| 174 case TRBinaryOpIC::UNINITIALIZED: | 189 case TRBinaryOpIC::UNINITIALIZED: |
| 175 // Uninitialized means never executed. | 190 // Uninitialized means never executed. |
| 176 // TODO(fschneider): Introduce a separate value for never-executed ICs | 191 // TODO(fschneider): Introduce a separate value for never-executed ICs |
| 177 return unknown; | 192 return unknown; |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 | 284 |
| 270 int length = code_positions.length(); | 285 int length = code_positions.length(); |
| 271 ASSERT(source_positions.length() == length); | 286 ASSERT(source_positions.length() == length); |
| 272 for (int i = 0; i < length; i++) { | 287 for (int i = 0; i < length; i++) { |
| 273 RelocInfo info(code->instruction_start() + code_positions[i], | 288 RelocInfo info(code->instruction_start() + code_positions[i], |
| 274 RelocInfo::CODE_TARGET, 0); | 289 RelocInfo::CODE_TARGET, 0); |
| 275 Handle<Code> target(Code::GetCodeFromTargetAddress(info.target_address())); | 290 Handle<Code> target(Code::GetCodeFromTargetAddress(info.target_address())); |
| 276 int position = source_positions[i]; | 291 int position = source_positions[i]; |
| 277 InlineCacheState state = target->ic_state(); | 292 InlineCacheState state = target->ic_state(); |
| 278 Code::Kind kind = target->kind(); | 293 Code::Kind kind = target->kind(); |
| 279 if (kind == Code::TYPE_RECORDING_BINARY_OP_IC || | 294 if (kind == Code::BINARY_OP_IC || |
| 295 kind == Code::TYPE_RECORDING_BINARY_OP_IC || |
| 280 kind == Code::COMPARE_IC) { | 296 kind == Code::COMPARE_IC) { |
| 281 // TODO(kasperl): Avoid having multiple ICs with the same | 297 // TODO(kasperl): Avoid having multiple ICs with the same |
| 282 // position by making sure that we have position information | 298 // position by making sure that we have position information |
| 283 // recorded for all binary ICs. | 299 // recorded for all binary ICs. |
| 284 if (GetElement(map_, position)->IsUndefined()) { | 300 if (GetElement(map_, position)->IsUndefined()) { |
| 285 SetElement(map_, position, target); | 301 SetElement(map_, position, target); |
| 286 } | 302 } |
| 287 } else if (state == MONOMORPHIC) { | 303 } else if (state == MONOMORPHIC) { |
| 288 Handle<Map> map = Handle<Map>(target->FindFirstMap()); | 304 Handle<Map> map = Handle<Map>(target->FindFirstMap()); |
| 289 if (*map == NULL) { | 305 if (*map == NULL) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 309 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | | 325 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | |
| 310 RelocInfo::kPositionMask; | 326 RelocInfo::kPositionMask; |
| 311 for (RelocIterator it(code, mask); !it.done(); it.next()) { | 327 for (RelocIterator it(code, mask); !it.done(); it.next()) { |
| 312 RelocInfo* info = it.rinfo(); | 328 RelocInfo* info = it.rinfo(); |
| 313 RelocInfo::Mode mode = info->rmode(); | 329 RelocInfo::Mode mode = info->rmode(); |
| 314 if (RelocInfo::IsCodeTarget(mode)) { | 330 if (RelocInfo::IsCodeTarget(mode)) { |
| 315 Code* target = Code::GetCodeFromTargetAddress(info->target_address()); | 331 Code* target = Code::GetCodeFromTargetAddress(info->target_address()); |
| 316 if (target->is_inline_cache_stub()) { | 332 if (target->is_inline_cache_stub()) { |
| 317 InlineCacheState state = target->ic_state(); | 333 InlineCacheState state = target->ic_state(); |
| 318 Code::Kind kind = target->kind(); | 334 Code::Kind kind = target->kind(); |
| 319 if (kind == Code::TYPE_RECORDING_BINARY_OP_IC && | 335 if (kind == Code::BINARY_OP_IC) { |
| 320 target->type_recording_binary_op_type() == TRBinaryOpIC::GENERIC) { | 336 if (target->binary_op_type() == BinaryOpIC::GENERIC) continue; |
| 321 continue; | 337 } else if (kind == Code::TYPE_RECORDING_BINARY_OP_IC) { |
| 322 } else if (kind == Code::COMPARE_IC && | 338 if (target->type_recording_binary_op_type() == |
| 323 target->compare_state() == CompareIC::GENERIC) { | 339 TRBinaryOpIC::GENERIC) { |
| 324 continue; | 340 continue; |
| 325 } else if (kind == Code::CALL_IC && state == MONOMORPHIC && | 341 } |
| 326 target->check_type() != RECEIVER_MAP_CHECK) { | 342 } else if (kind == Code::COMPARE_IC) { |
| 327 continue; | 343 if (target->compare_state() == CompareIC::GENERIC) continue; |
| 328 } else if (state != MONOMORPHIC && state != MEGAMORPHIC) { | 344 } else { |
| 329 continue; | 345 if (kind == Code::CALL_IC && state == MONOMORPHIC && |
| 346 target->check_type() != RECEIVER_MAP_CHECK) continue; |
| 347 if (state != MONOMORPHIC && state != MEGAMORPHIC) continue; |
| 330 } | 348 } |
| 331 code_positions->Add( | 349 code_positions->Add( |
| 332 static_cast<int>(info->pc() - code->instruction_start())); | 350 static_cast<int>(info->pc() - code->instruction_start())); |
| 333 source_positions->Add(position); | 351 source_positions->Add(position); |
| 334 } | 352 } |
| 335 } else { | 353 } else { |
| 336 ASSERT(RelocInfo::IsPosition(mode)); | 354 ASSERT(RelocInfo::IsPosition(mode)); |
| 337 position = static_cast<int>(info->data()); | 355 position = static_cast<int>(info->data()); |
| 338 } | 356 } |
| 339 } | 357 } |
| 340 } | 358 } |
| 341 | 359 |
| 342 } } // namespace v8::internal | 360 } } // namespace v8::internal |
| OLD | NEW |