| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
| 8 | 8 |
| 9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
| 10 #include "src/ic/ic.h" | 10 #include "src/ic/ic.h" |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 // bit test is enough. | 256 // bit test is enough. |
| 257 STATIC_ASSERT(kNotInternalizedTag != 0); | 257 STATIC_ASSERT(kNotInternalizedTag != 0); |
| 258 __ test_b(FieldOperand(map, Map::kInstanceTypeOffset), | 258 __ test_b(FieldOperand(map, Map::kInstanceTypeOffset), |
| 259 kIsNotInternalizedMask); | 259 kIsNotInternalizedMask); |
| 260 __ j(not_zero, not_unique); | 260 __ j(not_zero, not_unique); |
| 261 | 261 |
| 262 __ bind(&unique); | 262 __ bind(&unique); |
| 263 } | 263 } |
| 264 | 264 |
| 265 | 265 |
| 266 static Operand GenerateMappedArgumentsLookup( | |
| 267 MacroAssembler* masm, Register object, Register key, Register scratch1, | |
| 268 Register scratch2, Label* unmapped_case, Label* slow_case) { | |
| 269 Heap* heap = masm->isolate()->heap(); | |
| 270 Factory* factory = masm->isolate()->factory(); | |
| 271 | |
| 272 // Check that the receiver is a JSObject. Because of the elements | |
| 273 // map check later, we do not need to check for interceptors or | |
| 274 // whether it requires access checks. | |
| 275 __ JumpIfSmi(object, slow_case); | |
| 276 // Check that the object is some kind of JSObject. | |
| 277 __ CmpObjectType(object, FIRST_JS_RECEIVER_TYPE, scratch1); | |
| 278 __ j(below, slow_case); | |
| 279 | |
| 280 // Check that the key is a positive smi. | |
| 281 __ test(key, Immediate(0x80000001)); | |
| 282 __ j(not_zero, slow_case); | |
| 283 | |
| 284 // Load the elements into scratch1 and check its map. | |
| 285 Handle<Map> arguments_map(heap->sloppy_arguments_elements_map()); | |
| 286 __ mov(scratch1, FieldOperand(object, JSObject::kElementsOffset)); | |
| 287 __ CheckMap(scratch1, arguments_map, slow_case, DONT_DO_SMI_CHECK); | |
| 288 | |
| 289 // Check if element is in the range of mapped arguments. If not, jump | |
| 290 // to the unmapped lookup with the parameter map in scratch1. | |
| 291 __ mov(scratch2, FieldOperand(scratch1, FixedArray::kLengthOffset)); | |
| 292 __ sub(scratch2, Immediate(Smi::FromInt(2))); | |
| 293 __ cmp(key, scratch2); | |
| 294 __ j(above_equal, unmapped_case); | |
| 295 | |
| 296 // Load element index and check whether it is the hole. | |
| 297 const int kHeaderSize = FixedArray::kHeaderSize + 2 * kPointerSize; | |
| 298 __ mov(scratch2, | |
| 299 FieldOperand(scratch1, key, times_half_pointer_size, kHeaderSize)); | |
| 300 __ cmp(scratch2, factory->the_hole_value()); | |
| 301 __ j(equal, unmapped_case); | |
| 302 | |
| 303 // Load value from context and return it. We can reuse scratch1 because | |
| 304 // we do not jump to the unmapped lookup (which requires the parameter | |
| 305 // map in scratch1). | |
| 306 const int kContextOffset = FixedArray::kHeaderSize; | |
| 307 __ mov(scratch1, FieldOperand(scratch1, kContextOffset)); | |
| 308 return FieldOperand(scratch1, scratch2, times_half_pointer_size, | |
| 309 Context::kHeaderSize); | |
| 310 } | |
| 311 | |
| 312 | |
| 313 static Operand GenerateUnmappedArgumentsLookup(MacroAssembler* masm, | |
| 314 Register key, | |
| 315 Register parameter_map, | |
| 316 Register scratch, | |
| 317 Label* slow_case) { | |
| 318 // Element is in arguments backing store, which is referenced by the | |
| 319 // second element of the parameter_map. | |
| 320 const int kBackingStoreOffset = FixedArray::kHeaderSize + kPointerSize; | |
| 321 Register backing_store = parameter_map; | |
| 322 __ mov(backing_store, FieldOperand(parameter_map, kBackingStoreOffset)); | |
| 323 Handle<Map> fixed_array_map(masm->isolate()->heap()->fixed_array_map()); | |
| 324 __ CheckMap(backing_store, fixed_array_map, slow_case, DONT_DO_SMI_CHECK); | |
| 325 __ mov(scratch, FieldOperand(backing_store, FixedArray::kLengthOffset)); | |
| 326 __ cmp(key, scratch); | |
| 327 __ j(greater_equal, slow_case); | |
| 328 return FieldOperand(backing_store, key, times_half_pointer_size, | |
| 329 FixedArray::kHeaderSize); | |
| 330 } | |
| 331 | |
| 332 | |
| 333 void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) { | 266 void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) { |
| 334 // The return address is on the stack. | 267 // The return address is on the stack. |
| 335 Label slow, check_name, index_smi, index_name, property_array_property; | 268 Label slow, check_name, index_smi, index_name, property_array_property; |
| 336 Label probe_dictionary, check_number_dictionary; | 269 Label probe_dictionary, check_number_dictionary; |
| 337 | 270 |
| 338 Register receiver = LoadDescriptor::ReceiverRegister(); | 271 Register receiver = LoadDescriptor::ReceiverRegister(); |
| 339 Register key = LoadDescriptor::NameRegister(); | 272 Register key = LoadDescriptor::NameRegister(); |
| 340 DCHECK(receiver.is(edx)); | 273 DCHECK(receiver.is(edx)); |
| 341 DCHECK(key.is(ecx)); | 274 DCHECK(key.is(ecx)); |
| 342 | 275 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 430 __ IncrementCounter(counters->keyed_load_generic_symbol(), 1); | 363 __ IncrementCounter(counters->keyed_load_generic_symbol(), 1); |
| 431 __ ret(0); | 364 __ ret(0); |
| 432 | 365 |
| 433 __ bind(&index_name); | 366 __ bind(&index_name); |
| 434 __ IndexFromHash(ebx, key); | 367 __ IndexFromHash(ebx, key); |
| 435 // Now jump to the place where smi keys are handled. | 368 // Now jump to the place where smi keys are handled. |
| 436 __ jmp(&index_smi); | 369 __ jmp(&index_smi); |
| 437 } | 370 } |
| 438 | 371 |
| 439 | 372 |
| 440 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { | |
| 441 // Return address is on the stack. | |
| 442 Label slow, notin; | |
| 443 Register receiver = StoreDescriptor::ReceiverRegister(); | |
| 444 Register name = StoreDescriptor::NameRegister(); | |
| 445 Register value = StoreDescriptor::ValueRegister(); | |
| 446 DCHECK(receiver.is(edx)); | |
| 447 DCHECK(name.is(ecx)); | |
| 448 DCHECK(value.is(eax)); | |
| 449 | |
| 450 Operand mapped_location = GenerateMappedArgumentsLookup( | |
| 451 masm, receiver, name, ebx, edi, ¬in, &slow); | |
| 452 __ mov(mapped_location, value); | |
| 453 __ lea(ecx, mapped_location); | |
| 454 __ mov(edx, value); | |
| 455 __ RecordWrite(ebx, ecx, edx, kDontSaveFPRegs); | |
| 456 __ Ret(); | |
| 457 __ bind(¬in); | |
| 458 // The unmapped lookup expects that the parameter map is in ebx. | |
| 459 Operand unmapped_location = | |
| 460 GenerateUnmappedArgumentsLookup(masm, name, ebx, edi, &slow); | |
| 461 __ mov(unmapped_location, value); | |
| 462 __ lea(edi, unmapped_location); | |
| 463 __ mov(edx, value); | |
| 464 __ RecordWrite(ebx, edi, edx, kDontSaveFPRegs); | |
| 465 __ Ret(); | |
| 466 __ bind(&slow); | |
| 467 GenerateMiss(masm); | |
| 468 } | |
| 469 | |
| 470 | |
| 471 static void KeyedStoreGenerateMegamorphicHelper( | 373 static void KeyedStoreGenerateMegamorphicHelper( |
| 472 MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow, | 374 MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow, |
| 473 KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length) { | 375 KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length) { |
| 474 Label transition_smi_elements; | 376 Label transition_smi_elements; |
| 475 Label finish_object_store, non_double_value, transition_double_elements; | 377 Label finish_object_store, non_double_value, transition_double_elements; |
| 476 Label fast_double_without_map_check; | 378 Label fast_double_without_map_check; |
| 477 Register receiver = StoreDescriptor::ReceiverRegister(); | 379 Register receiver = StoreDescriptor::ReceiverRegister(); |
| 478 Register key = StoreDescriptor::NameRegister(); | 380 Register key = StoreDescriptor::NameRegister(); |
| 479 Register value = StoreDescriptor::ValueRegister(); | 381 Register value = StoreDescriptor::ValueRegister(); |
| 480 DCHECK(receiver.is(edx)); | 382 DCHECK(receiver.is(edx)); |
| (...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 946 Condition cc = | 848 Condition cc = |
| 947 (check == ENABLE_INLINED_SMI_CHECK) | 849 (check == ENABLE_INLINED_SMI_CHECK) |
| 948 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) | 850 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) |
| 949 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); | 851 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); |
| 950 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 852 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
| 951 } | 853 } |
| 952 } | 854 } |
| 953 } // namespace v8::internal | 855 } // namespace v8::internal |
| 954 | 856 |
| 955 #endif // V8_TARGET_ARCH_IA32 | 857 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |