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 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 | 194 |
195 // Probe the secondary table. | 195 // Probe the secondary table. |
196 ProbeTable(masm, flags, kSecondary, name, scratch); | 196 ProbeTable(masm, flags, kSecondary, name, scratch); |
197 | 197 |
198 // Cache miss: Fall-through and let caller handle the miss by | 198 // Cache miss: Fall-through and let caller handle the miss by |
199 // entering the runtime system. | 199 // entering the runtime system. |
200 __ bind(&miss); | 200 __ bind(&miss); |
201 } | 201 } |
202 | 202 |
203 | 203 |
| 204 // Both name_reg and receiver_reg are preserved on jumps to miss_label, |
| 205 // but may be destroyed if store is successful. |
204 void StubCompiler::GenerateStoreField(MacroAssembler* masm, | 206 void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
205 Builtins::Name storage_extend, | |
206 JSObject* object, | 207 JSObject* object, |
207 int index, | 208 int index, |
208 Map* transition, | 209 Map* transition, |
209 Register receiver_reg, | 210 Register receiver_reg, |
210 Register name_reg, | 211 Register name_reg, |
211 Register scratch, | 212 Register scratch, |
212 Label* miss_label) { | 213 Label* miss_label) { |
213 // Check that the object isn't a smi. | 214 // Check that the object isn't a smi. |
214 __ JumpIfSmi(receiver_reg, miss_label); | 215 __ JumpIfSmi(receiver_reg, miss_label); |
215 | 216 |
216 // Check that the map of the object hasn't changed. | 217 // Check that the map of the object hasn't changed. |
217 __ Cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset), | 218 __ Cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset), |
218 Handle<Map>(object->map())); | 219 Handle<Map>(object->map())); |
219 __ j(not_equal, miss_label); | 220 __ j(not_equal, miss_label); |
220 | 221 |
221 // Perform global security token check if needed. | 222 // Perform global security token check if needed. |
222 if (object->IsJSGlobalProxy()) { | 223 if (object->IsJSGlobalProxy()) { |
223 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); | 224 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); |
224 } | 225 } |
225 | 226 |
226 // Stub never generated for non-global objects that require access | 227 // Stub never generated for non-global objects that require access |
227 // checks. | 228 // checks. |
228 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 229 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
229 | 230 |
230 // Perform map transition for the receiver if necessary. | 231 // Perform map transition for the receiver if necessary. |
231 if ((transition != NULL) && (object->map()->unused_property_fields() == 0)) { | 232 if ((transition != NULL) && (object->map()->unused_property_fields() == 0)) { |
232 // The properties must be extended before we can store the value. | 233 // The properties must be extended before we can store the value. |
233 // We jump to a runtime call that extends the properties array. | 234 // We jump to a runtime call that extends the properties array. |
234 __ Move(rcx, Handle<Map>(transition)); | 235 __ pop(scratch); // Return address. |
235 Handle<Code> ic(Builtins::builtin(storage_extend)); | 236 __ push(receiver_reg); |
236 __ Jump(ic, RelocInfo::CODE_TARGET); | 237 __ Push(Handle<Map>(transition)); |
| 238 __ push(rax); |
| 239 __ push(scratch); |
| 240 __ TailCallRuntime( |
| 241 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage)), 3, 1); |
237 return; | 242 return; |
238 } | 243 } |
239 | 244 |
240 if (transition != NULL) { | 245 if (transition != NULL) { |
241 // Update the map of the object; no write barrier updating is | 246 // Update the map of the object; no write barrier updating is |
242 // needed because the map is never in new space. | 247 // needed because the map is never in new space. |
243 __ Move(FieldOperand(receiver_reg, HeapObject::kMapOffset), | 248 __ Move(FieldOperand(receiver_reg, HeapObject::kMapOffset), |
244 Handle<Map>(transition)); | 249 Handle<Map>(transition)); |
245 } | 250 } |
246 | 251 |
(...skipping 1145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1392 Map* transition, | 1397 Map* transition, |
1393 String* name) { | 1398 String* name) { |
1394 // ----------- S t a t e ------------- | 1399 // ----------- S t a t e ------------- |
1395 // -- rax : value | 1400 // -- rax : value |
1396 // -- rcx : name | 1401 // -- rcx : name |
1397 // -- rdx : receiver | 1402 // -- rdx : receiver |
1398 // -- rsp[0] : return address | 1403 // -- rsp[0] : return address |
1399 // ----------------------------------- | 1404 // ----------------------------------- |
1400 Label miss; | 1405 Label miss; |
1401 | 1406 |
1402 // Generate store field code. Trashes the name register. | 1407 // Generate store field code. Preserves receiver and name on jump to miss. |
1403 GenerateStoreField(masm(), | 1408 GenerateStoreField(masm(), |
1404 Builtins::StoreIC_ExtendStorage, | |
1405 object, | 1409 object, |
1406 index, | 1410 index, |
1407 transition, | 1411 transition, |
1408 rdx, rcx, rbx, | 1412 rdx, rcx, rbx, |
1409 &miss); | 1413 &miss); |
1410 | 1414 |
1411 // Handle store cache miss. | 1415 // Handle store cache miss. |
1412 __ bind(&miss); | 1416 __ bind(&miss); |
1413 __ Move(rcx, Handle<String>(name)); // restore name | |
1414 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); | 1417 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); |
1415 __ Jump(ic, RelocInfo::CODE_TARGET); | 1418 __ Jump(ic, RelocInfo::CODE_TARGET); |
1416 | 1419 |
1417 // Return the generated code. | 1420 // Return the generated code. |
1418 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 1421 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); |
1419 } | 1422 } |
1420 | 1423 |
1421 | 1424 |
1422 Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver, | 1425 Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver, |
1423 String* name) { | 1426 String* name) { |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1545 Label miss; | 1548 Label miss; |
1546 | 1549 |
1547 __ IncrementCounter(&Counters::keyed_store_field, 1); | 1550 __ IncrementCounter(&Counters::keyed_store_field, 1); |
1548 | 1551 |
1549 // Get the name from the stack. | 1552 // Get the name from the stack. |
1550 __ movq(rcx, Operand(rsp, 1 * kPointerSize)); | 1553 __ movq(rcx, Operand(rsp, 1 * kPointerSize)); |
1551 // Check that the name has not changed. | 1554 // Check that the name has not changed. |
1552 __ Cmp(rcx, Handle<String>(name)); | 1555 __ Cmp(rcx, Handle<String>(name)); |
1553 __ j(not_equal, &miss); | 1556 __ j(not_equal, &miss); |
1554 | 1557 |
1555 // Get the object from the stack. | 1558 // Get the receiver from the stack. |
1556 __ movq(rbx, Operand(rsp, 2 * kPointerSize)); | 1559 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); |
1557 | 1560 |
1558 // Generate store field code. Trashes the name register. | 1561 // Generate store field code. Preserves receiver and name on jump to miss. |
1559 GenerateStoreField(masm(), | 1562 GenerateStoreField(masm(), |
1560 Builtins::KeyedStoreIC_ExtendStorage, | |
1561 object, | 1563 object, |
1562 index, | 1564 index, |
1563 transition, | 1565 transition, |
1564 rbx, rcx, rdx, | 1566 rdx, rcx, rbx, |
1565 &miss); | 1567 &miss); |
1566 | 1568 |
1567 // Handle store cache miss. | 1569 // Handle store cache miss. |
1568 __ bind(&miss); | 1570 __ bind(&miss); |
1569 __ DecrementCounter(&Counters::keyed_store_field, 1); | 1571 __ DecrementCounter(&Counters::keyed_store_field, 1); |
1570 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); | 1572 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); |
1571 __ Jump(ic, RelocInfo::CODE_TARGET); | 1573 __ Jump(ic, RelocInfo::CODE_TARGET); |
1572 | 1574 |
1573 // Return the generated code. | 1575 // Return the generated code. |
1574 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 1576 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1867 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); | 1869 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); |
1868 | 1870 |
1869 // Return the generated code. | 1871 // Return the generated code. |
1870 return GetCode(); | 1872 return GetCode(); |
1871 } | 1873 } |
1872 | 1874 |
1873 | 1875 |
1874 #undef __ | 1876 #undef __ |
1875 | 1877 |
1876 } } // namespace v8::internal | 1878 } } // namespace v8::internal |
OLD | NEW |