| 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 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 // Adjust for the number of properties stored in the object. Even in the | 375 // Adjust for the number of properties stored in the object. Even in the |
| 376 // face of a transition we can use the old map here because the size of the | 376 // face of a transition we can use the old map here because the size of the |
| 377 // object and the number of in-object properties is not going to change. | 377 // object and the number of in-object properties is not going to change. |
| 378 index -= object->map()->inobject_properties(); | 378 index -= object->map()->inobject_properties(); |
| 379 | 379 |
| 380 if (index < 0) { | 380 if (index < 0) { |
| 381 // Set the property straight into the object. | 381 // Set the property straight into the object. |
| 382 int offset = object->map()->instance_size() + (index * kPointerSize); | 382 int offset = object->map()->instance_size() + (index * kPointerSize); |
| 383 __ movq(FieldOperand(receiver_reg, offset), rax); | 383 __ movq(FieldOperand(receiver_reg, offset), rax); |
| 384 | 384 |
| 385 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 385 // Update the write barrier for the array address. | 386 // Update the write barrier for the array address. |
| 386 // Pass the value being stored in the now unused name_reg. | 387 // Pass the value being stored in the now unused name_reg. |
| 387 __ movq(name_reg, rax); | 388 __ movq(name_reg, rax); |
| 388 __ RecordWrite(receiver_reg, offset, name_reg, scratch); | 389 __ RecordWrite(receiver_reg, offset, name_reg, scratch); |
| 390 #endif |
| 389 } else { | 391 } else { |
| 390 // Write to the properties array. | 392 // Write to the properties array. |
| 391 int offset = index * kPointerSize + FixedArray::kHeaderSize; | 393 int offset = index * kPointerSize + FixedArray::kHeaderSize; |
| 392 // Get the properties array (optimistically). | 394 // Get the properties array (optimistically). |
| 393 __ movq(scratch, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); | 395 __ movq(scratch, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); |
| 394 __ movq(FieldOperand(scratch, offset), rax); | 396 __ movq(FieldOperand(scratch, offset), rax); |
| 395 | 397 |
| 398 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 396 // Update the write barrier for the array address. | 399 // Update the write barrier for the array address. |
| 397 // Pass the value being stored in the now unused name_reg. | 400 // Pass the value being stored in the now unused name_reg. |
| 398 __ movq(name_reg, rax); | 401 __ movq(name_reg, rax); |
| 399 __ RecordWrite(scratch, offset, name_reg, receiver_reg); | 402 __ RecordWrite(scratch, offset, name_reg, receiver_reg); |
| 403 #endif |
| 400 } | 404 } |
| 401 | 405 |
| 402 // Return the value (register rax). | 406 // Return the value (register rax). |
| 403 __ ret(0); | 407 __ ret(0); |
| 404 } | 408 } |
| 405 | 409 |
| 406 | 410 |
| 407 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, | 411 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, |
| 408 Register receiver, | 412 Register receiver, |
| 409 Register scratch, | 413 Register scratch, |
| (...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1205 | 1209 |
| 1206 // Get the elements array of the object. | 1210 // Get the elements array of the object. |
| 1207 __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset)); | 1211 __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset)); |
| 1208 | 1212 |
| 1209 // Check that the elements are in fast mode and writable. | 1213 // Check that the elements are in fast mode and writable. |
| 1210 __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset), | 1214 __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset), |
| 1211 Factory::fixed_array_map()); | 1215 Factory::fixed_array_map()); |
| 1212 __ j(not_equal, &call_builtin); | 1216 __ j(not_equal, &call_builtin); |
| 1213 | 1217 |
| 1214 if (argc == 1) { // Otherwise fall through to call builtin. | 1218 if (argc == 1) { // Otherwise fall through to call builtin. |
| 1215 Label exit, with_write_barrier, attempt_to_grow_elements; | 1219 Label exit, attempt_to_grow_elements; |
| 1220 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 1221 Label with_write_barrier; |
| 1222 #endif |
| 1216 | 1223 |
| 1217 // Get the array's length into rax and calculate new length. | 1224 // Get the array's length into rax and calculate new length. |
| 1218 __ SmiToInteger32(rax, FieldOperand(rdx, JSArray::kLengthOffset)); | 1225 __ SmiToInteger32(rax, FieldOperand(rdx, JSArray::kLengthOffset)); |
| 1219 STATIC_ASSERT(FixedArray::kMaxLength < Smi::kMaxValue); | 1226 STATIC_ASSERT(FixedArray::kMaxLength < Smi::kMaxValue); |
| 1220 __ addl(rax, Immediate(argc)); | 1227 __ addl(rax, Immediate(argc)); |
| 1221 | 1228 |
| 1222 // Get the element's length into rcx. | 1229 // Get the element's length into rcx. |
| 1223 __ SmiToInteger32(rcx, FieldOperand(rbx, FixedArray::kLengthOffset)); | 1230 __ SmiToInteger32(rcx, FieldOperand(rbx, FixedArray::kLengthOffset)); |
| 1224 | 1231 |
| 1225 // Check if we could survive without allocation. | 1232 // Check if we could survive without allocation. |
| 1226 __ cmpl(rax, rcx); | 1233 __ cmpl(rax, rcx); |
| 1227 __ j(greater, &attempt_to_grow_elements); | 1234 __ j(greater, &attempt_to_grow_elements); |
| 1228 | 1235 |
| 1229 // Save new length. | 1236 // Save new length. |
| 1230 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax); | 1237 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax); |
| 1231 | 1238 |
| 1232 // Push the element. | 1239 // Push the element. |
| 1233 __ movq(rcx, Operand(rsp, argc * kPointerSize)); | 1240 __ movq(rcx, Operand(rsp, argc * kPointerSize)); |
| 1234 __ lea(rdx, FieldOperand(rbx, | 1241 __ lea(rdx, FieldOperand(rbx, |
| 1235 rax, times_pointer_size, | 1242 rax, times_pointer_size, |
| 1236 FixedArray::kHeaderSize - argc * kPointerSize)); | 1243 FixedArray::kHeaderSize - argc * kPointerSize)); |
| 1237 __ movq(Operand(rdx, 0), rcx); | 1244 __ movq(Operand(rdx, 0), rcx); |
| 1238 | 1245 |
| 1239 // Check if value is a smi. | 1246 // Check if value is a smi. |
| 1240 __ Integer32ToSmi(rax, rax); // Return new length as smi. | 1247 __ Integer32ToSmi(rax, rax); // Return new length as smi. |
| 1241 | 1248 |
| 1249 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 1242 __ JumpIfNotSmi(rcx, &with_write_barrier); | 1250 __ JumpIfNotSmi(rcx, &with_write_barrier); |
| 1251 #endif |
| 1243 | 1252 |
| 1244 __ bind(&exit); | 1253 __ bind(&exit); |
| 1245 __ ret((argc + 1) * kPointerSize); | 1254 __ ret((argc + 1) * kPointerSize); |
| 1246 | 1255 |
| 1256 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 1247 __ bind(&with_write_barrier); | 1257 __ bind(&with_write_barrier); |
| 1248 | 1258 |
| 1249 __ InNewSpace(rbx, rcx, equal, &exit); | 1259 __ InNewSpace(rbx, rcx, equal, &exit); |
| 1250 | 1260 |
| 1251 RecordWriteStub stub(rbx, rdx, rcx); | 1261 RecordWriteStub stub(rbx, rdx, rcx); |
| 1252 __ CallStub(&stub); | 1262 __ CallStub(&stub); |
| 1253 | 1263 |
| 1254 __ ret((argc + 1) * kPointerSize); | 1264 __ ret((argc + 1) * kPointerSize); |
| 1265 #endif |
| 1255 | 1266 |
| 1256 __ bind(&attempt_to_grow_elements); | 1267 __ bind(&attempt_to_grow_elements); |
| 1257 if (!FLAG_inline_new) { | 1268 if (!FLAG_inline_new) { |
| 1258 __ jmp(&call_builtin); | 1269 __ jmp(&call_builtin); |
| 1259 } | 1270 } |
| 1260 | 1271 |
| 1261 ExternalReference new_space_allocation_top = | 1272 ExternalReference new_space_allocation_top = |
| 1262 ExternalReference::new_space_allocation_top_address(); | 1273 ExternalReference::new_space_allocation_top_address(); |
| 1263 ExternalReference new_space_allocation_limit = | 1274 ExternalReference new_space_allocation_limit = |
| 1264 ExternalReference::new_space_allocation_limit_address(); | 1275 ExternalReference::new_space_allocation_limit_address(); |
| (...skipping 1291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2556 __ SmiCompare(rcx, FieldOperand(rdi, FixedArray::kLengthOffset)); | 2567 __ SmiCompare(rcx, FieldOperand(rdi, FixedArray::kLengthOffset)); |
| 2557 __ j(above_equal, &miss); | 2568 __ j(above_equal, &miss); |
| 2558 } | 2569 } |
| 2559 | 2570 |
| 2560 // Do the store and update the write barrier. Make sure to preserve | 2571 // Do the store and update the write barrier. Make sure to preserve |
| 2561 // the value in register eax. | 2572 // the value in register eax. |
| 2562 __ movq(rdx, rax); | 2573 __ movq(rdx, rax); |
| 2563 __ SmiToInteger32(rcx, rcx); | 2574 __ SmiToInteger32(rcx, rcx); |
| 2564 __ movq(FieldOperand(rdi, rcx, times_pointer_size, FixedArray::kHeaderSize), | 2575 __ movq(FieldOperand(rdi, rcx, times_pointer_size, FixedArray::kHeaderSize), |
| 2565 rax); | 2576 rax); |
| 2577 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 2566 __ RecordWrite(rdi, 0, rdx, rcx); | 2578 __ RecordWrite(rdi, 0, rdx, rcx); |
| 2579 #endif |
| 2567 | 2580 |
| 2568 // Done. | 2581 // Done. |
| 2569 __ ret(0); | 2582 __ ret(0); |
| 2570 | 2583 |
| 2571 // Handle store cache miss. | 2584 // Handle store cache miss. |
| 2572 __ bind(&miss); | 2585 __ bind(&miss); |
| 2573 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); | 2586 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); |
| 2574 __ jmp(ic, RelocInfo::CODE_TARGET); | 2587 __ jmp(ic, RelocInfo::CODE_TARGET); |
| 2575 | 2588 |
| 2576 // Return the generated code. | 2589 // Return the generated code. |
| (...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3118 // Return the generated code. | 3131 // Return the generated code. |
| 3119 return GetCode(); | 3132 return GetCode(); |
| 3120 } | 3133 } |
| 3121 | 3134 |
| 3122 | 3135 |
| 3123 #undef __ | 3136 #undef __ |
| 3124 | 3137 |
| 3125 } } // namespace v8::internal | 3138 } } // namespace v8::internal |
| 3126 | 3139 |
| 3127 #endif // V8_TARGET_ARCH_X64 | 3140 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |