OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_X64 | 7 #if V8_TARGET_ARCH_X64 |
8 | 8 |
9 #include "src/ic/call-optimization.h" | 9 #include "src/ic/call-optimization.h" |
10 #include "src/ic/handler-compiler.h" | 10 #include "src/ic/handler-compiler.h" |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 DCHECK(cell->value()->IsTheHole()); | 208 DCHECK(cell->value()->IsTheHole()); |
209 Factory* factory = masm->isolate()->factory(); | 209 Factory* factory = masm->isolate()->factory(); |
210 Handle<WeakCell> weak_cell = factory->NewWeakCell(cell); | 210 Handle<WeakCell> weak_cell = factory->NewWeakCell(cell); |
211 __ LoadWeakValue(scratch, weak_cell, miss); | 211 __ LoadWeakValue(scratch, weak_cell, miss); |
212 __ Cmp(FieldOperand(scratch, Cell::kValueOffset), factory->the_hole_value()); | 212 __ Cmp(FieldOperand(scratch, Cell::kValueOffset), factory->the_hole_value()); |
213 __ j(not_equal, miss); | 213 __ j(not_equal, miss); |
214 } | 214 } |
215 | 215 |
216 | 216 |
217 void NamedStoreHandlerCompiler::GenerateStoreViaSetter( | 217 void NamedStoreHandlerCompiler::GenerateStoreViaSetter( |
218 MacroAssembler* masm, Handle<HeapType> type, Register receiver, | 218 MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder, |
219 Register holder, int accessor_index, int expected_arguments, | 219 int accessor_index, int expected_arguments, Register scratch) { |
220 Register scratch) { | |
221 // ----------- S t a t e ------------- | 220 // ----------- S t a t e ------------- |
222 // -- rsp[0] : return address | 221 // -- rsp[0] : return address |
223 // ----------------------------------- | 222 // ----------------------------------- |
224 { | 223 { |
225 FrameScope scope(masm, StackFrame::INTERNAL); | 224 FrameScope scope(masm, StackFrame::INTERNAL); |
226 | 225 |
227 // Save value register, so we can restore it later. | 226 // Save value register, so we can restore it later. |
228 __ Push(value()); | 227 __ Push(value()); |
229 | 228 |
230 if (accessor_index >= 0) { | 229 if (accessor_index >= 0) { |
231 DCHECK(!holder.is(scratch)); | 230 DCHECK(!holder.is(scratch)); |
232 DCHECK(!receiver.is(scratch)); | 231 DCHECK(!receiver.is(scratch)); |
233 DCHECK(!value().is(scratch)); | 232 DCHECK(!value().is(scratch)); |
234 // Call the JavaScript setter with receiver and value on the stack. | 233 // Call the JavaScript setter with receiver and value on the stack. |
235 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { | 234 if (map->IsJSGlobalObjectMap()) { |
236 // Swap in the global receiver. | 235 // Swap in the global receiver. |
237 __ movp(scratch, | 236 __ movp(scratch, |
238 FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); | 237 FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); |
239 receiver = scratch; | 238 receiver = scratch; |
240 } | 239 } |
241 __ Push(receiver); | 240 __ Push(receiver); |
242 __ Push(value()); | 241 __ Push(value()); |
243 ParameterCount actual(1); | 242 ParameterCount actual(1); |
244 ParameterCount expected(expected_arguments); | 243 ParameterCount expected(expected_arguments); |
245 __ LoadAccessor(rdi, holder, accessor_index, ACCESSOR_SETTER); | 244 __ LoadAccessor(rdi, holder, accessor_index, ACCESSOR_SETTER); |
246 __ InvokeFunction(rdi, expected, actual, CALL_FUNCTION, | 245 __ InvokeFunction(rdi, expected, actual, CALL_FUNCTION, |
247 NullCallWrapper()); | 246 NullCallWrapper()); |
248 } else { | 247 } else { |
249 // If we generate a global code snippet for deoptimization only, remember | 248 // If we generate a global code snippet for deoptimization only, remember |
250 // the place to continue after deoptimization. | 249 // the place to continue after deoptimization. |
251 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset()); | 250 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset()); |
252 } | 251 } |
253 | 252 |
254 // We have to return the passed value, not the return value of the setter. | 253 // We have to return the passed value, not the return value of the setter. |
255 __ Pop(rax); | 254 __ Pop(rax); |
256 | 255 |
257 // Restore context register. | 256 // Restore context register. |
258 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 257 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
259 } | 258 } |
260 __ ret(0); | 259 __ ret(0); |
261 } | 260 } |
262 | 261 |
263 | 262 |
264 void NamedLoadHandlerCompiler::GenerateLoadViaGetter( | 263 void NamedLoadHandlerCompiler::GenerateLoadViaGetter( |
265 MacroAssembler* masm, Handle<HeapType> type, Register receiver, | 264 MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder, |
266 Register holder, int accessor_index, int expected_arguments, | 265 int accessor_index, int expected_arguments, Register scratch) { |
267 Register scratch) { | |
268 // ----------- S t a t e ------------- | 266 // ----------- S t a t e ------------- |
269 // -- rax : receiver | 267 // -- rax : receiver |
270 // -- rcx : name | 268 // -- rcx : name |
271 // -- rsp[0] : return address | 269 // -- rsp[0] : return address |
272 // ----------------------------------- | 270 // ----------------------------------- |
273 { | 271 { |
274 FrameScope scope(masm, StackFrame::INTERNAL); | 272 FrameScope scope(masm, StackFrame::INTERNAL); |
275 | 273 |
276 if (accessor_index >= 0) { | 274 if (accessor_index >= 0) { |
277 DCHECK(!holder.is(scratch)); | 275 DCHECK(!holder.is(scratch)); |
278 DCHECK(!receiver.is(scratch)); | 276 DCHECK(!receiver.is(scratch)); |
279 // Call the JavaScript getter with the receiver on the stack. | 277 // Call the JavaScript getter with the receiver on the stack. |
280 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { | 278 if (map->IsJSGlobalObjectMap()) { |
281 // Swap in the global receiver. | 279 // Swap in the global receiver. |
282 __ movp(scratch, | 280 __ movp(scratch, |
283 FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); | 281 FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); |
284 receiver = scratch; | 282 receiver = scratch; |
285 } | 283 } |
286 __ Push(receiver); | 284 __ Push(receiver); |
287 ParameterCount actual(0); | 285 ParameterCount actual(0); |
288 ParameterCount expected(expected_arguments); | 286 ParameterCount expected(expected_arguments); |
289 __ LoadAccessor(rdi, holder, accessor_index, ACCESSOR_GETTER); | 287 __ LoadAccessor(rdi, holder, accessor_index, ACCESSOR_GETTER); |
290 __ InvokeFunction(rdi, expected, actual, CALL_FUNCTION, | 288 __ InvokeFunction(rdi, expected, actual, CALL_FUNCTION, |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 } | 407 } |
410 __ bind(&do_store); | 408 __ bind(&do_store); |
411 } | 409 } |
412 } | 410 } |
413 | 411 |
414 | 412 |
415 Register PropertyHandlerCompiler::CheckPrototypes( | 413 Register PropertyHandlerCompiler::CheckPrototypes( |
416 Register object_reg, Register holder_reg, Register scratch1, | 414 Register object_reg, Register holder_reg, Register scratch1, |
417 Register scratch2, Handle<Name> name, Label* miss, | 415 Register scratch2, Handle<Name> name, Label* miss, |
418 PrototypeCheckType check) { | 416 PrototypeCheckType check) { |
419 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate())); | 417 Handle<Map> receiver_map = map(); |
420 | 418 |
421 // Make sure there's no overlap between holder and object registers. | 419 // Make sure there's no overlap between holder and object registers. |
422 DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 420 DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
423 DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) && | 421 DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) && |
424 !scratch2.is(scratch1)); | 422 !scratch2.is(scratch1)); |
425 | 423 |
426 // Keep track of the current object in register reg. On the first | 424 // Keep track of the current object in register reg. On the first |
427 // iteration, reg is an alias for object_reg, on later iterations, | 425 // iteration, reg is an alias for object_reg, on later iterations, |
428 // it is an alias for holder_reg. | 426 // it is an alias for holder_reg. |
429 Register reg = object_reg; | 427 Register reg = object_reg; |
430 int depth = 0; | 428 int depth = 0; |
431 | 429 |
432 Handle<JSObject> current = Handle<JSObject>::null(); | 430 Handle<JSObject> current = Handle<JSObject>::null(); |
433 if (type()->IsConstant()) { | 431 if (receiver_map->IsJSGlobalObjectMap()) { |
434 current = Handle<JSObject>::cast(type()->AsConstant()->Value()); | 432 current = isolate()->global_object(); |
435 } | 433 } |
436 Handle<JSObject> prototype = Handle<JSObject>::null(); | 434 Handle<JSObject> prototype = Handle<JSObject>::null(); |
437 Handle<Map> current_map = receiver_map; | 435 Handle<Map> current_map = receiver_map; |
438 Handle<Map> holder_map(holder()->map()); | 436 Handle<Map> holder_map(holder()->map()); |
439 // Traverse the prototype chain and check the maps in the prototype chain for | 437 // Traverse the prototype chain and check the maps in the prototype chain for |
440 // fast and global objects or do negative lookup for normal objects. | 438 // fast and global objects or do negative lookup for normal objects. |
441 while (!current_map.is_identical_to(holder_map)) { | 439 while (!current_map.is_identical_to(holder_map)) { |
442 ++depth; | 440 ++depth; |
443 | 441 |
444 // Only global objects and objects that do not require access | 442 // Only global objects and objects that do not require access |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
757 // Return the generated code. | 755 // Return the generated code. |
758 return GetCode(kind(), Code::NORMAL, name); | 756 return GetCode(kind(), Code::NORMAL, name); |
759 } | 757 } |
760 | 758 |
761 | 759 |
762 #undef __ | 760 #undef __ |
763 } | 761 } |
764 } // namespace v8::internal | 762 } // namespace v8::internal |
765 | 763 |
766 #endif // V8_TARGET_ARCH_X64 | 764 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |