| 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_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
| 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 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 &fun, ExternalReference::DIRECT_API_CALL, masm->isolate()); | 216 &fun, ExternalReference::DIRECT_API_CALL, masm->isolate()); |
| 217 __ Mov(api_function_address, ref); | 217 __ Mov(api_function_address, ref); |
| 218 | 218 |
| 219 // Jump to stub. | 219 // Jump to stub. |
| 220 CallApiAccessorStub stub(isolate, is_store, call_data_undefined); | 220 CallApiAccessorStub stub(isolate, is_store, call_data_undefined); |
| 221 __ TailCallStub(&stub); | 221 __ TailCallStub(&stub); |
| 222 } | 222 } |
| 223 | 223 |
| 224 | 224 |
| 225 void NamedStoreHandlerCompiler::GenerateStoreViaSetter( | 225 void NamedStoreHandlerCompiler::GenerateStoreViaSetter( |
| 226 MacroAssembler* masm, Handle<HeapType> type, Register receiver, | 226 MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder, |
| 227 Register holder, int accessor_index, int expected_arguments, | 227 int accessor_index, int expected_arguments, Register scratch) { |
| 228 Register scratch) { | |
| 229 // ----------- S t a t e ------------- | 228 // ----------- S t a t e ------------- |
| 230 // -- lr : return address | 229 // -- lr : return address |
| 231 // ----------------------------------- | 230 // ----------------------------------- |
| 232 Label miss; | 231 Label miss; |
| 233 { | 232 { |
| 234 FrameScope scope(masm, StackFrame::INTERNAL); | 233 FrameScope scope(masm, StackFrame::INTERNAL); |
| 235 | 234 |
| 236 // Save value register, so we can restore it later. | 235 // Save value register, so we can restore it later. |
| 237 __ Push(value()); | 236 __ Push(value()); |
| 238 | 237 |
| 239 if (accessor_index >= 0) { | 238 if (accessor_index >= 0) { |
| 240 DCHECK(!AreAliased(holder, scratch)); | 239 DCHECK(!AreAliased(holder, scratch)); |
| 241 DCHECK(!AreAliased(receiver, scratch)); | 240 DCHECK(!AreAliased(receiver, scratch)); |
| 242 DCHECK(!AreAliased(value(), scratch)); | 241 DCHECK(!AreAliased(value(), scratch)); |
| 243 // Call the JavaScript setter with receiver and value on the stack. | 242 // Call the JavaScript setter with receiver and value on the stack. |
| 244 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { | 243 if (map->IsJSGlobalObjectMap()) { |
| 245 // Swap in the global receiver. | 244 // Swap in the global receiver. |
| 246 __ Ldr(scratch, | 245 __ Ldr(scratch, |
| 247 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); | 246 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); |
| 248 receiver = scratch; | 247 receiver = scratch; |
| 249 } | 248 } |
| 250 __ Push(receiver, value()); | 249 __ Push(receiver, value()); |
| 251 ParameterCount actual(1); | 250 ParameterCount actual(1); |
| 252 ParameterCount expected(expected_arguments); | 251 ParameterCount expected(expected_arguments); |
| 253 __ LoadAccessor(x1, holder, accessor_index, ACCESSOR_SETTER); | 252 __ LoadAccessor(x1, holder, accessor_index, ACCESSOR_SETTER); |
| 254 __ InvokeFunction(x1, expected, actual, CALL_FUNCTION, NullCallWrapper()); | 253 __ InvokeFunction(x1, expected, actual, CALL_FUNCTION, NullCallWrapper()); |
| 255 } else { | 254 } else { |
| 256 // If we generate a global code snippet for deoptimization only, remember | 255 // If we generate a global code snippet for deoptimization only, remember |
| 257 // the place to continue after deoptimization. | 256 // the place to continue after deoptimization. |
| 258 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset()); | 257 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset()); |
| 259 } | 258 } |
| 260 | 259 |
| 261 // We have to return the passed value, not the return value of the setter. | 260 // We have to return the passed value, not the return value of the setter. |
| 262 __ Pop(x0); | 261 __ Pop(x0); |
| 263 | 262 |
| 264 // Restore context register. | 263 // Restore context register. |
| 265 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 264 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 266 } | 265 } |
| 267 __ Ret(); | 266 __ Ret(); |
| 268 } | 267 } |
| 269 | 268 |
| 270 | 269 |
| 271 void NamedLoadHandlerCompiler::GenerateLoadViaGetter( | 270 void NamedLoadHandlerCompiler::GenerateLoadViaGetter( |
| 272 MacroAssembler* masm, Handle<HeapType> type, Register receiver, | 271 MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder, |
| 273 Register holder, int accessor_index, int expected_arguments, | 272 int accessor_index, int expected_arguments, Register scratch) { |
| 274 Register scratch) { | |
| 275 { | 273 { |
| 276 FrameScope scope(masm, StackFrame::INTERNAL); | 274 FrameScope scope(masm, StackFrame::INTERNAL); |
| 277 | 275 |
| 278 if (accessor_index >= 0) { | 276 if (accessor_index >= 0) { |
| 279 DCHECK(!AreAliased(holder, scratch)); | 277 DCHECK(!AreAliased(holder, scratch)); |
| 280 DCHECK(!AreAliased(receiver, scratch)); | 278 DCHECK(!AreAliased(receiver, scratch)); |
| 281 // Call the JavaScript getter with the receiver on the stack. | 279 // Call the JavaScript getter with the receiver on the stack. |
| 282 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { | 280 if (map->IsJSGlobalObjectMap()) { |
| 283 // Swap in the global receiver. | 281 // Swap in the global receiver. |
| 284 __ Ldr(scratch, | 282 __ Ldr(scratch, |
| 285 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); | 283 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); |
| 286 receiver = scratch; | 284 receiver = scratch; |
| 287 } | 285 } |
| 288 __ Push(receiver); | 286 __ Push(receiver); |
| 289 ParameterCount actual(0); | 287 ParameterCount actual(0); |
| 290 ParameterCount expected(expected_arguments); | 288 ParameterCount expected(expected_arguments); |
| 291 __ LoadAccessor(x1, holder, accessor_index, ACCESSOR_GETTER); | 289 __ LoadAccessor(x1, holder, accessor_index, ACCESSOR_GETTER); |
| 292 __ InvokeFunction(x1, expected, actual, CALL_FUNCTION, NullCallWrapper()); | 290 __ InvokeFunction(x1, expected, actual, CALL_FUNCTION, NullCallWrapper()); |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 } | 456 } |
| 459 __ Bind(&do_store); | 457 __ Bind(&do_store); |
| 460 } | 458 } |
| 461 } | 459 } |
| 462 | 460 |
| 463 | 461 |
| 464 Register PropertyHandlerCompiler::CheckPrototypes( | 462 Register PropertyHandlerCompiler::CheckPrototypes( |
| 465 Register object_reg, Register holder_reg, Register scratch1, | 463 Register object_reg, Register holder_reg, Register scratch1, |
| 466 Register scratch2, Handle<Name> name, Label* miss, | 464 Register scratch2, Handle<Name> name, Label* miss, |
| 467 PrototypeCheckType check) { | 465 PrototypeCheckType check) { |
| 468 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate())); | 466 Handle<Map> receiver_map = map(); |
| 469 | 467 |
| 470 // object_reg and holder_reg registers can alias. | 468 // object_reg and holder_reg registers can alias. |
| 471 DCHECK(!AreAliased(object_reg, scratch1, scratch2)); | 469 DCHECK(!AreAliased(object_reg, scratch1, scratch2)); |
| 472 DCHECK(!AreAliased(holder_reg, scratch1, scratch2)); | 470 DCHECK(!AreAliased(holder_reg, scratch1, scratch2)); |
| 473 | 471 |
| 474 // Keep track of the current object in register reg. | 472 // Keep track of the current object in register reg. |
| 475 Register reg = object_reg; | 473 Register reg = object_reg; |
| 476 int depth = 0; | 474 int depth = 0; |
| 477 | 475 |
| 478 Handle<JSObject> current = Handle<JSObject>::null(); | 476 Handle<JSObject> current = Handle<JSObject>::null(); |
| 479 if (type()->IsConstant()) { | 477 if (receiver_map->IsJSGlobalObjectMap()) { |
| 480 current = Handle<JSObject>::cast(type()->AsConstant()->Value()); | 478 current = isolate()->global_object(); |
| 481 } | 479 } |
| 482 Handle<JSObject> prototype = Handle<JSObject>::null(); | 480 Handle<JSObject> prototype = Handle<JSObject>::null(); |
| 483 Handle<Map> current_map = receiver_map; | 481 Handle<Map> current_map = receiver_map; |
| 484 Handle<Map> holder_map(holder()->map()); | 482 Handle<Map> holder_map(holder()->map()); |
| 485 // Traverse the prototype chain and check the maps in the prototype chain for | 483 // Traverse the prototype chain and check the maps in the prototype chain for |
| 486 // fast and global objects or do negative lookup for normal objects. | 484 // fast and global objects or do negative lookup for normal objects. |
| 487 while (!current_map.is_identical_to(holder_map)) { | 485 while (!current_map.is_identical_to(holder_map)) { |
| 488 ++depth; | 486 ++depth; |
| 489 | 487 |
| 490 // Only global objects and objects that do not require access | 488 // Only global objects and objects that do not require access |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 759 // Return the generated code. | 757 // Return the generated code. |
| 760 return GetCode(kind(), Code::FAST, name); | 758 return GetCode(kind(), Code::FAST, name); |
| 761 } | 759 } |
| 762 | 760 |
| 763 | 761 |
| 764 #undef __ | 762 #undef __ |
| 765 } | 763 } |
| 766 } // namespace v8::internal | 764 } // namespace v8::internal |
| 767 | 765 |
| 768 #endif // V8_TARGET_ARCH_IA32 | 766 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |